- Timestamp:
- Jan 5, 2017 12:04:34 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r65100 r65149 301 301 /** Shutdown indicator. */ 302 302 volatile bool fShutdown; 303 /** Whether the thread should do any data processing or not. */ 304 volatile bool fEnabled; 303 305 uint32_t Padding1; 304 306 } AC97STREAMSTATEAIO, *PAC97STREAMSTATEAIO; … … 312 314 /** Circular buffer (FIFO) for holding DMA'ed data. */ 313 315 R3PTRTYPE(PRTCIRCBUF) pCircBuf; 316 /** Criticial section for this stream. */ 317 RTCRITSECT CritSect; 314 318 #ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO 315 319 /** Asynchronous I/O state members. */ … … 325 329 /** Stream number (SDn). */ 326 330 uint8_t u8Strm; 327 /** Criticial section for this stream. */328 RTCRITSECT CritSect;329 331 /** Bus master registers of this stream. */ 330 332 AC97BMREGS Regs; … … 477 479 static int ichac97StreamClose(PAC97STATE pThis, PAC97STREAM pStream); 478 480 static void ichac97StreamReset(PAC97STATE pThis, PAC97STREAM pStream); 481 static void ichac97StreamLock(PAC97STREAM pStream); 482 static void ichac97StreamUnlock(PAC97STREAM pStream); 479 483 480 484 static DECLCALLBACK(void) ichac97Reset(PPDMDEVINS pDevIns); … … 498 502 static void ichac97StreamAsyncIOLock(PAC97STREAM pStream); 499 503 static void ichac97StreamAsyncIOUnlock(PAC97STREAM pStream); 504 static void ichac97StreamAsyncIOEnable(PAC97STREAM pStream, bool fEnable); 500 505 #endif 501 506 … … 647 652 * @param pStream AC'97 stream to enable or disable. 648 653 * @param fEnable Whether to enable or disble the stream. 654 * 649 655 */ 650 656 static int ichac97StreamEnable(PAC97STATE pThis, PAC97STREAM pStream, bool fEnable) … … 653 659 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 654 660 655 PAUDMIXSINK pSink = ichac97IndexToSink(pThis, pStream->u8Strm); 656 if (!pSink) /* No sink available (yet)? Bail out early. */ 657 return VINF_SUCCESS; 658 659 #ifdef LOG_ENABLED 660 const AUDMIXSINKSTS stsSink = AudioMixerSinkGetStatus(pSink); 661 662 const bool fIsEnabled = RT_BOOL(stsSink & AUDMIXSINK_STS_RUNNING); 663 const bool fPendingDisable = RT_BOOL(stsSink & AUDMIXSINK_STS_PENDING_DISABLE); 664 665 LogFunc(("[SD%RU8] fEnable=%RTbool, fIsEnabled=%RTbool, fPendingDisable=%RTbool, DCH=%RTbool, cStreamsActive=%RU8\n", 666 pStream->u8Strm, fEnable, fIsEnabled, fPendingDisable, RT_BOOL(pStream->Regs.sr & AC97_SR_DCH), pThis->cStreamsActive)); 667 #endif 661 ichac97StreamLock(pStream); 668 662 669 663 int rc = VINF_SUCCESS; … … 673 667 rc = ichac97StreamAsyncIOCreate(pThis, pStream); 674 668 if (RT_SUCCESS(rc)) 669 { 675 670 ichac97StreamAsyncIOLock(pStream); 671 ichac97StreamAsyncIOEnable(pStream, fEnable); 672 } 676 673 #endif 677 674 678 675 if (fEnable) 676 { 677 if (pStream->State.pCircBuf) 678 RTCircBufReset(pStream->State.pCircBuf); 679 679 680 rc = ichac97StreamOpen(pThis, pStream); 681 } 680 682 else 681 683 rc = ichac97StreamClose(pThis, pStream); 682 684 683 685 if (RT_SUCCESS(rc)) 686 { 687 /* First, enable or disable the stream and the stream's sink, if any. */ 684 688 rc = AudioMixerSinkCtl(ichac97IndexToSink(pThis, pStream->u8Strm), 685 689 fEnable ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE); 690 } 686 691 687 692 #ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO … … 689 694 #endif 690 695 691 if (RT_SUCCESS(rc)) 692 { 693 if (!fEnable) 694 { 695 if (pThis->cStreamsActive) /* Disable can be called mupltiple times. */ 696 pThis->cStreamsActive--; 696 /* Make sure to leave the lock before (eventually) starting the timer. */ 697 ichac97StreamUnlock(pStream); 697 698 698 699 #ifndef VBOX_WITH_AUDIO_AC97_CALLBACKS 699 ichac97TimerMaybeStop(pThis); 700 /* Second, see if we need to start or stop the timer. */ 701 if (!fEnable) 702 ichac97TimerMaybeStop(pThis); 703 else 704 ichac97TimerMaybeStart(pThis); 700 705 #endif 701 } 702 else 703 { 704 pThis->cStreamsActive++; 705 #ifndef VBOX_WITH_AUDIO_AC97_CALLBACKS 706 ichac97TimerMaybeStart(pThis); 707 #endif 708 } 709 } 710 711 LogFunc(("Returning %Rrc\n", rc)); 706 707 LogFunc(("[SD%RU8]: cStreamsActive=%RU8, rc=%Rrc\n", pStream->u8Strm, pThis->cStreamsActive, rc)); 712 708 return rc; 713 709 } 714 710 715 static void ichac97StreamResetBMRegs(PAC97STATE pThis, PAC97STREAM pStream) 711 /** 712 * Resets an AC'97 stream. 713 * 714 * @param pThis AC'97 state. 715 * @param pStream AC'97 stream to reset. 716 * 717 */ 718 static void ichac97StreamReset(PAC97STATE pThis, PAC97STREAM pStream) 716 719 { 717 720 AssertPtrReturnVoid(pThis); 718 721 AssertPtrReturnVoid(pStream); 719 722 723 ichac97StreamLock(pStream); 724 720 725 LogFunc(("[SD%RU8]\n", pStream->u8Strm)); 726 727 AudioMixerSinkReset(ichac97IndexToSink(pThis, pStream->u8Strm)); 728 729 if (pStream->State.pCircBuf) 730 RTCircBufReset(pStream->State.pCircBuf); 721 731 722 732 PAC97BMREGS pRegs = &pStream->Regs; … … 725 735 pRegs->civ = 0; 726 736 pRegs->lvi = 0; 727 728 ichac97StreamReset(pThis, pStream);729 730 ichac97StreamEnable(pThis, pStream, false /* fEnable */);731 732 ichac97StreamUpdateSR(pThis, pStream, AC97_SR_DCH); /** @todo Do we need to do that? */733 737 734 738 pRegs->picb = 0; … … 738 742 739 743 RT_ZERO(pThis->silence); 744 745 ichac97StreamUnlock(pStream); 740 746 } 741 747 … … 758 764 pStream->u8Strm = u8Strm; 759 765 760 int rc = RTCritSectInit(&pStream-> CritSect);766 int rc = RTCritSectInit(&pStream->State.CritSect); 761 767 if (RT_SUCCESS(rc)) 762 768 rc = RTCircBufCreate(&pStream->State.pCircBuf, _4K); /** @todo Make this configurable. */ … … 776 782 LogFlowFunc(("[SD%RU8]\n", pStream->u8Strm)); 777 783 778 int rc2 = RTCritSectDelete(&pStream-> CritSect);784 int rc2 = RTCritSectDelete(&pStream->State.CritSect); 779 785 AssertRC(rc2); 780 786 … … 793 799 794 800 LogFlowFuncLeave(); 795 }796 797 /**798 * Creates all AC'97 audio streams of the device.799 *800 * @returns IPRT status code.801 * @param pThis AC'97 state.802 */803 static int ichac97StreamsCreate(PAC97STATE pThis)804 {805 LogFlowFuncEnter();806 807 /*808 * Create all sinks and AC'97 streams.809 */810 811 /* Line-In. */812 int rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThis->pSinkLineIn);813 if (RT_SUCCESS(rc))814 rc = ichac97StreamCreate(pThis, &pThis->StreamLineIn, AC97SOUNDSOURCE_PI_INDEX);815 816 /* Microphone-In. */817 if (RT_SUCCESS(rc))818 {819 rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThis->pSinkMicIn);820 if (RT_SUCCESS(rc))821 rc = ichac97StreamCreate(pThis, &pThis->StreamMicIn, AC97SOUNDSOURCE_MC_INDEX);822 }823 824 /* Output. */825 if (RT_SUCCESS(rc))826 {827 rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOut);828 if (RT_SUCCESS(rc))829 rc = ichac97StreamCreate(pThis, &pThis->StreamOut, AC97SOUNDSOURCE_PO_INDEX);830 }831 832 /*833 * Open all streams with the current AC'97 mixer settings.834 */835 if (RT_SUCCESS(rc))836 {837 rc = ichac97StreamOpen (pThis, &pThis->StreamLineIn);838 if (RT_SUCCESS(rc))839 {840 rc = ichac97StreamOpen (pThis, &pThis->StreamMicIn);841 if (RT_SUCCESS(rc))842 {843 rc = ichac97StreamOpen(pThis, &pThis->StreamOut);844 }845 }846 }847 848 LogFlowFunc(("Returning %Rrc\n", rc));849 return rc;850 801 } 851 802 … … 1050 1001 break; 1051 1002 1052 size_t cbToProcess = RTCircBufUsed(pCircBuf); 1053 if (cbToProcess) 1054 { 1003 rc2 = RTCritSectEnter(&pAIO->CritSect); 1004 if (RT_SUCCESS(rc2)) 1005 { 1006 if (!pAIO->fEnabled) 1007 { 1008 RTCritSectLeave(&pAIO->CritSect); 1009 continue; 1010 } 1011 1012 uint32_t cbToProcess; 1055 1013 uint32_t cbProcessed = 0; 1056 1014 1057 rc2 = RTCritSectEnter(&pAIO->CritSect); 1015 switch (pStream->u8Strm) 1016 { 1017 /* Input. */ 1018 case AC97SOUNDSOURCE_PI_INDEX: 1019 case AC97SOUNDSOURCE_MC_INDEX: 1020 { 1021 cbToProcess = RTCircBufFree(pCircBuf); 1022 if (cbToProcess) 1023 rc2 = ichac97StreamWrite(pThis, pStream, pMixSink, (uint32_t)cbToProcess, &cbProcessed); 1024 break; 1025 } 1026 1027 /* Output. */ 1028 case AC97SOUNDSOURCE_PO_INDEX: 1029 { 1030 cbToProcess = RTCircBufUsed(pCircBuf); 1031 if (cbToProcess) 1032 rc2 = ichac97StreamRead(pThis, pStream, pMixSink, (uint32_t)cbToProcess, &cbProcessed); 1033 break; 1034 } 1035 1036 default: 1037 AssertFailedStmt(rc2 = VERR_NOT_SUPPORTED); 1038 break; 1039 } 1040 1058 1041 if (RT_SUCCESS(rc2)) 1059 { 1060 switch (pStream->u8Strm) 1061 { 1062 case AC97SOUNDSOURCE_PI_INDEX: 1063 case AC97SOUNDSOURCE_MC_INDEX: 1064 rc2 = ichac97StreamWrite(pThis, pStream, pMixSink, (uint32_t)cbToProcess, &cbProcessed); 1065 break; 1066 1067 case AC97SOUNDSOURCE_PO_INDEX: 1068 rc2 = ichac97StreamRead(pThis, pStream, pMixSink, (uint32_t)cbToProcess, &cbProcessed); 1069 break; 1070 1071 default: 1072 AssertFailedStmt(rc2 = VERR_NOT_SUPPORTED); 1073 break; 1074 } 1075 1076 if (RT_SUCCESS(rc2)) 1077 rc2 = AudioMixerSinkUpdate(pMixSink); 1078 1079 if (cbProcessed) 1080 { 1081 Assert(cbToProcess >= cbProcessed); 1082 cbToProcess -= cbProcessed; 1083 } 1084 1085 int rc3 = RTCritSectLeave(&pAIO->CritSect); 1086 AssertRC(rc3); 1087 } 1042 rc2 = AudioMixerSinkUpdate(pMixSink); 1043 1044 int rc3 = RTCritSectLeave(&pAIO->CritSect); 1045 AssertRC(rc3); 1088 1046 } 1089 1047 … … 1173 1131 pAIO->fStarted = false; 1174 1132 pAIO->fShutdown = false; 1133 pAIO->fEnabled = false; 1175 1134 } 1176 1135 … … 1225 1184 AssertRC(rc2); 1226 1185 } 1227 #endif /* VBOX_WITH_AUDIO_AC97_ASYNC_IO*/ 1186 1187 /** 1188 * Enables (resumes) or disables (pauses) the async I/O thread. 1189 * 1190 * @param pStream AC'97 stream to enable/disable async I/O thread for. 1191 * @param fEnable Whether to enable or disable the I/O thread. 1192 * 1193 * @remarks Does not do locking. 1194 */ 1195 static void ichac97StreamAsyncIOEnable(PAC97STREAM pStream, bool fEnable) 1196 { 1197 PAC97STREAMSTATEAIO pAIO = &pStream->State.AIO; 1198 ASMAtomicXchgBool(&pAIO->fEnabled, fEnable); 1199 } 1200 #endif /* VBOX_WITH_AUDIO_AC97_ASYNC_IO */ 1228 1201 1229 1202 /** … … 1245 1218 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1246 1219 1220 ichac97StreamLock(pStream); 1221 1247 1222 PAUDMIXSINK pMixSink = ichac97IndexToSink(pThis, pStream->u8Strm); 1248 if (!pMixSink) 1223 AssertPtr(pMixSink); 1224 1225 if (!AudioMixerSinkIsActive(pMixSink)) 1226 { 1227 ichac97StreamUnlock(pStream); 1249 1228 return VINF_SUCCESS; 1250 1251 if (AudioMixerSinkIsActive(pMixSink) == false) 1252 return VINF_SUCCESS; 1229 } 1253 1230 1254 1231 PRTCIRCBUF pCircBuf = pStream->State.pCircBuf; 1255 1232 AssertPtr(pCircBuf); 1256 1233 1257 int rc = VINF_SUCCESS;1258 1259 1234 bool fDone = false; 1260 1235 uint8_t cTransfers = 0; 1261 1236 1262 Log 3Func(("[SD%RU8] Started\n", pStream->u8Strm));1237 Log2Func(("[SD%RU8] Started\n", pStream->u8Strm)); 1263 1238 1264 1239 while (!fDone) … … 1399 1374 } /* while !fDone */ 1400 1375 1401 LogFunc(("[SD%RU8] End\n", pStream->u8Strm)); 1402 1403 return rc; 1376 Log2Func(("[SD%RU8] End\n", pStream->u8Strm)); 1377 1378 ichac97StreamUnlock(pStream); 1379 1380 return VINF_SUCCESS; 1404 1381 } 1405 1382 … … 1657 1634 if (RT_SUCCESS(rc)) 1658 1635 { 1659 if (streamCfg.uHz) /* Some valid rate set in the AC'97 mixer? */ 1660 { 1636 ichac97MixerRemoveDrvStreams(pThis, pMixSink, streamCfg.enmDir, streamCfg.DestSource); 1637 1638 if (streamCfg.uHz) 1639 { 1640 Assert(streamCfg.enmDir != PDMAUDIODIR_UNKNOWN); 1641 1661 1642 streamCfg.cChannels = 2; 1662 1643 streamCfg.enmFormat = PDMAUDIOFMT_S16; 1663 1644 streamCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS; 1664 1645 1665 ichac97MixerRemoveDrvStreams(pThis, pMixSink, streamCfg.enmDir, streamCfg.DestSource);1666 1667 1646 rc = ichac97MixerAddDrvStreams(pThis, pMixSink, &streamCfg); 1668 1647 } … … 1710 1689 1711 1690 /** 1712 * Resets an AC'97 stream. 1713 * 1714 * @param pThis AC'97 state. 1715 * @param pStream AC'97 stream to reset. 1716 * @remark 1717 */ 1718 static void ichac97StreamReset(PAC97STATE pThis, PAC97STREAM pStream) 1719 { 1720 AssertPtrReturnVoid(pThis); 1691 * Locks an AC'97 stream for serialized access. 1692 * 1693 * @returns IPRT status code. 1694 * @param pStream AC'97 stream to lock. 1695 */ 1696 static void ichac97StreamLock(PAC97STREAM pStream) 1697 { 1721 1698 AssertPtrReturnVoid(pStream); 1722 1723 LogFunc(("[SD%RU8] Reset\n", pStream->u8Strm)); 1724 1725 #ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO 1726 /* 1727 * Make sure to destroy the async I/O thread for this stream on reset, as we 1728 * can't be sure that the same stream is being used in the next cycle 1729 * (and therefore would leave unused threads around). 1730 */ 1731 int rc2 = ichac97StreamAsyncIODestroy(pThis, pStream); 1699 int rc2 = RTCritSectEnter(&pStream->State.CritSect); 1732 1700 AssertRC(rc2); 1733 #endif 1734 1735 if (pStream->State.pCircBuf) 1736 RTCircBufReset(pStream->State.pCircBuf); 1701 } 1702 1703 1704 /** 1705 * Unlocks a formerly locked AC'97 stream. 1706 * 1707 * @returns IPRT status code. 1708 * @param pStream AC'97 stream to unlock. 1709 */ 1710 static void ichac97StreamUnlock(PAC97STREAM pStream) 1711 { 1712 AssertPtrReturnVoid(pStream); 1713 int rc2 = RTCritSectLeave(&pStream->State.CritSect); 1714 AssertRC(rc2); 1737 1715 } 1738 1716 … … 2045 2023 static void ichac97TimerMaybeStart(PAC97STATE pThis) 2046 2024 { 2047 if (pThis->cStreamsActive == 0) /* Only start the timer if there at least is one active streams. */ 2048 return; 2025 LogFlowFuncEnter(); 2049 2026 2050 2027 if (!pThis->pTimer) 2051 2028 return; 2052 2029 2053 if (ASMAtomicReadBool(&pThis->fTimerActive) == true) /* Already started? */ 2054 return; 2055 2056 LogRel2(("AC97: Starting transfers\n")); 2030 pThis->cStreamsActive++; 2031 2032 /* Only start the timer at the first active stream. */ 2033 if (pThis->cStreamsActive == 1) 2034 { 2035 LogRel2(("AC97: Starting transfers\n")); 2036 2037 /* Set timer flag. */ 2038 ASMAtomicXchgBool(&pThis->fTimerActive, true); 2039 2040 /* Update current time timestamp. */ 2041 pThis->uTimerTS = TMTimerGet(pThis->pTimer); 2042 2043 /* Start transfers. */ 2044 ichac97TimerMain(pThis); 2045 } 2046 } 2047 2048 /** 2049 * Stops the internal audio device timer. 2050 * 2051 * @param pThis AC'97 state. 2052 */ 2053 static void ichac97TimerStop(PAC97STATE pThis) 2054 { 2055 LogFlowFuncEnter(); 2057 2056 2058 2057 /* Set timer flag. */ 2059 ASMAtomicXchgBool(&pThis->fTimerActive, true); 2060 2061 /* Update current time timestamp. */ 2062 pThis->uTimerTS = TMTimerGet(pThis->pTimer); 2063 2064 /* Start transfers. */ 2065 ichac97TimerMain(pThis); 2066 } 2067 2068 /** 2069 * Stops the internal audio device timer (if not stopped yet). 2058 ASMAtomicXchgBool(&pThis->fTimerActive, false); 2059 } 2060 2061 /** 2062 * Decreases the active AC'97 streams count by one and 2063 * then checks if the internal audio device timer can be 2064 * stopped. 2070 2065 * 2071 2066 * @param pThis AC'97 state. … … 2073 2068 static void ichac97TimerMaybeStop(PAC97STATE pThis) 2074 2069 { 2075 if (pThis->cStreamsActive) /* Some streams still active? Bail out. */ 2076 return; 2070 LogFlowFuncEnter(); 2077 2071 2078 2072 if (!pThis->pTimer) 2079 2073 return; 2080 2074 2081 if ( ASMAtomicReadBool(&pThis->fTimerActive) == false) /* Already stopped?*/2082 return;2083 2084 LogRel2(("AC97: Stopping transfers\n")); 2085 2086 /* Set timer flag. */2087 ASMAtomicXchgBool(&pThis->fTimerActive, false);2075 if (pThis->cStreamsActive) /* Function can be called mupltiple times. */ 2076 { 2077 pThis->cStreamsActive--; 2078 2079 if (pThis->cStreamsActive == 0) 2080 ichac97TimerStop(pThis); 2081 } 2088 2082 } 2089 2083 … … 2125 2119 } 2126 2120 else 2127 LogRel2(("AC97: Stopp edtransfers\n"));2121 LogRel2(("AC97: Stopping transfers\n")); 2128 2122 2129 2123 STAM_PROFILE_STOP(&pThis->StatTimer, a); … … 2372 2366 PAC97BMREGS pRegs = NULL; 2373 2367 2374 if (pStream) 2375 { 2368 if (pStream) /* Can be NULL, depending on the index (port). */ 2376 2369 pRegs = &pStream->Regs; 2377 2378 int rc2 = RTCritSectEnter(&pStream->CritSect);2379 AssertRC(rc2);2380 }2381 2370 2382 2371 int rc = VINF_SUCCESS; … … 2519 2508 } 2520 2509 2521 if (pStream)2522 {2523 int rc2 = RTCritSectLeave(&pStream->CritSect);2524 AssertRC(rc2);2525 }2526 2527 2510 return rc; 2528 2511 } … … 2543 2526 PAC97BMREGS pRegs = NULL; 2544 2527 2545 if (pStream) 2546 { 2528 if (pStream) /* Can be NULL, depending on the index (port). */ 2547 2529 pRegs = &pStream->Regs; 2548 2549 int rc2 = RTCritSectEnter(&pStream->CritSect);2550 AssertRC(rc2);2551 }2552 2530 2553 2531 switch (cb) … … 2594 2572 Assert((pRegs->cr & AC97_CR_RPBM) == 0); 2595 2573 2596 ichac97StreamResetBMRegs(pThis, pStream); 2574 ichac97StreamEnable(pThis, pStream, false /* Disable */); 2575 ichac97StreamReset(pThis, pStream); 2576 2577 ichac97StreamUpdateSR(pThis, pStream, AC97_SR_DCH); /** @todo Do we need to do that? */ 2597 2578 } 2598 2579 else … … 2702 2683 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", uPort, cb, u32)); 2703 2684 break; 2704 }2705 2706 if (pStream)2707 {2708 int rc2 = RTCritSectLeave(&pStream->CritSect);2709 AssertRC(rc2);2710 2685 } 2711 2686 … … 3074 3049 ichac97MixerGet(pThis, AC97_Headphone_Volume_Mute)); 3075 3050 3076 ichac97StreamsDestroy(pThis); 3077 3078 rc2 = ichac97StreamsCreate(pThis); 3051 /** @todo r=andy Stream IDs are hardcoded to certain streams. */ 3052 rc2 = ichac97StreamEnable(pThis, &pThis->StreamLineIn, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_PI_INDEX])); 3079 3053 if (RT_SUCCESS(rc2)) 3080 { 3081 /** @todo r=andy Stream IDs are hardcoded to certain streams. */ 3082 rc2 = ichac97StreamEnable(pThis, &pThis->StreamLineIn, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_PI_INDEX])); 3083 if (RT_SUCCESS(rc2)) 3084 rc2 = ichac97StreamEnable(pThis, &pThis->StreamMicIn, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_MC_INDEX])); 3085 if (RT_SUCCESS(rc2)) 3086 rc2 = ichac97StreamEnable(pThis, &pThis->StreamOut, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_PO_INDEX])); 3087 } 3054 rc2 = ichac97StreamEnable(pThis, &pThis->StreamMicIn, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_MC_INDEX])); 3055 if (RT_SUCCESS(rc2)) 3056 rc2 = ichac97StreamEnable(pThis, &pThis->StreamOut, RT_BOOL(uaStrmsActive[AC97SOUNDSOURCE_PO_INDEX])); 3088 3057 3089 3058 pThis->bup_flag = 0; … … 3148 3117 3149 3118 /* 3150 * Reset the device state (will need pDrv later).3151 */3152 ichac97StreamResetBMRegs(pThis, &pThis->StreamLineIn);3153 ichac97StreamResetBMRegs(pThis, &pThis->StreamMicIn);3154 ichac97StreamResetBMRegs(pThis, &pThis->StreamOut);3155 3156 /*3157 3119 * Reset the mixer too. The Windows XP driver seems to rely on 3158 3120 * this. At least it wants to read the vendor id before it resets … … 3164 3126 * Reset all streams. 3165 3127 */ 3128 ichac97StreamEnable(pThis, &pThis->StreamLineIn, false /* Disable */); 3166 3129 ichac97StreamReset(pThis, &pThis->StreamLineIn); 3130 3131 ichac97StreamEnable(pThis, &pThis->StreamMicIn, false /* Disable */); 3167 3132 ichac97StreamReset(pThis, &pThis->StreamMicIn); 3133 3134 ichac97StreamEnable(pThis, &pThis->StreamOut, false /* Disable */); 3168 3135 ichac97StreamReset(pThis, &pThis->StreamOut); 3169 3136 … … 3514 3481 3515 3482 if (RT_SUCCESS(rc)) 3483 { 3516 3484 rc = AudioMixerCreate("AC'97 Mixer", 0 /* uFlags */, &pThis->pMixer); 3517 3518 ichac97Reset(pDevIns); 3485 if (RT_SUCCESS(rc)) 3486 { 3487 rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThis->pSinkLineIn); 3488 AssertRC(rc); 3489 rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThis->pSinkMicIn); 3490 AssertRC(rc); 3491 rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOut); 3492 AssertRC(rc); 3493 } 3494 } 3519 3495 3520 3496 if (RT_SUCCESS(rc)) 3521 3497 { 3522 ichac97StreamsCreate(pThis); 3498 /* 3499 * Create all hardware streams. 3500 */ 3501 rc = ichac97StreamCreate(pThis, &pThis->StreamLineIn, AC97SOUNDSOURCE_PI_INDEX); 3502 if (RT_SUCCESS(rc)) 3503 { 3504 rc = ichac97StreamCreate(pThis, &pThis->StreamMicIn, AC97SOUNDSOURCE_MC_INDEX); 3505 if (RT_SUCCESS(rc)) 3506 rc = ichac97StreamCreate(pThis, &pThis->StreamOut, AC97SOUNDSOURCE_PO_INDEX); 3507 } 3523 3508 3524 3509 #ifdef VBOX_WITH_AUDIO_AC97_ONETIME_INIT … … 3546 3531 LogRel(("AC97: Falling back to NULL backend (no sound audible)\n")); 3547 3532 3548 /* Destroy the streams before re-attaching the NULL driver. */3549 ichac97StreamsDestroy(pThis);3550 3551 3533 ichac97Reset(pDevIns); 3552 3534 ichac97Reattach(pThis, pDrv, pDrv->uLUN, "NullAudio"); 3553 3554 /* Re-create the streams after re-attaching. */3555 ichac97StreamsCreate(pThis);3556 3535 3557 3536 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", … … 3625 3604 #endif /* VBOX_WITH_AUDIO_AC97_ONETIME_INIT */ 3626 3605 } 3606 3607 if (RT_SUCCESS(rc)) 3608 ichac97Reset(pDevIns); 3627 3609 3628 3610 #ifndef VBOX_WITH_AUDIO_AC97_CALLBACKS
Note:
See TracChangeset
for help on using the changeset viewer.