VirtualBox

Changeset 65149 in vbox


Ignore:
Timestamp:
Jan 5, 2017 12:04:34 PM (8 years ago)
Author:
vboxsync
Message:

Audio/DevAc97.cpp: Update for async I/O.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r65100 r65149  
    301301    /** Shutdown indicator. */
    302302    volatile bool         fShutdown;
     303    /** Whether the thread should do any data processing or not. */
     304    volatile bool         fEnabled;
    303305    uint32_t              Padding1;
    304306} AC97STREAMSTATEAIO, *PAC97STREAMSTATEAIO;
     
    312314    /** Circular buffer (FIFO) for holding DMA'ed data. */
    313315    R3PTRTYPE(PRTCIRCBUF) pCircBuf;
     316    /** Criticial section for this stream. */
     317    RTCRITSECT            CritSect;
    314318#ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
    315319    /** Asynchronous I/O state members. */
     
    325329    /** Stream number (SDn). */
    326330    uint8_t         u8Strm;
    327     /** Criticial section for this stream. */
    328     RTCRITSECT      CritSect;
    329331    /** Bus master registers of this stream. */
    330332    AC97BMREGS      Regs;
     
    477479static int                ichac97StreamClose(PAC97STATE pThis, PAC97STREAM pStream);
    478480static void               ichac97StreamReset(PAC97STATE pThis, PAC97STREAM pStream);
     481static void               ichac97StreamLock(PAC97STREAM pStream);
     482static void               ichac97StreamUnlock(PAC97STREAM pStream);
    479483
    480484static DECLCALLBACK(void) ichac97Reset(PPDMDEVINS pDevIns);
     
    498502static void               ichac97StreamAsyncIOLock(PAC97STREAM pStream);
    499503static void               ichac97StreamAsyncIOUnlock(PAC97STREAM pStream);
     504static void               ichac97StreamAsyncIOEnable(PAC97STREAM pStream, bool fEnable);
    500505#endif
    501506
     
    647652 * @param   pStream             AC'97 stream to enable or disable.
    648653 * @param   fEnable             Whether to enable or disble the stream.
     654 *
    649655 */
    650656static int ichac97StreamEnable(PAC97STATE pThis, PAC97STREAM pStream, bool fEnable)
     
    653659    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    654660
    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);
    668662
    669663    int rc = VINF_SUCCESS;
     
    673667        rc = ichac97StreamAsyncIOCreate(pThis, pStream);
    674668    if (RT_SUCCESS(rc))
     669    {
    675670        ichac97StreamAsyncIOLock(pStream);
     671        ichac97StreamAsyncIOEnable(pStream, fEnable);
     672    }
    676673#endif
    677674
    678675    if (fEnable)
     676    {
     677        if (pStream->State.pCircBuf)
     678            RTCircBufReset(pStream->State.pCircBuf);
     679
    679680        rc = ichac97StreamOpen(pThis, pStream);
     681    }
    680682    else
    681683        rc = ichac97StreamClose(pThis, pStream);
    682684
    683685    if (RT_SUCCESS(rc))
     686    {
     687        /* First, enable or disable the stream and the stream's sink, if any. */
    684688        rc = AudioMixerSinkCtl(ichac97IndexToSink(pThis, pStream->u8Strm),
    685689                               fEnable ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE);
     690    }
    686691
    687692#ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
     
    689694#endif
    690695
    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);
    697698
    698699#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);
    700705#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));
    712708    return rc;
    713709}
    714710
    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 */
     718static void ichac97StreamReset(PAC97STATE pThis, PAC97STREAM pStream)
    716719{
    717720    AssertPtrReturnVoid(pThis);
    718721    AssertPtrReturnVoid(pStream);
    719722
     723    ichac97StreamLock(pStream);
     724
    720725    LogFunc(("[SD%RU8]\n", pStream->u8Strm));
     726
     727    AudioMixerSinkReset(ichac97IndexToSink(pThis, pStream->u8Strm));
     728
     729    if (pStream->State.pCircBuf)
     730        RTCircBufReset(pStream->State.pCircBuf);
    721731
    722732    PAC97BMREGS pRegs = &pStream->Regs;
     
    725735    pRegs->civ      = 0;
    726736    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? */
    733737
    734738    pRegs->picb     = 0;
     
    738742
    739743    RT_ZERO(pThis->silence);
     744
     745    ichac97StreamUnlock(pStream);
    740746}
    741747
     
    758764    pStream->u8Strm = u8Strm;
    759765
    760     int rc = RTCritSectInit(&pStream->CritSect);
     766    int rc = RTCritSectInit(&pStream->State.CritSect);
    761767    if (RT_SUCCESS(rc))
    762768        rc = RTCircBufCreate(&pStream->State.pCircBuf, _4K); /** @todo Make this configurable. */
     
    776782    LogFlowFunc(("[SD%RU8]\n", pStream->u8Strm));
    777783
    778     int rc2 = RTCritSectDelete(&pStream->CritSect);
     784    int rc2 = RTCritSectDelete(&pStream->State.CritSect);
    779785    AssertRC(rc2);
    780786
     
    793799
    794800    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;
    850801}
    851802
     
    10501001            break;
    10511002
    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;
    10551013            uint32_t cbProcessed = 0;
    10561014
    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
    10581041            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);
    10881046        }
    10891047
     
    11731131        pAIO->fStarted  = false;
    11741132        pAIO->fShutdown = false;
     1133        pAIO->fEnabled  = false;
    11751134    }
    11761135
     
    12251184    AssertRC(rc2);
    12261185}
    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 */
     1195static 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 */
    12281201
    12291202/**
     
    12451218    AssertPtrReturn(pStream, VERR_INVALID_POINTER);
    12461219
     1220    ichac97StreamLock(pStream);
     1221
    12471222    PAUDMIXSINK pMixSink = ichac97IndexToSink(pThis, pStream->u8Strm);
    1248     if (!pMixSink)
     1223    AssertPtr(pMixSink);
     1224
     1225    if (!AudioMixerSinkIsActive(pMixSink))
     1226    {
     1227        ichac97StreamUnlock(pStream);
    12491228        return VINF_SUCCESS;
    1250 
    1251     if (AudioMixerSinkIsActive(pMixSink) == false)
    1252         return VINF_SUCCESS;
     1229    }
    12531230
    12541231    PRTCIRCBUF pCircBuf  = pStream->State.pCircBuf;
    12551232    AssertPtr(pCircBuf);
    12561233
    1257     int rc = VINF_SUCCESS;
    1258 
    12591234    bool fDone = false;
    12601235    uint8_t cTransfers = 0;
    12611236
    1262     Log3Func(("[SD%RU8] Started\n", pStream->u8Strm));
     1237    Log2Func(("[SD%RU8] Started\n", pStream->u8Strm));
    12631238
    12641239    while (!fDone)
     
    13991374    } /* while !fDone */
    14001375
    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;
    14041381}
    14051382
     
    16571634    if (RT_SUCCESS(rc))
    16581635    {
    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
    16611642            streamCfg.cChannels     = 2;
    16621643            streamCfg.enmFormat     = PDMAUDIOFMT_S16;
    16631644            streamCfg.enmEndianness = PDMAUDIOHOSTENDIANNESS;
    16641645
    1665             ichac97MixerRemoveDrvStreams(pThis, pMixSink, streamCfg.enmDir, streamCfg.DestSource);
    1666 
    16671646            rc = ichac97MixerAddDrvStreams(pThis, pMixSink, &streamCfg);
    16681647        }
     
    17101689
    17111690/**
    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 */
     1696static void ichac97StreamLock(PAC97STREAM pStream)
     1697{
    17211698    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);
    17321700    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 */
     1710static void ichac97StreamUnlock(PAC97STREAM pStream)
     1711{
     1712    AssertPtrReturnVoid(pStream);
     1713    int rc2 = RTCritSectLeave(&pStream->State.CritSect);
     1714    AssertRC(rc2);
    17371715}
    17381716
     
    20452023static void ichac97TimerMaybeStart(PAC97STATE pThis)
    20462024{
    2047     if (pThis->cStreamsActive == 0) /* Only start the timer if there at least is one active streams. */
    2048         return;
     2025    LogFlowFuncEnter();
    20492026
    20502027    if (!pThis->pTimer)
    20512028        return;
    20522029
    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 */
     2053static void ichac97TimerStop(PAC97STATE pThis)
     2054{
     2055    LogFlowFuncEnter();
    20572056
    20582057    /* 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.
    20702065 *
    20712066 * @param   pThis               AC'97 state.
     
    20732068static void ichac97TimerMaybeStop(PAC97STATE pThis)
    20742069{
    2075     if (pThis->cStreamsActive) /* Some streams still active? Bail out. */
    2076         return;
     2070    LogFlowFuncEnter();
    20772071
    20782072    if (!pThis->pTimer)
    20792073        return;
    20802074
    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    }
    20882082}
    20892083
     
    21252119    }
    21262120    else
    2127         LogRel2(("AC97: Stopped transfers\n"));
     2121        LogRel2(("AC97: Stopping transfers\n"));
    21282122
    21292123    STAM_PROFILE_STOP(&pThis->StatTimer, a);
     
    23722366    PAC97BMREGS pRegs   = NULL;
    23732367
    2374     if (pStream)
    2375     {
     2368    if (pStream) /* Can be NULL, depending on the index (port). */
    23762369        pRegs = &pStream->Regs;
    2377 
    2378         int rc2 = RTCritSectEnter(&pStream->CritSect);
    2379         AssertRC(rc2);
    2380     }
    23812370
    23822371    int rc = VINF_SUCCESS;
     
    25192508    }
    25202509
    2521     if (pStream)
    2522     {
    2523         int rc2 = RTCritSectLeave(&pStream->CritSect);
    2524         AssertRC(rc2);
    2525     }
    2526 
    25272510    return rc;
    25282511}
     
    25432526    PAC97BMREGS pRegs   = NULL;
    25442527
    2545     if (pStream)
    2546     {
     2528    if (pStream) /* Can be NULL, depending on the index (port). */
    25472529        pRegs = &pStream->Regs;
    2548 
    2549         int rc2 = RTCritSectEnter(&pStream->CritSect);
    2550         AssertRC(rc2);
    2551     }
    25522530
    25532531    switch (cb)
     
    25942572                        Assert((pRegs->cr & AC97_CR_RPBM) == 0);
    25952573
    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? */
    25972578                    }
    25982579                    else
     
    27022683            AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", uPort, cb, u32));
    27032684            break;
    2704     }
    2705 
    2706     if (pStream)
    2707     {
    2708         int rc2 = RTCritSectLeave(&pStream->CritSect);
    2709         AssertRC(rc2);
    27102685    }
    27112686
     
    30743049                             ichac97MixerGet(pThis, AC97_Headphone_Volume_Mute));
    30753050
    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]));
    30793053    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]));
    30883057
    30893058    pThis->bup_flag  = 0;
     
    31483117
    31493118    /*
    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     /*
    31573119     * Reset the mixer too. The Windows XP driver seems to rely on
    31583120     * this. At least it wants to read the vendor id before it resets
     
    31643126     * Reset all streams.
    31653127     */
     3128    ichac97StreamEnable(pThis, &pThis->StreamLineIn, false /* Disable */);
    31663129    ichac97StreamReset(pThis, &pThis->StreamLineIn);
     3130
     3131    ichac97StreamEnable(pThis, &pThis->StreamMicIn, false /* Disable */);
    31673132    ichac97StreamReset(pThis, &pThis->StreamMicIn);
     3133
     3134    ichac97StreamEnable(pThis, &pThis->StreamOut, false /* Disable */);
    31683135    ichac97StreamReset(pThis, &pThis->StreamOut);
    31693136
     
    35143481
    35153482    if (RT_SUCCESS(rc))
     3483    {
    35163484        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    }
    35193495
    35203496    if (RT_SUCCESS(rc))
    35213497    {
    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        }
    35233508
    35243509#ifdef VBOX_WITH_AUDIO_AC97_ONETIME_INIT
     
    35463531                LogRel(("AC97: Falling back to NULL backend (no sound audible)\n"));
    35473532
    3548                 /* Destroy the streams before re-attaching the NULL driver. */
    3549                 ichac97StreamsDestroy(pThis);
    3550 
    35513533                ichac97Reset(pDevIns);
    35523534                ichac97Reattach(pThis, pDrv, pDrv->uLUN, "NullAudio");
    3553 
    3554                 /* Re-create the streams after re-attaching. */
    3555                 ichac97StreamsCreate(pThis);
    35563535
    35573536                PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
     
    36253604#endif /* VBOX_WITH_AUDIO_AC97_ONETIME_INIT */
    36263605    }
     3606
     3607    if (RT_SUCCESS(rc))
     3608        ichac97Reset(pDevIns);
    36273609
    36283610#ifndef VBOX_WITH_AUDIO_AC97_CALLBACKS
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette