VirtualBox

Changeset 88307 in vbox for trunk


Ignore:
Timestamp:
Mar 26, 2021 9:18:42 PM (4 years ago)
Author:
vboxsync
Message:

Audio: Buffer usage statistics so we can monitor whether they are emptied when they should be. bugref:9890

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmaudioifs.h

    r88300 r88307  
    10341034     *       differ between parent and child.  */
    10351035    uint32_t                    cMixed;
    1036     /** How much audio frames are currently being used
    1037      *  in this buffer.
    1038      *  Note: This also is known as the distance in ring buffer terms. */
     1036    /** How much audio frames are currently being used in this buffer.
     1037     * @note This also is known as the distance in ring buffer terms. */
    10391038    uint32_t                    cUsed;
    10401039    /** Number of children mix buffers kept in lstChildren. */
     
    12401239        STAMCOUNTER     AvgFramesWritten;
    12411240        STAMCOUNTER     TotalTimesWritten;
     1241        uint32_t        cbBackendWritableBefore;
     1242        uint32_t        cbBackendWritableAfter;
    12421243    } Stats;
    12431244    /** Hack alert: Max writable amount reported by the backend.
     
    15241525     * @param   pCfgGuest       Stream configuration for guest side.
    15251526     * @param   ppStream        Pointer where to return the created audio stream on success.
     1527     * @todo r=bird: It is not documented how pCfgHost and pCfgGuest can be
     1528     *       modified the DrvAudio...
    15261529     */
    15271530    DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfgHost,
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp

    r88299 r88307  
    19641964
    19651965        PDMAUDMIXBUFCONVOPTS convOpts;
    1966         RT_ZERO(convOpts);
    1967 
    19681966        convOpts.From.Volume.fMuted = pMixBuf->Volume.fMuted;
    19691967        convOpts.From.Volume.uLeft  = pMixBuf->Volume.uLeft;
    19701968        convOpts.From.Volume.uRight = pMixBuf->Volume.uRight;
    1971 
    19721969        convOpts.cFrames = cToWrite;
    19731970
  • trunk/src/VBox/Devices/Audio/AudioMixBuffer.h

    r88269 r88307  
    5454
    5555
    56 inline uint32_t AudioMixBufBytesToSamples(PPDMAUDIOMIXBUF pMixBuf);
     56int     AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames);
     57void    AudioMixBufDestroy(PPDMAUDIOMIXBUF pMixBuf);
    5758void AudioMixBufClear(PPDMAUDIOMIXBUF pMixBuf);
    58 void AudioMixBufDestroy(PPDMAUDIOMIXBUF pMixBuf);
    5959void AudioMixBufFinish(PPDMAUDIOMIXBUF pMixBuf, uint32_t cFramesToClear);
    6060uint32_t AudioMixBufFree(PPDMAUDIOMIXBUF pMixBuf);
    6161uint32_t AudioMixBufFreeBytes(PPDMAUDIOMIXBUF pMixBuf);
    62 int AudioMixBufInit(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PCPDMAUDIOPCMPROPS pProps, uint32_t cFrames);
    6362bool AudioMixBufIsEmpty(PPDMAUDIOMIXBUF pMixBuf);
    6463int AudioMixBufLinkTo(PPDMAUDIOMIXBUF pMixBuf, PPDMAUDIOMIXBUF pParent);
  • trunk/src/VBox/Devices/Audio/AudioMixer.cpp

    r88299 r88307  
    9898
    9999static int audioMixerSinkInit(PAUDMIXSINK pSink, PAUDIOMIXER pMixer, const char *pcszName, AUDMIXSINKDIR enmDir);
    100 static void audioMixerSinkDestroyInternal(PAUDMIXSINK pSink);
     100static void audioMixerSinkDestroyInternal(PAUDMIXSINK pSink, PPDMDEVINS pDevIns);
    101101static int audioMixerSinkUpdateVolume(PAUDMIXSINK pSink, const PPDMAUDIOVOLUME pVolMaster);
    102102static void audioMixerSinkRemoveAllStreamsInternal(PAUDMIXSINK pSink);
     
    110110
    111111static int audioMixerStreamCtlInternal(PAUDMIXSTREAM pMixStream, PDMAUDIOSTREAMCMD enmCmd, uint32_t fCtl);
    112 static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pStream);
     112static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pStream, PPDMDEVINS pDevIns);
    113113static int audioMixerStreamUpdateStatus(PAUDMIXSTREAM pMixStream);
    114114
     
    161161 *
    162162 * @returns VBox status code.
    163  * @param   pMixer              Mixer to attach created sink to.
    164  * @param   pszName             Name of the sink to create.
    165  * @param   enmDir              Direction of the sink to create.
    166  * @param   ppSink              Pointer which returns the created sink on success.
    167  */
    168 int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PAUDMIXSINK *ppSink)
     163 * @param   pMixer      Mixer to attach created sink to.
     164 * @param   pszName     Name of the sink to create.
     165 * @param   enmDir      Direction of the sink to create.
     166 * @param   pDevIns     The device instance to register statistics under.
     167 * @param   ppSink      Pointer which returns the created sink on success.
     168 */
     169int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PPDMDEVINS pDevIns, PAUDMIXSINK *ppSink)
    169170{
    170171    AssertPtrReturn(pMixer, VERR_INVALID_POINTER);
     
    173174
    174175    int rc = RTCritSectEnter(&pMixer->CritSect);
    175     if (RT_FAILURE(rc))
    176         return rc;
     176    AssertRCReturn(rc, rc);
    177177
    178178    PAUDMIXSINK pSink = (PAUDMIXSINK)RTMemAllocZ(sizeof(AUDMIXSINK));
     
    185185            if (RT_SUCCESS(rc))
    186186            {
     187                RTCritSectLeave(&pMixer->CritSect);
     188
    187189                if (ppSink)
    188190                    *ppSink = pSink;
     191                return VINF_SUCCESS;
    189192            }
    190193        }
    191194
    192         if (RT_FAILURE(rc))
    193         {
    194             audioMixerSinkDestroyInternal(pSink);
    195 
    196             RTMemFree(pSink);
    197             pSink = NULL;
    198         }
     195        audioMixerSinkDestroyInternal(pSink, pDevIns);
     196
     197        RTMemFree(pSink);
     198        pSink = NULL;
    199199    }
    200200    else
    201201        rc = VERR_NO_MEMORY;
    202202
    203     int rc2 = RTCritSectLeave(&pMixer->CritSect);
    204     AssertRC(rc2);
    205 
     203    RTCritSectLeave(&pMixer->CritSect);
    206204    return rc;
    207205}
     
    297295 * Destroys an audio mixer.
    298296 *
    299  * @param   pMixer              Audio mixer to destroy.
    300  */
    301 void AudioMixerDestroy(PAUDIOMIXER pMixer)
     297 * @param   pMixer      Audio mixer to destroy.
     298 * @param   pDevIns     The device instance the statistics are associated with.
     299 */
     300void AudioMixerDestroy(PAUDIOMIXER pMixer, PPDMDEVINS pDevIns)
    302301{
    303302    if (!pMixer)
     
    312311    RTListForEachSafe(&pMixer->lstSinks, pSink, pSinkNext, AUDMIXSINK, Node)
    313312    {
    314         /* Save a pointer to the sink to remove, as pSink
    315          * will not be valid anymore after calling audioMixerRemoveSinkInternal(). */
    316         PAUDMIXSINK pSinkToRemove = pSink;
    317 
    318         audioMixerSinkDestroyInternal(pSinkToRemove);
    319         audioMixerRemoveSinkInternal(pMixer, pSinkToRemove);
    320 
    321         RTMemFree(pSinkToRemove);
     313        audioMixerSinkDestroyInternal(pSink, pDevIns);
     314        audioMixerRemoveSinkInternal(pMixer, pSink);
     315        RTMemFree(pSink);
    322316    }
    323317
    324318    Assert(pMixer->cSinks == 0);
    325319
    326     if (pMixer->pszName)
    327     {
    328         RTStrFree(pMixer->pszName);
    329         pMixer->pszName = NULL;
    330     }
     320    RTStrFree(pMixer->pszName);
     321    pMixer->pszName = NULL;
    331322
    332323    rc2 = RTCritSectLeave(&pMixer->CritSect);
     
    558549 *
    559550 * @returns VBox status code.
    560  * @param   pSink               Sink to use for creating the stream.
    561  * @param   pConn               Audio connector interface to use.
    562  * @param   pCfg                Audio stream configuration to use.
    563  * @param   fFlags              Stream flags. Currently unused, set to 0.
    564  * @param   ppStream            Pointer which receives the newly created audio stream.
    565  */
    566 int AudioMixerSinkCreateStream(PAUDMIXSINK pSink,
    567                                PPDMIAUDIOCONNECTOR pConn, PPDMAUDIOSTREAMCFG pCfg, AUDMIXSTREAMFLAGS fFlags, PAUDMIXSTREAM *ppStream)
     551 * @param   pSink       Sink to use for creating the stream.
     552 * @param   pConn       Audio connector interface to use.
     553 * @param   pCfg        Audio stream configuration to use.  This may be modified
     554 *                      in some unspecified way (see
     555 *                      PDMIAUDIOCONNECTOR::pfnStreamCreate).
     556 * @param   fFlags      Stream flags. Currently unused, set to 0.
     557 * @param   pDevIns     The device instance to register statistics with.
     558 * @param   ppStream    Pointer which receives the newly created audio stream.
     559 */
     560int AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConn, PPDMAUDIOSTREAMCFG pCfg,
     561                               AUDMIXSTREAMFLAGS fFlags, PPDMDEVINS pDevIns, PAUDMIXSTREAM *ppStream)
    568562{
    569563    AssertPtrReturn(pSink, VERR_INVALID_POINTER);
     
    573567    /* ppStream is optional. */
    574568
     569    /*
     570     * Check status and get the host driver config.
     571     */
    575572    if (pConn->pfnGetStatus(pConn, PDMAUDIODIR_DUPLEX) == PDMAUDIOBACKENDSTS_NOT_ATTACHED)
    576573        return VERR_AUDIO_BACKEND_NOT_ATTACHED;
    577 
    578     PAUDMIXSTREAM pMixStream = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM));
    579     if (!pMixStream)
    580         return VERR_NO_MEMORY;
    581574
    582575    PDMAUDIOBACKENDCFG BackendCfg;
    583576    int rc = pConn->pfnGetConfig(pConn, &BackendCfg);
    584577    if (RT_FAILURE(rc))
    585     {
    586         RTMemFree(pMixStream);
    587578        return rc;
    588     }
     579
     580    /*
     581     * Allocate the instance.
     582     */
     583    PAUDMIXSTREAM pMixStream = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM));
     584    AssertReturn(pMixStream, VERR_NO_MEMORY);
     585
     586    pMixStream->fFlags = fFlags;
    589587
    590588    /* Assign the backend's name to the mixer stream's name for easier identification in the (release) log. */
    591589    pMixStream->pszName = RTStrAPrintf2("[%s] %s", pCfg->szName, BackendCfg.szName);
    592     if (!pMixStream->pszName)
    593     {
    594         RTMemFree(pMixStream);
    595         return VERR_NO_MEMORY;
    596     }
    597 
    598     rc = RTCritSectEnter(&pSink->CritSect);
    599     if (RT_FAILURE(rc))
    600         return rc;
    601 
    602     LogFlowFunc(("[%s] fFlags=0x%x (enmDir=%ld, %u bits, %RU8 channels, %RU32Hz)\n", pSink->pszName, fFlags, pCfg->enmDir,
    603                  PDMAudioPropsSampleBits(&pCfg->Props), PDMAudioPropsChannels(&pCfg->Props), pCfg->Props.uHz));
    604 
    605     /*
    606      * Initialize the host-side configuration for the stream to be created.
    607      * Always use the sink's PCM audio format as the host side when creating a stream for it.
    608      */
    609     AssertMsg(AudioHlpPcmPropsAreValid(&pSink->PCMProps),
    610               ("%s: Does not (yet) have a format set when it must\n", pSink->pszName));
    611 
    612     PDMAUDIOSTREAMCFG CfgHost;
    613     rc = PDMAudioStrmCfgInitWithProps(&CfgHost, &pSink->PCMProps);
    614     AssertRCReturn(rc, rc);
    615 
    616     /* Apply the sink's direction for the configuration to use to
    617      * create the stream. */
    618     if (pSink->enmDir == AUDMIXSINKDIR_INPUT)
    619     {
    620         CfgHost.enmDir      = PDMAUDIODIR_IN;
    621         CfgHost.u.enmSrc    = pCfg->u.enmSrc;
    622         CfgHost.enmLayout   = pCfg->enmLayout;
     590    pMixStream->pszStatPrefix = RTStrAPrintf2("Mix-%s/[%s] %s/", pSink->pszName, pCfg->szName, BackendCfg.szName);
     591    if (pMixStream->pszName && pMixStream->pszStatPrefix)
     592    {
     593        rc = RTCritSectInit(&pMixStream->CritSect);
     594        if (RT_SUCCESS(rc))
     595        {
     596            rc = RTCircBufCreate(&pMixStream->pCircBuf, PDMAudioPropsMilliToBytes(&pSink->PCMProps, 100 /*ms*/)); /** @todo Make this configurable. */
     597            if (RT_SUCCESS(rc))
     598            {
     599                pMixStream->StatsCircBufSize = RTCircBufSize(pMixStream->pCircBuf);
     600                pMixStream->StatsCircBufUsed = RTCircBufUsed(pMixStream->pCircBuf);
     601
     602                /*
     603                 * Lock the sink so we can safely get it's properties and call
     604                 * down into the audio driver to create that end of the stream.
     605                 */
     606                rc = RTCritSectEnter(&pSink->CritSect);
     607                AssertRC(rc);
     608                if (RT_SUCCESS(rc))
     609                {
     610                    LogFlowFunc(("[%s] fFlags=0x%x (enmDir=%ld, %u bits, %RU8 channels, %RU32Hz)\n", pSink->pszName, fFlags, pCfg->enmDir,
     611                                 PDMAudioPropsSampleBits(&pCfg->Props), PDMAudioPropsChannels(&pCfg->Props), pCfg->Props.uHz));
     612
     613                    /*
     614                     * Initialize the host-side configuration for the stream to be created.
     615                     * Always use the sink's PCM audio format as the host side when creating a stream for it.
     616                     */
     617                    AssertMsg(AudioHlpPcmPropsAreValid(&pSink->PCMProps),
     618                              ("%s: Does not (yet) have a format set when it must\n", pSink->pszName));
     619
     620                    PDMAUDIOSTREAMCFG CfgHost;
     621                    rc = PDMAudioStrmCfgInitWithProps(&CfgHost, &pSink->PCMProps);
     622                    AssertRC(rc); /* cannot fail */
     623
     624                    /* Apply the sink's direction for the configuration to use to create the stream. */
     625                    if (pSink->enmDir == AUDMIXSINKDIR_INPUT)
     626                    {
     627                        CfgHost.enmDir      = PDMAUDIODIR_IN;
     628                        CfgHost.u.enmSrc    = pCfg->u.enmSrc;
     629                        CfgHost.enmLayout   = pCfg->enmLayout;
     630                    }
     631                    else
     632                    {
     633                        CfgHost.enmDir      = PDMAUDIODIR_OUT;
     634                        CfgHost.u.enmDst    = pCfg->u.enmDst;
     635                        CfgHost.enmLayout   = pCfg->enmLayout;
     636                    }
     637
     638                    RTStrCopy(CfgHost.szName, sizeof(CfgHost.szName), pCfg->szName);
     639
     640                    /*
     641                     * Create the stream.
     642                     */
     643                    PPDMAUDIOSTREAM pStream;
     644                    rc = pConn->pfnStreamCreate(pConn, &CfgHost, pCfg, &pStream);
     645                    if (RT_SUCCESS(rc))
     646                    {
     647                        /* Save the audio stream pointer to this mixing stream. */
     648                        pMixStream->pStream = pStream;
     649
     650                        /* Increase the stream's reference count to let others know
     651                         * we're reyling on it to be around now. */
     652                        pConn->pfnStreamRetain(pConn, pStream);
     653                        pMixStream->pConn = pConn;
     654
     655                        RTCritSectLeave(&pSink->CritSect);
     656
     657                        /*
     658                         * Register statistics before we return.
     659                         */
     660                        PDMDevHlpSTAMRegisterF(pDevIns, &pMixStream->StatsCircBufSize, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
     661                                               "Circular buffer size", "%sCircBufSize", pMixStream->pszStatPrefix);
     662                        PDMDevHlpSTAMRegisterF(pDevIns, &pMixStream->StatsCircBufUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
     663                                               "Circular buffer fill size", "%sCircBufUsed", pMixStream->pszStatPrefix);
     664
     665                        if (ppStream)
     666                            *ppStream = pMixStream;
     667                        return VINF_SUCCESS;
     668                    }
     669
     670                    /*
     671                     * Failed.  Tear down the stream.
     672                     */
     673                    int rc2 = RTCritSectLeave(&pSink->CritSect);
     674                    AssertRC(rc2);
     675                }
     676                RTCircBufDestroy(pMixStream->pCircBuf);
     677            }
     678            RTCritSectDelete(&pMixStream->CritSect);
     679        }
    623680    }
    624681    else
    625     {
    626         CfgHost.enmDir      = PDMAUDIODIR_OUT;
    627         CfgHost.u.enmDst    = pCfg->u.enmDst;
    628         CfgHost.enmLayout   = pCfg->enmLayout;
    629     }
    630 
    631     RTStrPrintf(CfgHost.szName, sizeof(CfgHost.szName), "%s", pCfg->szName);
    632 
    633     rc = RTCritSectInit(&pMixStream->CritSect);
    634     if (RT_SUCCESS(rc))
    635     {
    636         PPDMAUDIOSTREAM pStream;
    637         rc = pConn->pfnStreamCreate(pConn, &CfgHost, pCfg, &pStream);
    638         if (RT_SUCCESS(rc))
    639         {
    640             /* Save the audio stream pointer to this mixing stream. */
    641             pMixStream->pStream = pStream;
    642 
    643             /* Increase the stream's reference count to let others know
    644              * we're reyling on it to be around now. */
    645             pConn->pfnStreamRetain(pConn, pStream);
    646         }
    647     }
    648 
    649     if (RT_SUCCESS(rc))
    650     {
    651         rc = RTCircBufCreate(&pMixStream->pCircBuf, PDMAudioPropsMilliToBytes(&pSink->PCMProps, 100 /*ms*/)); /** @todo Make this configurable. */
    652         AssertRC(rc);
    653     }
    654 
    655     if (RT_SUCCESS(rc))
    656     {
    657         pMixStream->fFlags = fFlags;
    658         pMixStream->pConn  = pConn;
    659 
    660         if (ppStream)
    661             *ppStream = pMixStream;
    662     }
    663     else if (pMixStream)
    664     {
    665         int rc2 = RTCritSectDelete(&pMixStream->CritSect);
    666         AssertRC(rc2);
    667 
    668         if (pMixStream->pszName)
    669         {
    670             RTStrFree(pMixStream->pszName);
    671             pMixStream->pszName = NULL;
    672         }
    673 
    674         RTMemFree(pMixStream);
    675         pMixStream = NULL;
    676     }
    677 
    678     int rc2 = RTCritSectLeave(&pSink->CritSect);
    679     AssertRC(rc2);
    680 
     682        rc = VERR_NO_STR_MEMORY;
     683
     684    RTStrFree(pMixStream->pszStatPrefix);
     685    pMixStream->pszStatPrefix = NULL;
     686    RTStrFree(pMixStream->pszName);
     687    pMixStream->pszName = NULL;
     688    RTMemFree(pMixStream);
    681689    return rc;
    682690}
     
    859867 * Destroys a mixer sink and removes it from the attached mixer (if any).
    860868 *
    861  * @param   pSink               Mixer sink to destroy.
    862  */
    863 void AudioMixerSinkDestroy(PAUDMIXSINK pSink)
     869 * @param   pSink       Mixer sink to destroy.
     870 * @param   pDevIns     The device instance that statistics are registered with.
     871 */
     872void AudioMixerSinkDestroy(PAUDMIXSINK pSink, PPDMDEVINS pDevIns)
    864873{
    865874    if (!pSink)
     
    882891    AssertRC(rc2);
    883892
    884     audioMixerSinkDestroyInternal(pSink);
     893    audioMixerSinkDestroyInternal(pSink, pDevIns);
    885894
    886895    RTMemFree(pSink);
     
    891900 * Destroys a mixer sink.
    892901 *
    893  * @param   pSink               Mixer sink to destroy.
    894  */
    895 static void audioMixerSinkDestroyInternal(PAUDMIXSINK pSink)
     902 * @param   pSink       Mixer sink to destroy.
     903 * @param   pDevIns     The device instance statistics are registered with.
     904 */
     905static void audioMixerSinkDestroyInternal(PAUDMIXSINK pSink, PPDMDEVINS pDevIns)
    896906{
    897907    AssertPtrReturnVoid(pSink);
     
    902912    RTListForEachSafe(&pSink->lstStreams, pStream, pStreamNext, AUDMIXSTREAM, Node)
    903913    {
    904         /* Save a pointer to the stream to remove, as pStream
    905          * will not be valid anymore after calling audioMixerSinkRemoveStreamInternal(). */
    906         PAUDMIXSTREAM pStreamToRemove = pStream;
    907 
    908         audioMixerSinkRemoveStreamInternal(pSink, pStreamToRemove);
    909         audioMixerStreamDestroyInternal(pStreamToRemove);
     914        audioMixerSinkRemoveStreamInternal(pSink, pStream);
     915        audioMixerStreamDestroyInternal(pStream, pDevIns);
    910916    }
    911917
     
    917923    }
    918924
    919     if (pSink->pszName)
    920     {
    921         RTStrFree(pSink->pszName);
    922         pSink->pszName = NULL;
    923     }
    924 
    925     if (pSink->pabScratchBuf)
    926     {
    927         Assert(pSink->cbScratchBuf);
    928 
    929         RTMemFree(pSink->pabScratchBuf);
    930         pSink->pabScratchBuf = NULL;
    931 
    932         pSink->cbScratchBuf = 0;
    933     }
     925    RTStrFree(pSink->pszName);
     926    pSink->pszName = NULL;
     927
     928    RTMemFree(pSink->pabScratchBuf);
     929    pSink->pabScratchBuf = NULL;
     930    pSink->cbScratchBuf = 0;
    934931
    935932    AudioMixBufDestroy(&pSink->MixBuf);
     
    19731970    }
    19741971
     1972    pMixStream->StatsCircBufUsed = RTCircBufUsed(pCircBuf);
    19751973    Log3Func(("[%s] cbWritten=%RU32\n", pMixStream->pszName, cbWritten));
    19761974
     
    20482046
    20492047                pMixStream->tsLastReadWrittenNs = RTTimeNanoTS();
     2048                pMixStream->StatsCircBufUsed    = RTCircBufUsed(pCircBuf);
    20502049                Log3Func(("[%s] Mixer stream '%s' -> cbWrittenBuf=%RU32\n", pSink->pszName, pMixStream->pszName, cbToWrite));
    20512050            }
     
    20782077
    20792078    int rc = RTCritSectEnter(&pSink->CritSect);
    2080     if (RT_FAILURE(rc))
    2081         return rc;
     2079    AssertRCReturn(rc, rc);
    20822080
    20832081    AssertMsg(pSink->fStatus & AUDMIXSINK_STS_RUNNING,
     
    20902088    while (cbToWrite)
    20912089    {
    2092         /* First, write the data to the mixer sink's own mixing buffer.
    2093          * Here the audio data can be transformed into the mixer sink's format. */
    2094         uint32_t cfWritten = 0;
    2095         rc = AudioMixBufWriteCirc(&pSink->MixBuf, (uint8_t *)pvBuf + cbWritten, cbToWrite, &cfWritten);
    2096         if (RT_FAILURE(rc))
     2090        /* Write the data to the mixer sink's own mixing buffer.
     2091           Here the audio data is transformed into the mixer sink's format. */
     2092        uint32_t cFramesWritten = 0;
     2093        rc = AudioMixBufWriteCirc(&pSink->MixBuf, (uint8_t const*)pvBuf + cbWritten, cbToWrite, &cFramesWritten);
     2094        if (RT_SUCCESS(rc))
     2095        {
     2096            const uint32_t cbWrittenChunk = PDMAudioPropsFramesToBytes(&pSink->PCMProps, cFramesWritten);
     2097            Assert(cbToWrite >= cbWrittenChunk);
     2098            cbToWrite -= cbWrittenChunk;
     2099            cbWritten += cbWrittenChunk;
     2100        }
     2101        else
    20972102            break;
    2098 
    2099         const uint32_t cbWrittenChunk = PDMAudioPropsFramesToBytes(&pSink->PCMProps, cfWritten);
    2100 
    2101         Assert(cbToWrite >= cbWrittenChunk);
    2102         cbToWrite -= cbWrittenChunk;
    2103         cbWritten += cbWrittenChunk;
    21042103    }
    21052104
     
    21122111        *pcbWritten = cbWritten;
    21132112
    2114     int rc2 = RTCritSectLeave(&pSink->CritSect);
    2115     AssertRC(rc2);
    2116 
     2113    RTCritSectLeave(&pSink->CritSect);
    21172114    return rc;
    21182115}
     
    22142211 * Destroys a mixer stream, internal version.
    22152212 *
    2216  * @param   pMixStream          Mixer stream to destroy.
    2217  */
    2218 static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pMixStream)
     2213 * @param   pMixStream  Mixer stream to destroy.
     2214 * @param   pDevIns     The device instance the statistics are registered with.
     2215 */
     2216static void audioMixerStreamDestroyInternal(PAUDMIXSTREAM pMixStream, PPDMDEVINS pDevIns)
    22192217{
    22202218    AssertPtrReturnVoid(pMixStream);
     
    22352233    }
    22362234
    2237     if (pMixStream->pszName)
    2238     {
    2239         RTStrFree(pMixStream->pszName);
    2240         pMixStream->pszName = NULL;
    2241     }
     2235    if (pMixStream->pszStatPrefix)
     2236    {
     2237        PDMDevHlpSTAMDeregisterByPrefix(pDevIns, pMixStream->pszStatPrefix);
     2238        RTStrFree(pMixStream->pszStatPrefix);
     2239        pMixStream->pszStatPrefix = NULL;
     2240    }
     2241
     2242    RTStrFree(pMixStream->pszName);
     2243    pMixStream->pszName = NULL;
    22422244
    22432245    if (pMixStream->pCircBuf)
     
    22572259 * Destroys a mixer stream.
    22582260 *
    2259  * @param   pMixStream          Mixer stream to destroy.
    2260  */
    2261 void AudioMixerStreamDestroy(PAUDMIXSTREAM pMixStream)
     2261 * @param   pMixStream      Mixer stream to destroy.
     2262 * @param   pDevIns         The device instance statistics are registered with.
     2263 */
     2264void AudioMixerStreamDestroy(PAUDMIXSTREAM pMixStream, PPDMDEVINS pDevIns)
    22622265{
    22632266    if (!pMixStream)
     
    22902293    if (RT_SUCCESS(rc2))
    22912294    {
    2292         audioMixerStreamDestroyInternal(pMixStream);
     2295        audioMixerStreamDestroyInternal(pMixStream, pDevIns);
    22932296        pMixStream = NULL;
    22942297    }
  • trunk/src/VBox/Devices/Audio/AudioMixer.h

    r87852 r88307  
    8686    /** Name of this stream. */
    8787    char                   *pszName;
     88    /** The statistics prefix. */
     89    char                   *pszStatPrefix;
    8890    /** The streams's critical section. */
    8991    RTCRITSECT              CritSect;
     
    103105     *  holding (raw) device audio data. */
    104106    PRTCIRCBUF              pCircBuf;
     107    /** Stats: Number of bytes used in the circular buffer. */
     108    uint32_t                StatsCircBufUsed;
     109    /** Stats: Size of circular buffer. */
     110    uint32_t                StatsCircBufSize;
    105111} AUDMIXSTREAM, *PAUDMIXSTREAM;
    106112
     
    259265
    260266int AudioMixerCreate(const char *pszName, uint32_t fFlags, PAUDIOMIXER *ppMixer);
    261 int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PAUDMIXSINK *ppSink);
    262 void AudioMixerDestroy(PAUDIOMIXER pMixer);
     267int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PPDMDEVINS pDevIns, PAUDMIXSINK *ppSink);
     268void AudioMixerDestroy(PAUDIOMIXER pMixer, PPDMDEVINS pDevIns);
    263269void AudioMixerInvalidate(PAUDIOMIXER pMixer);
    264270void AudioMixerRemoveSink(PAUDIOMIXER pMixer, PAUDMIXSINK pSink);
     
    267273
    268274int AudioMixerSinkAddStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
    269 int AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg, AUDMIXSTREAMFLAGS fFlags, PAUDMIXSTREAM *ppStream);
     275int     AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg,
     276                                   AUDMIXSTREAMFLAGS fFlags, PPDMDEVINS pDevIns, PAUDMIXSTREAM *ppStream);
    270277int AudioMixerSinkCtl(PAUDMIXSINK pSink, AUDMIXSINKCMD enmCmd);
    271 void AudioMixerSinkDestroy(PAUDMIXSINK pSink);
     278void AudioMixerSinkDestroy(PAUDMIXSINK pSink, PPDMDEVINS pDevIns);
    272279uint32_t AudioMixerSinkGetReadable(PAUDMIXSINK pSink);
    273280uint32_t AudioMixerSinkGetWritable(PAUDMIXSINK pSink);
     
    291298
    292299int AudioMixerStreamCtl(PAUDMIXSTREAM pStream, PDMAUDIOSTREAMCMD enmCmd, uint32_t fCtl);
    293 void AudioMixerStreamDestroy(PAUDMIXSTREAM pStream);
     300void AudioMixerStreamDestroy(PAUDMIXSTREAM pStream, PPDMDEVINS pDevIns);
    294301bool AudioMixerStreamIsActive(PAUDMIXSTREAM pStream);
    295302bool AudioMixerStreamIsValid(PAUDMIXSTREAM pStream);
  • trunk/src/VBox/Devices/Audio/DevHda.cpp

    r88300 r88307  
    360360 */
    361361#ifdef IN_RING3
    362 static int hdaR3MixerAddDrvStream(PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv);
     362static int hdaR3MixerAddDrvStream(PPDMDEVINS pDevIns, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv);
    363363#endif
    364364/** @} */
     
    21852185 *
    21862186 * @returns VBox status code.
     2187 * @param   pDevIns     The HDA device instance.
    21872188 * @param   pThisCC     The ring-3 HDA device state.
    21882189 * @param   pDrv        HDA driver to add.
    21892190 */
    2190 static int hdaR3MixerAddDrv(PHDASTATER3 pThisCC, PHDADRIVER pDrv)
     2191static int hdaR3MixerAddDrv(PPDMDEVINS pDevIns, PHDASTATER3 pThisCC, PHDADRIVER pDrv)
    21912192{
    21922193    int rc = VINF_SUCCESS;
     
    21962197        && AudioHlpStreamCfgIsValid(&pStream->State.Cfg))
    21972198    {
    2198         int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkLineIn.pMixSink, &pStream->State.Cfg, pDrv);
     2199        int rc2 = hdaR3MixerAddDrvStream(pDevIns, pThisCC->SinkLineIn.pMixSink, &pStream->State.Cfg, pDrv);
    21992200        if (RT_SUCCESS(rc))
    22002201            rc = rc2;
     
    22062207        && AudioHlpStreamCfgIsValid(&pStream->State.Cfg))
    22072208    {
    2208         int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkMicIn.pMixSink, &pStream->State.Cfg, pDrv);
     2209        int rc2 = hdaR3MixerAddDrvStream(pDevIns, pThisCC->SinkMicIn.pMixSink, &pStream->State.Cfg, pDrv);
    22092210        if (RT_SUCCESS(rc))
    22102211            rc = rc2;
     
    22162217        && AudioHlpStreamCfgIsValid(&pStream->State.Cfg))
    22172218    {
    2218         int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkFront.pMixSink, &pStream->State.Cfg, pDrv);
     2219        int rc2 = hdaR3MixerAddDrvStream(pDevIns, pThisCC->SinkFront.pMixSink, &pStream->State.Cfg, pDrv);
    22192220        if (RT_SUCCESS(rc))
    22202221            rc = rc2;
     
    22262227        && AudioHlpStreamCfgIsValid(&pStream->State.Cfg))
    22272228    {
    2228         int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkCenterLFE.pMixSink, &pStream->State.Cfg, pDrv);
     2229        int rc2 = hdaR3MixerAddDrvStream(pDevIns, pThisCC->SinkCenterLFE.pMixSink, &pStream->State.Cfg, pDrv);
    22292230        if (RT_SUCCESS(rc))
    22302231            rc = rc2;
     
    22352236        && AudioHlpStreamCfgIsValid(&pStream->State.Cfg))
    22362237    {
    2237         int rc2 = hdaR3MixerAddDrvStream(pThisCC->SinkRear.pMixSink, &pStream->State.Cfg, pDrv);
     2238        int rc2 = hdaR3MixerAddDrvStream(pDevIns, pThisCC->SinkRear.pMixSink, &pStream->State.Cfg, pDrv);
    22382239        if (RT_SUCCESS(rc))
    22392240            rc = rc2;
     
    22482249 * associated streams.
    22492250 *
    2250  * @param   pThisCC             The ring-3 HDA device state.
    2251  * @param   pDrv                HDA driver to remove.
    2252  */
    2253 static void hdaR3MixerRemoveDrv(PHDASTATER3 pThisCC, PHDADRIVER pDrv)
     2251 * @param   pDevIns     The device instance.
     2252 * @param   pThisCC     The ring-3 HDA device state.
     2253 * @param   pDrv        HDA driver to remove.
     2254 */
     2255static void hdaR3MixerRemoveDrv(PPDMDEVINS pDevIns, PHDASTATER3 pThisCC, PHDADRIVER pDrv)
    22542256{
    22552257    AssertPtrReturnVoid(pDrv);
     
    22612263
    22622264        AudioMixerSinkRemoveStream(pThisCC->SinkLineIn.pMixSink, pDrv->LineIn.pMixStrm);
    2263         AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm);
     2265        AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm, pDevIns);
    22642266        pDrv->LineIn.pMixStrm = NULL;
    22652267    }
     
    22722274
    22732275        AudioMixerSinkRemoveStream(pThisCC->SinkMicIn.pMixSink, pDrv->MicIn.pMixStrm);
    2274         AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm);
     2276        AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm, pDevIns);
    22752277        pDrv->MicIn.pMixStrm = NULL;
    22762278    }
     
    22802282    {
    22812283        AudioMixerSinkRemoveStream(pThisCC->SinkFront.pMixSink, pDrv->Front.pMixStrm);
    2282         AudioMixerStreamDestroy(pDrv->Front.pMixStrm);
     2284        AudioMixerStreamDestroy(pDrv->Front.pMixStrm, pDevIns);
    22832285        pDrv->Front.pMixStrm = NULL;
    22842286    }
     
    22882290    {
    22892291        AudioMixerSinkRemoveStream(pThisCC->SinkCenterLFE.pMixSink, pDrv->CenterLFE.pMixStrm);
    2290         AudioMixerStreamDestroy(pDrv->CenterLFE.pMixStrm);
     2292        AudioMixerStreamDestroy(pDrv->CenterLFE.pMixStrm, pDevIns);
    22912293        pDrv->CenterLFE.pMixStrm = NULL;
    22922294    }
     
    22952297    {
    22962298        AudioMixerSinkRemoveStream(pThisCC->SinkRear.pMixSink, pDrv->Rear.pMixStrm);
    2297         AudioMixerStreamDestroy(pDrv->Rear.pMixStrm);
     2299        AudioMixerStreamDestroy(pDrv->Rear.pMixStrm, pDevIns);
    22982300        pDrv->Rear.pMixStrm = NULL;
    22992301    }
     
    23072309 *
    23082310 * @returns VBox status code (ignored by caller).
    2309  * @param   pMixSink            Audio mixer sink to add audio streams to.
    2310  * @param   pCfg                Audio stream configuration to use for the audio streams to add.
    2311  * @param   pDrv                Driver stream to add.
    2312  */
    2313 static int hdaR3MixerAddDrvStream(PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv)
     2311 * @param   pDevIns     The HDA device instance.
     2312 * @param   pMixSink    Audio mixer sink to add audio streams to.
     2313 * @param   pCfg        Audio stream configuration to use for the audio
     2314 *                      streams to add.
     2315 * @param   pDrv        Driver stream to add.
     2316 */
     2317static int hdaR3MixerAddDrvStream(PPDMDEVINS pDevIns, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv)
    23142318{
    23152319    AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
     
    23182322    LogFunc(("szSink=%s, szStream=%s, cChannels=%RU8\n", pMixSink->pszName, pCfg->szName, PDMAudioPropsChannels(&pCfg->Props)));
    23192323
    2320     PPDMAUDIOSTREAMCFG pStreamCfg = PDMAudioStrmCfgDup(pCfg);
    2321     if (!pStreamCfg)
    2322         return VERR_NO_MEMORY;
    2323 
    2324     LogFunc(("[LUN#%RU8] %s\n", pDrv->uLUN, pStreamCfg->szName));
    2325 
    2326     int rc = VINF_SUCCESS;
    2327 
     2324    /*
     2325     * Get the matching stream driver.
     2326     */
    23282327    PHDADRIVERSTREAM pDrvStream = NULL;
    2329 
    2330     if (pStreamCfg->enmDir == PDMAUDIODIR_IN)
    2331     {
    2332         LogFunc(("enmRecSource=%d\n", pStreamCfg->u.enmSrc));
    2333 
    2334         switch (pStreamCfg->u.enmSrc)
     2328    if (pCfg->enmDir == PDMAUDIODIR_IN)
     2329    {
     2330        LogFunc(("enmSrc=%d\n", pCfg->u.enmSrc));
     2331        switch (pCfg->u.enmSrc)
    23352332        {
    23362333            case PDMAUDIORECSRC_LINE:
     
    23432340# endif
    23442341            default:
    2345                 rc = VERR_NOT_SUPPORTED;
    2346                 break;
    2347         }
    2348     }
    2349     else if (pStreamCfg->enmDir == PDMAUDIODIR_OUT)
    2350     {
    2351         LogFunc(("enmPlaybackDest=%d\n", pStreamCfg->u.enmDst));
    2352 
    2353         switch (pStreamCfg->u.enmDst)
     2342                LogFunc(("returns VERR_NOT_SUPPORTED - enmSrc=%d\n", pCfg->u.enmSrc));
     2343                return VERR_NOT_SUPPORTED;
     2344        }
     2345    }
     2346    else if (pCfg->enmDir == PDMAUDIODIR_OUT)
     2347    {
     2348        LogFunc(("enmDst=%d %s\n", pCfg->u.enmDst, PDMAudioPlaybackDstGetName(pCfg->u.enmDst)));
     2349        switch (pCfg->u.enmDst)
    23542350        {
    23552351            case PDMAUDIOPLAYBACKDST_FRONT:
     
    23652361# endif
    23662362            default:
    2367                 rc = VERR_NOT_SUPPORTED;
    2368                 break;
     2363                LogFunc(("returns VERR_NOT_SUPPORTED - enmDst=%d %s\n", pCfg->u.enmDst, PDMAudioPlaybackDstGetName(pCfg->u.enmDst)));
     2364                return VERR_NOT_SUPPORTED;
    23692365        }
    23702366    }
    23712367    else
    2372         rc = VERR_NOT_SUPPORTED;
    2373 
     2368        AssertFailedReturn(VERR_NOT_SUPPORTED);
     2369
     2370    PDMAUDIOSTREAMCFG StreamCfg; /** @todo r=bird: Why do we need to copy this? (We used to duplicate it originally.) */
     2371    PDMAudioStrmCfgCopy(&StreamCfg, pCfg);
     2372
     2373    LogFunc(("[LUN#%RU8] %s\n", pDrv->uLUN, StreamCfg.szName));
     2374
     2375    AssertPtr(pDrvStream);
     2376    AssertMsg(pDrvStream->pMixStrm == NULL, ("[LUN#%RU8] Driver stream already present when it must not\n", pDrv->uLUN));
     2377
     2378    PAUDMIXSTREAM pMixStrm = NULL;
     2379    int rc = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, &StreamCfg, 0 /* fFlags */, pDevIns, &pMixStrm);
     2380    LogFlowFunc(("LUN#%RU8: Created stream \"%s\" for sink, rc=%Rrc\n", pDrv->uLUN, StreamCfg.szName, rc));
    23742381    if (RT_SUCCESS(rc))
    23752382    {
    2376         AssertPtr(pDrvStream);
    2377         AssertMsg(pDrvStream->pMixStrm == NULL, ("[LUN#%RU8] Driver stream already present when it must not\n", pDrv->uLUN));
    2378 
    2379         PAUDMIXSTREAM pMixStrm;
    2380         rc = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, pStreamCfg, 0 /* fFlags */, &pMixStrm);
    2381         LogFlowFunc(("LUN#%RU8: Created stream \"%s\" for sink, rc=%Rrc\n", pDrv->uLUN, pStreamCfg->szName, rc));
     2383        rc = AudioMixerSinkAddStream(pMixSink, pMixStrm);
     2384        LogFlowFunc(("LUN#%RU8: Added stream \"%s\" to sink, rc=%Rrc\n", pDrv->uLUN, StreamCfg.szName, rc));
    23822385        if (RT_SUCCESS(rc))
    23832386        {
    2384             rc = AudioMixerSinkAddStream(pMixSink, pMixStrm);
    2385             LogFlowFunc(("LUN#%RU8: Added stream \"%s\" to sink, rc=%Rrc\n", pDrv->uLUN, pStreamCfg->szName, rc));
    2386             if (RT_SUCCESS(rc))
     2387            /* If this is an input stream, always set the latest (added) stream
     2388             * as the recording source. */
     2389            /** @todo Make the recording source dynamic (CFGM?). */
     2390            if (StreamCfg.enmDir == PDMAUDIODIR_IN)
    23872391            {
    2388                 /* If this is an input stream, always set the latest (added) stream
    2389                  * as the recording source. */
    2390                 /** @todo Make the recording source dynamic (CFGM?). */
    2391                 if (pStreamCfg->enmDir == PDMAUDIODIR_IN)
     2392                PDMAUDIOBACKENDCFG Cfg;
     2393                rc = pDrv->pConnector->pfnGetConfig(pDrv->pConnector, &Cfg);
     2394                if (RT_SUCCESS(rc))
    23922395                {
    2393                     PDMAUDIOBACKENDCFG Cfg;
    2394                     rc = pDrv->pConnector->pfnGetConfig(pDrv->pConnector, &Cfg);
    2395                     if (RT_SUCCESS(rc))
     2396                    if (Cfg.cMaxStreamsIn) /* At least one input source available? */
    23962397                    {
    2397                         if (Cfg.cMaxStreamsIn) /* At least one input source available? */
    2398                         {
    2399                             rc = AudioMixerSinkSetRecordingSource(pMixSink, pMixStrm);
    2400                             LogFlowFunc(("LUN#%RU8: Recording source for '%s' -> '%s', rc=%Rrc\n",
    2401                                          pDrv->uLUN, pStreamCfg->szName, Cfg.szName, rc));
    2402 
    2403                             if (RT_SUCCESS(rc))
    2404                                 LogRel(("HDA: Set recording source for '%s' to '%s'\n",
    2405                                         pStreamCfg->szName, Cfg.szName));
    2406                         }
    2407                         else
    2408                             LogRel(("HDA: Backend '%s' currently is not offering any recording source for '%s'\n",
    2409                                     Cfg.szName, pStreamCfg->szName));
     2398                        rc = AudioMixerSinkSetRecordingSource(pMixSink, pMixStrm);
     2399                        LogFlowFunc(("LUN#%RU8: Recording source for '%s' -> '%s', rc=%Rrc\n",
     2400                                     pDrv->uLUN, StreamCfg.szName, Cfg.szName, rc));
     2401
     2402                        if (RT_SUCCESS(rc))
     2403                            LogRel(("HDA: Set recording source for '%s' to '%s'\n",
     2404                                    StreamCfg.szName, Cfg.szName));
    24102405                    }
    2411                     else if (RT_FAILURE(rc))
    2412                         LogFunc(("LUN#%RU8: Unable to retrieve backend configuration for '%s', rc=%Rrc\n",
    2413                                  pDrv->uLUN, pStreamCfg->szName, rc));
     2406                    else
     2407                        LogRel(("HDA: Backend '%s' currently is not offering any recording source for '%s'\n",
     2408                                Cfg.szName, StreamCfg.szName));
    24142409                }
     2410                else if (RT_FAILURE(rc))
     2411                    LogFunc(("LUN#%RU8: Unable to retrieve backend configuration for '%s', rc=%Rrc\n",
     2412                             pDrv->uLUN, StreamCfg.szName, rc));
    24152413            }
    24162414        }
    2417 
    2418         if (RT_SUCCESS(rc))
    2419             pDrvStream->pMixStrm = pMixStrm;
    2420     }
    2421 
    2422     PDMAudioStrmCfgFree(pStreamCfg);
     2415/** @todo r=bird: We are missing cleanup code here!   */
     2416    }
     2417
     2418    if (RT_SUCCESS(rc))
     2419        pDrvStream->pMixStrm = pMixStrm;
    24232420
    24242421    LogFlowFuncLeaveRC(rc);
     
    24302427 *
    24312428 * @returns VBox status code.
    2432  * @param   pThisCC             The ring-3 HDA device state.
    2433  * @param   pMixSink            Audio mixer sink to add stream to.
    2434  * @param   pCfg                Audio stream configuration to use for the audio streams to add.
    2435  */
    2436 static int hdaR3MixerAddDrvStreams(PHDASTATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
     2429 * @param   pDevIns     The HDA device instance.
     2430 * @param   pThisCC     The ring-3 HDA device state.
     2431 * @param   pMixSink    Audio mixer sink to add stream to.
     2432 * @param   pCfg        Audio stream configuration to use for the audio streams
     2433 *                      to add.
     2434 */
     2435static int hdaR3MixerAddDrvStreams(PPDMDEVINS pDevIns, PHDASTATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
    24372436{
    24382437    AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
     
    24452444
    24462445    int rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props);
    2447     if (RT_FAILURE(rc))
    2448         return rc;
    2449 
    2450     PHDADRIVER pDrv;
    2451     RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node)
    2452     {
    2453         int rc2 = hdaR3MixerAddDrvStream(pMixSink, pCfg, pDrv);
    2454         if (RT_FAILURE(rc2))
    2455             LogFunc(("Attaching stream failed with %Rrc\n", rc2));
    2456 
    2457         /* Do not pass failure to rc here, as there might be drivers which aren't
    2458          * configured / ready yet. */
    2459     }
    2460 
     2446    if (RT_SUCCESS(rc))
     2447    {
     2448        PHDADRIVER pDrv;
     2449        RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node)
     2450        {
     2451            int rc2 = hdaR3MixerAddDrvStream(pDevIns, pMixSink, pCfg, pDrv);
     2452            if (RT_FAILURE(rc2))
     2453                LogFunc(("Attaching stream failed with %Rrc\n", rc2));
     2454
     2455            /* Do not pass failure to rc here, as there might be drivers which aren't
     2456             * configured / ready yet. */
     2457        }
     2458    }
    24612459    return rc;
    24622460}
     
    24742472    if (pSink)
    24752473    {
    2476         rc = hdaR3MixerAddDrvStreams(pThisCC, pSink->pMixSink, pCfg);
     2474        rc = hdaR3MixerAddDrvStreams(pDevIns, pThisCC, pSink->pMixSink, pCfg);
    24772475
    24782476        AssertPtr(pSink->pMixSink);
     
    25412539            {
    25422540                AudioMixerSinkRemoveStream(pSink->pMixSink, pMixStream);
    2543                 AudioMixerStreamDestroy(pMixStream);
     2541                AudioMixerStreamDestroy(pMixStream, pDevIns);
    25442542
    25452543                pMixStream = NULL;
     
    34533451    AssertRCReturn(rc, rc);
    34543452
    3455     uint32_t cbCircBufSize = 0;
     3453    uint32_t cbCircBuf    = 0;
    34563454    uint32_t cbCircBufUsed = 0;
    34573455
    34583456    if (pStreamR3->State.pCircBuf)
    34593457    {
    3460         cbCircBufSize = (uint32_t)RTCircBufSize(pStreamR3->State.pCircBuf);
     3458        cbCircBuf    = (uint32_t)RTCircBufSize(pStreamR3->State.pCircBuf);
    34613459        cbCircBufUsed = (uint32_t)RTCircBufUsed(pStreamR3->State.pCircBuf);
    34623460    }
    34633461
    3464     rc = pHlp->pfnSSMPutU32(pSSM, cbCircBufSize);
    3465     AssertRCReturn(rc, rc);
    3466 
     3462    pHlp->pfnSSMPutU32(pSSM, cbCircBuf);
    34673463    rc = pHlp->pfnSSMPutU32(pSSM, cbCircBufUsed);
    34683464    AssertRCReturn(rc, rc);
     
    40454041         * Load internal (FIFO) buffer.
    40464042         */
    4047         uint32_t cbCircBufSize = 0;
    4048         pHlp->pfnSSMGetU32(pSSM, &cbCircBufSize); /* cbCircBuf */
     4043        uint32_t cbCircBuf = 0;
     4044        pHlp->pfnSSMGetU32(pSSM, &cbCircBuf); /* cbCircBuf */
    40494045        uint32_t cbCircBufUsed = 0;
    40504046        rc = pHlp->pfnSSMGetU32(pSSM, &cbCircBufUsed); /* cbCircBuf */
    40514047        AssertRCReturn(rc, rc);
    40524048
    4053         if (cbCircBufSize) /* If 0, skip the buffer. */
     4049        if (cbCircBuf) /* If 0, skip the buffer. */
    40544050        {
    40554051            /* Paranoia. */
    4056             AssertLogRelMsgReturn(cbCircBufSize <= _32M,
     4052            AssertLogRelMsgReturn(cbCircBuf <= _32M,
    40574053                                  ("HDA: Saved state contains bogus DMA buffer size (%RU32) for stream #%RU8",
    4058                                    cbCircBufSize, idStream),
     4054                                   cbCircBuf, idStream),
    40594055                                  VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
    4060             AssertLogRelMsgReturn(cbCircBufUsed <= cbCircBufSize,
     4056            AssertLogRelMsgReturn(cbCircBufUsed <= cbCircBuf,
    40614057                                  ("HDA: Saved state contains invalid DMA buffer usage (%RU32/%RU32) for stream #%RU8",
    4062                                    cbCircBufUsed, cbCircBufSize, idStream),
     4058                                   cbCircBufUsed, cbCircBuf, idStream),
    40634059                                  VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
    40644060
    40654061            /* Do we need to cre-create the circular buffer do fit the data size? */
    40664062            if (   pStreamR3->State.pCircBuf
    4067                 && cbCircBufSize != (uint32_t)RTCircBufSize(pStreamR3->State.pCircBuf))
     4063                && cbCircBuf != (uint32_t)RTCircBufSize(pStreamR3->State.pCircBuf))
    40684064            {
    40694065                RTCircBufDestroy(pStreamR3->State.pCircBuf);
     
    40714067            }
    40724068
    4073             rc = RTCircBufCreate(&pStreamR3->State.pCircBuf, cbCircBufSize);
     4069            rc = RTCircBufCreate(&pStreamR3->State.pCircBuf, cbCircBuf);
    40744070            AssertRCReturn(rc, rc);
     4071            pStreamR3->State.StatDmaBufSize = cbCircBuf;
    40754072
    40764073            if (cbCircBufUsed)
     
    45244521 *
    45254522 * @returns VBox status code.
     4523 * @param   pDevIns     The device instance.
    45264524 * @param   pThisCC     The ring-3 HDA device state.
    45274525 * @param   pDrv        Driver to detach from device.
    45284526 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    45294527 */
    4530 static int hdaR3DetachInternal(PHDASTATER3 pThisCC, PHDADRIVER pDrv, uint32_t fFlags)
     4528static int hdaR3DetachInternal(PPDMDEVINS pDevIns, PHDASTATER3 pThisCC, PHDADRIVER pDrv, uint32_t fFlags)
    45314529{
    45324530    RT_NOREF(fFlags);
     
    45344532    /* First, remove the driver from our list and destory it's associated streams.
    45354533     * This also will un-set the driver as a recording source (if associated). */
    4536     hdaR3MixerRemoveDrv(pThisCC, pDrv);
     4534    hdaR3MixerRemoveDrv(pDevIns, pThisCC, pDrv);
    45374535
    45384536    /* Next, search backwards for a capable (attached) driver which now will be the
     
    45894587    int rc2 = hdaR3AttachInternal(pDevIns, pThis, pThisCC, uLUN, fFlags, &pDrv);
    45904588    if (RT_SUCCESS(rc2))
    4591         rc2 = hdaR3MixerAddDrv(pThisCC, pDrv);
     4589        rc2 = hdaR3MixerAddDrv(pDevIns, pThisCC, pDrv);
    45924590
    45934591    if (RT_FAILURE(rc2))
     
    46164614        if (pDrv->uLUN == uLUN)
    46174615        {
    4618             int rc2 = hdaR3DetachInternal(pThisCC, pDrv, fFlags);
     4616            int rc2 = hdaR3DetachInternal(pDevIns, pThisCC, pDrv, fFlags);
    46194617            if (RT_SUCCESS(rc2))
    46204618            {
     
    46224620                pDrv = NULL;
    46234621            }
    4624 
    46254622            break;
    46264623        }
     
    46544651    if (pThisCC->pMixer)
    46554652    {
    4656         AudioMixerDestroy(pThisCC->pMixer);
     4653        AudioMixerDestroy(pThisCC->pMixer, pDevIns);
    46574654        pThisCC->pMixer = NULL;
    46584655    }
     
    50225019     */
    50235020# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    5024     rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Front", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkFront.pMixSink);
     5021    rc = AudioMixerCreateSink(pThisCC->pMixer, "Front",
     5022                              AUDMIXSINKDIR_OUTPUT, pDevIns, &pThisCC->SinkFront.pMixSink);
    50255023    AssertRCReturn(rc, rc);
    5026     rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Center / Subwoofer", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkCenterLFE.pMixSink);
     5024    rc = AudioMixerCreateSink(pThisCC->pMixer, "Center+Subwoofer",
     5025                              AUDMIXSINKDIR_OUTPUT, pDevIns, &pThisCC->SinkCenterLFE.pMixSink);
    50275026    AssertRCReturn(rc, rc);
    5028     rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] Rear", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkRear.pMixSink);
     5027    rc = AudioMixerCreateSink(pThisCC->pMixer, "Rear",
     5028                              AUDMIXSINKDIR_OUTPUT, pDevIns, &pThisCC->SinkRear.pMixSink);
    50295029    AssertRCReturn(rc, rc);
    50305030# else
    5031     rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThisCC->SinkFront.pMixSink);
     5031    rc = AudioMixerCreateSink(pThisCC->pMixer, "PCM Output",
     5032                              AUDMIXSINKDIR_OUTPUT, pDevIns, &pThisCC->SinkFront.pMixSink);
    50325033    AssertRCReturn(rc, rc);
    50335034# endif /* VBOX_WITH_AUDIO_HDA_51_SURROUND */
     
    50365037     * Add mixer input sinks.
    50375038     */
    5038     rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThisCC->SinkLineIn.pMixSink);
     5039    rc = AudioMixerCreateSink(pThisCC->pMixer, "Line In",
     5040                              AUDMIXSINKDIR_INPUT, pDevIns, &pThisCC->SinkLineIn.pMixSink);
    50395041    AssertRCReturn(rc, rc);
    50405042# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    5041     rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThisCC->SinkMicIn.pMixSink);
     5043    rc = AudioMixerCreateSink(pThisCC->pMixer, "Microphone In",
     5044                              AUDMIXSINKDIR_INPUT, pDevIns, &pThisCC->SinkMicIn.pMixSink);
    50425045    AssertRCReturn(rc, rc);
    50435046# endif
     
    53575360        PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.Mapping.GuestProps.cbFrame, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
    53585361                               "The number of channels.",                   "Stream%u/Cfg/FrameSize-Guest", idxStream);
    5359 #if 0 /** @todo this would require some callback */
     5362#if 0 /** @todo this would require some callback or expansion. */
    53605363        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStreams[idxStream].State.Cfg.Props.cChannelsX, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_BYTES,
    53615364                               "The number of channels.",                   "Stream%u/Cfg/Channels-Host", idxStream);
     
    53655368                               "The size of a sample (per channel).",       "Stream%u/Cfg/cbSample", idxStream);
    53665369#endif
     5370
     5371        PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaBufSize, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
     5372                               "Size of the internal DMA buffer.",  "Stream%u/DMABufSize", idxStream);
     5373        PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aStreams[idxStream].State.StatDmaBufUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_BYTES,
     5374                               "Number of bytes used in the internal DMA buffer.",  "Stream%u/DMABufUsed", idxStream);
    53675375    }
    53685376
  • trunk/src/VBox/Devices/Audio/DevHdaStream.cpp

    r88300 r88307  
    191191        RTCircBufDestroy(pStreamR3->State.pCircBuf);
    192192        pStreamR3->State.pCircBuf = NULL;
     193        pStreamR3->State.StatDmaBufSize = 0;
     194        pStreamR3->State.StatDmaBufUsed = 0;
    193195    }
    194196
     
    692694        RTCircBufDestroy(pStreamR3->State.pCircBuf);
    693695        pStreamR3->State.pCircBuf = NULL;
     696        pStreamR3->State.StatDmaBufSize = 0;
     697        pStreamR3->State.StatDmaBufUsed = 0;
    694698    }
    695699    pStreamR3->State.offWrite = 0;
     
    750754        if (RT_SUCCESS(rc))
    751755        {
     756            pStreamR3->State.StatDmaBufSize = cbCircBuf;
     757
    752758            /*
    753759             * Forward the timer frequency hint to TM as well for better accuracy on
     
    12161222 * @param   pDevIns         The device instance.
    12171223 * @param   pThis           The shared HDA device state.
    1218  * @param   pStreamShared   HDA stream to update (shared).
    1219  */
    1220 DECLINLINE(void) hdaR3StreamDoDmaEpilogue(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared)
     1224 * @param   pStreamShared   The HDA stream (shared).
     1225 * @param   pStreamR3       The HDA stream (ring-3).
     1226 */
     1227DECLINLINE(void) hdaR3StreamDoDmaEpilogue(PPDMDEVINS pDevIns, PHDASTATE pThis, PHDASTREAM pStreamShared, PHDASTREAMR3 pStreamR3)
    12211228{
    12221229    /*
     
    12321239     */
    12331240    pStreamShared->State.tsTransferLast = PDMDevHlpTimerGet(pDevIns, pStreamShared->hTimer);
     1241
     1242    /*
     1243     * Update the buffer statistics.
     1244     */
     1245    pStreamR3->State.StatDmaBufUsed = RTCircBufUsed(pStreamR3->State.pCircBuf);
    12341246}
    12351247
     
    15131525     * Common epilogue.
    15141526     */
    1515     hdaR3StreamDoDmaEpilogue(pDevIns, pThis, pStreamShared);
     1527    hdaR3StreamDoDmaEpilogue(pDevIns, pThis, pStreamShared, pStreamR3);
    15161528
    15171529    /*
     
    15961608        cbSinkReadable -= cbRead;
    15971609    }
     1610
     1611    /* Update buffer stats. */
     1612    pStreamR3->State.StatDmaBufUsed = RTCircBufUsed(pStreamR3->State.pCircBuf);
    15981613}
    15991614
     
    17971812     * Common epilogue.
    17981813     */
    1799     hdaR3StreamDoDmaEpilogue(pDevIns, pThis, pStreamShared);
     1814    hdaR3StreamDoDmaEpilogue(pDevIns, pThis, pStreamShared, pStreamR3);
    18001815
    18011816    /*
     
    18631878    }
    18641879
     1880    /* Update buffer stats. */
     1881    pStreamR3->State.StatDmaBufUsed = RTCircBufUsed(pStreamR3->State.pCircBuf);
     1882
     1883    /*
     1884     * Push the stuff thru the mixer jungle and down the host audio driver (backend).
     1885     */
    18651886    int rc2 = AudioMixerSinkUpdate(pSink);
    18661887    AssertRC(rc2);
  • trunk/src/VBox/Devices/Audio/DevHdaStream.h

    r88235 r88307  
    316316        HDASTREAMSTATEAIO       AIO;
    317317#endif
     318        /** Size of the DMA buffer (pCircBuf) in bytes. */
     319        uint32_t                StatDmaBufSize;
     320        /** Number of used bytes in the DMA buffer (pCircBuf). */
     321        uint32_t                StatDmaBufUsed;
    318322        /** Counter for all under/overflows problems. */
    319323        STAMCOUNTER             StatDmaFlowProblems;
     
    325329    /** Debug bits. */
    326330    HDASTREAMDEBUG              Dbg;
    327     uint64_t                    au64Alignment[2];
     331    uint64_t                    au64Alignment[1];
    328332} HDASTREAMR3;
    329333AssertCompileSizeAlignment(HDASTREAMR3, 64);
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r88300 r88307  
    682682*********************************************************************************************************************************/
    683683#ifdef IN_RING3
    684 static int                ichac97R3StreamOpen(PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce);
     684static int                ichac97R3StreamOpen(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream,
     685                                              PAC97STREAMR3 pStreamCC, bool fForce);
    685686static int                ichac97R3StreamClose(PAC97STREAM pStream);
    686687static void               ichac97R3StreamLock(PAC97STREAMR3 pStreamCC);
     
    695696static DECLCALLBACK(void) ichac97R3Reset(PPDMDEVINS pDevIns);
    696697
    697 static void               ichac97R3MixerRemoveDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir,
    698                                                          PDMAUDIODSTSRCUNION dstSrc);
     698static void               ichac97R3MixerRemoveDrvStreams(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink,
     699                                                         PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc);
    699700
    700701# ifdef VBOX_WITH_AUDIO_AC97_ASYNC_IO
     
    968969 *
    969970 * @returns VBox status code.
    970  * @param   pThis               The shared AC'97 state.
    971  * @param   pThisCC             The ring-3 AC'97 state.
    972  * @param   pStream             The AC'97 stream to enable or disable (shared
    973  *                              state).
    974  * @param   pStreamCC           The ring-3 stream state (matching to @a pStream).
    975  * @param   fEnable             Whether to enable or disable the stream.
    976  *
    977  */
    978 static int ichac97R3StreamEnable(PAC97STATE pThis, PAC97STATER3 pThisCC,
     971 * @param   pDevIns     The device instance.
     972 * @param   pThis       The shared AC'97 state.
     973 * @param   pThisCC     The ring-3 AC'97 state.
     974 * @param   pStream     The AC'97 stream to enable or disable (shared
     975 *                      state).
     976 * @param   pStreamCC   The ring-3 stream state (matching to @a pStream).
     977 * @param   fEnable     Whether to enable or disable the stream.
     978 *
     979 */
     980static int ichac97R3StreamEnable(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC,
    979981                                 PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fEnable)
    980982{
     
    995997            RTCircBufReset(pStreamCC->State.pCircBuf);
    996998
    997         rc = ichac97R3StreamOpen(pThis, pThisCC, pStream, pStreamCC, false /* fForce */);
     999        rc = ichac97R3StreamOpen(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fForce */);
    9981000
    9991001        if (RT_LIKELY(!pStreamCC->Dbg.Runtime.fEnabled))
     
    11761178 * Destroys all AC'97 audio streams of the device.
    11771179 *
    1178  * @param   pThis               The shared AC'97 state.
    1179  * @param   pThisCC             The ring-3 AC'97 state.
    1180  */
    1181 static void ichac97R3StreamsDestroy(PAC97STATE pThis, PAC97STATER3 pThisCC)
     1180 * @param   pDevIns     The device AC'97 instance.
     1181 * @param   pThis       The shared AC'97 state.
     1182 * @param   pThisCC     The ring-3 AC'97 state.
     1183 */
     1184static void ichac97R3StreamsDestroy(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC)
    11821185{
    11831186    LogFlowFuncEnter();
     
    11971200    {
    11981201        dstSrc.enmSrc = PDMAUDIORECSRC_LINE;
    1199         ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkLineIn, PDMAUDIODIR_IN, dstSrc);
    1200 
    1201         AudioMixerSinkDestroy(pThisCC->pSinkLineIn);
     1202        ichac97R3MixerRemoveDrvStreams(pDevIns, pThisCC, pThisCC->pSinkLineIn, PDMAUDIODIR_IN, dstSrc);
     1203
     1204        AudioMixerSinkDestroy(pThisCC->pSinkLineIn, pDevIns);
    12021205        pThisCC->pSinkLineIn = NULL;
    12031206    }
     
    12061209    {
    12071210        dstSrc.enmSrc = PDMAUDIORECSRC_MIC;
    1208         ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkMicIn, PDMAUDIODIR_IN, dstSrc);
    1209 
    1210         AudioMixerSinkDestroy(pThisCC->pSinkMicIn);
     1211        ichac97R3MixerRemoveDrvStreams(pDevIns, pThisCC, pThisCC->pSinkMicIn, PDMAUDIODIR_IN, dstSrc);
     1212
     1213        AudioMixerSinkDestroy(pThisCC->pSinkMicIn, pDevIns);
    12111214        pThisCC->pSinkMicIn = NULL;
    12121215    }
     
    12151218    {
    12161219        dstSrc.enmDst = PDMAUDIOPLAYBACKDST_FRONT;
    1217         ichac97R3MixerRemoveDrvStreams(pThisCC, pThisCC->pSinkOut, PDMAUDIODIR_OUT, dstSrc);
    1218 
    1219         AudioMixerSinkDestroy(pThisCC->pSinkOut);
     1220        ichac97R3MixerRemoveDrvStreams(pDevIns, pThisCC, pThisCC->pSinkOut, PDMAUDIODIR_OUT, dstSrc);
     1221
     1222        AudioMixerSinkDestroy(pThisCC->pSinkOut, pDevIns);
    12201223        pThisCC->pSinkOut = NULL;
    12211224    }
     
    18391842 *
    18401843 * @returns VBox status code.
    1841  * @param   pMixSink            Mixer sink to add driver stream to.
    1842  * @param   pCfg                Stream configuration to use.
    1843  * @param   pDrv                Driver stream to add.
    1844  */
    1845 static int ichac97R3MixerAddDrvStream(PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv)
     1844 * @param   pDevIns     The device instance.
     1845 * @param   pMixSink    Mixer sink to add driver stream to.
     1846 * @param   pCfg        Stream configuration to use.
     1847 * @param   pDrv        Driver stream to add.
     1848 */
     1849static int ichac97R3MixerAddDrvStream(PPDMDEVINS pDevIns, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PAC97DRIVER pDrv)
    18461850{
    18471851    AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
     
    18671871
    18681872        PAUDMIXSTREAM pMixStrm;
    1869         rc = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, pStreamCfg, 0 /* fFlags */, &pMixStrm);
     1873        rc = AudioMixerSinkCreateStream(pMixSink, pDrv->pConnector, pStreamCfg, 0 /* fFlags */, pDevIns, &pMixStrm);
    18701874        LogFlowFunc(("LUN#%RU8: Created stream \"%s\" for sink, rc=%Rrc\n", pDrv->uLUN, pStreamCfg->szName, rc));
    18711875        if (RT_SUCCESS(rc))
     
    19131917             * STAM when 48000Hz is configured right afterwards. */
    19141918            if (RT_FAILURE(rc))
    1915                 AudioMixerStreamDestroy(pMixStrm);
     1919                AudioMixerStreamDestroy(pMixStrm, pDevIns);
    19161920        }
    19171921
     
    19321936 *
    19331937 * @returns VBox status code.
    1934  * @param   pThisCC             The ring-3 AC'97 state.
    1935  * @param   pMixSink            Mixer sink to add stream to.
    1936  * @param   pCfg                Stream configuration to use.
    1937  */
    1938 static int ichac97R3MixerAddDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
     1938 * @param   pDevIns     The device instance.
     1939 * @param   pThisCC     The ring-3 AC'97 state.
     1940 * @param   pMixSink    Mixer sink to add stream to.
     1941 * @param   pCfg        Stream configuration to use.
     1942 */
     1943static int ichac97R3MixerAddDrvStreams(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg)
    19391944{
    19401945    AssertPtrReturn(pMixSink, VERR_INVALID_POINTER);
     
    19501955    RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
    19511956    {
    1952         int rc2 = ichac97R3MixerAddDrvStream(pMixSink, pCfg, pDrv);
     1957        int rc2 = ichac97R3MixerAddDrvStream(pDevIns, pMixSink, pCfg, pDrv);
    19531958        if (RT_FAILURE(rc2))
    19541959            LogFunc(("Attaching stream failed with %Rrc\n", rc2));
     
    19661971 *
    19671972 * @returns VBox status code.
     1973 * @param   pDevIns     The device instance.
    19681974 * @param   pThisCC     The ring-3 AC'97 device state.
    19691975 * @param   pDrv        The AC'97 driver to add.
    19701976 */
    1971 static int ichac97R3MixerAddDrv(PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
     1977static int ichac97R3MixerAddDrv(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
    19721978{
    19731979    int rc = VINF_SUCCESS;
    19741980
    19751981    if (AudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg))
    1976         rc = ichac97R3MixerAddDrvStream(pThisCC->pSinkLineIn, &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg, pDrv);
     1982        rc = ichac97R3MixerAddDrvStream(pDevIns, pThisCC->pSinkLineIn,
     1983                                        &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX].State.Cfg, pDrv);
    19771984
    19781985    if (AudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg))
    19791986    {
    1980         int rc2 = ichac97R3MixerAddDrvStream(pThisCC->pSinkOut, &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg, pDrv);
     1987        int rc2 = ichac97R3MixerAddDrvStream(pDevIns, pThisCC->pSinkOut,
     1988                                             &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX].State.Cfg, pDrv);
    19811989        if (RT_SUCCESS(rc))
    19821990            rc = rc2;
     
    19851993    if (AudioHlpStreamCfgIsValid(&pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg))
    19861994    {
    1987         int rc2 = ichac97R3MixerAddDrvStream(pThisCC->pSinkMicIn, &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg, pDrv);
     1995        int rc2 = ichac97R3MixerAddDrvStream(pDevIns, pThisCC->pSinkMicIn,
     1996                                             &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX].State.Cfg, pDrv);
    19881997        if (RT_SUCCESS(rc))
    19891998            rc = rc2;
     
    19972006 * associated streams.
    19982007 *
    1999  * @param pThisCC               The ring-3 AC'97 device state.
    2000  * @param pDrv                  AC'97 driver to remove.
    2001  */
    2002 static void ichac97R3MixerRemoveDrv(PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
     2008 * @param   pDevIns     The device instance.
     2009 * @param   pThisCC     The ring-3 AC'97 device state.
     2010 * @param   pDrv        AC'97 driver to remove.
     2011 */
     2012static void ichac97R3MixerRemoveDrv(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAC97DRIVER pDrv)
    20032013{
    20042014    if (pDrv->MicIn.pMixStrm)
     
    20082018
    20092019        AudioMixerSinkRemoveStream(pThisCC->pSinkMicIn,  pDrv->MicIn.pMixStrm);
    2010         AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm);
     2020        AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm, pDevIns);
    20112021        pDrv->MicIn.pMixStrm = NULL;
    20122022    }
     
    20182028
    20192029        AudioMixerSinkRemoveStream(pThisCC->pSinkLineIn, pDrv->LineIn.pMixStrm);
    2020         AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm);
     2030        AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm, pDevIns);
    20212031        pDrv->LineIn.pMixStrm = NULL;
    20222032    }
     
    20252035    {
    20262036        AudioMixerSinkRemoveStream(pThisCC->pSinkOut,    pDrv->Out.pMixStrm);
    2027         AudioMixerStreamDestroy(pDrv->Out.pMixStrm);
     2037        AudioMixerStreamDestroy(pDrv->Out.pMixStrm, pDevIns);
    20282038        pDrv->Out.pMixStrm = NULL;
    20292039    }
     
    20352045 * Removes a driver stream from a specific mixer sink.
    20362046 *
    2037  * @param   pMixSink            Mixer sink to remove audio streams from.
    2038  * @param   enmDir              Stream direction to remove.
    2039  * @param   dstSrc              Stream destination / source to remove.
    2040  * @param   pDrv                Driver stream to remove.
    2041  */
    2042 static void ichac97R3MixerRemoveDrvStream(PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc, PAC97DRIVER pDrv)
     2047 * @param   pDevIns     The device instance.
     2048 * @param   pMixSink    Mixer sink to remove audio streams from.
     2049 * @param   enmDir      Stream direction to remove.
     2050 * @param   dstSrc      Stream destination / source to remove.
     2051 * @param   pDrv        Driver stream to remove.
     2052 */
     2053static void ichac97R3MixerRemoveDrvStream(PPDMDEVINS pDevIns, PAUDMIXSINK pMixSink, PDMAUDIODIR enmDir,
     2054                                          PDMAUDIODSTSRCUNION dstSrc, PAC97DRIVER pDrv)
    20432055{
    20442056    PAC97DRIVERSTREAM pDrvStream = ichac97R3MixerGetDrvStream(pDrv, enmDir, dstSrc);
     
    20492061            AudioMixerSinkRemoveStream(pMixSink, pDrvStream->pMixStrm);
    20502062
    2051             AudioMixerStreamDestroy(pDrvStream->pMixStrm);
     2063            AudioMixerStreamDestroy(pDrvStream->pMixStrm, pDevIns);
    20522064            pDrvStream->pMixStrm = NULL;
    20532065        }
     
    20582070 * Removes all driver streams from a specific mixer sink.
    20592071 *
    2060  * @param   pThisCC             The ring-3 AC'97 state.
    2061  * @param   pMixSink            Mixer sink to remove audio streams from.
    2062  * @param   enmDir              Stream direction to remove.
    2063  * @param   dstSrc              Stream destination / source to remove.
    2064  */
    2065 static void ichac97R3MixerRemoveDrvStreams(PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink,
     2072 * @param   pDevIns     The device instance.
     2073 * @param   pThisCC     The ring-3 AC'97 state.
     2074 * @param   pMixSink    Mixer sink to remove audio streams from.
     2075 * @param   enmDir      Stream direction to remove.
     2076 * @param   dstSrc      Stream destination / source to remove.
     2077 */
     2078static void ichac97R3MixerRemoveDrvStreams(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAUDMIXSINK pMixSink,
    20662079                                           PDMAUDIODIR enmDir, PDMAUDIODSTSRCUNION dstSrc)
    20672080{
     
    20712084    RTListForEach(&pThisCC->lstDrv, pDrv, AC97DRIVER, Node)
    20722085    {
    2073         ichac97R3MixerRemoveDrvStream(pMixSink, enmDir, dstSrc, pDrv);
     2086        ichac97R3MixerRemoveDrvStream(pDevIns, pMixSink, enmDir, dstSrc, pDrv);
    20742087    }
    20752088}
     
    21282141 *
    21292142 * @returns VBox status code.
    2130  * @param   pThis               The shared AC'97 device state (shared).
    2131  * @param   pThisCC             The shared AC'97 device state (ring-3).
    2132  * @param   pStream             The AC'97 stream to open (shared).
    2133  * @param   pStreamCC           The AC'97 stream to open (ring-3).
    2134  * @param   fForce              Whether to force re-opening the stream or not.
    2135  *                              Otherwise re-opening only will happen if the PCM properties have changed.
    2136  */
    2137 static int ichac97R3StreamOpen(PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce)
     2143 * @param   pDevIns     The device instance.
     2144 * @param   pThis       The shared AC'97 device state (shared).
     2145 * @param   pThisCC     The shared AC'97 device state (ring-3).
     2146 * @param   pStream     The AC'97 stream to open (shared).
     2147 * @param   pStreamCC   The AC'97 stream to open (ring-3).
     2148 * @param   fForce      Whether to force re-opening the stream or not.
     2149 *                      Otherwise re-opening only will happen if the PCM properties have changed.
     2150 */
     2151static int ichac97R3StreamOpen(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC, PAC97STREAM pStream,
     2152                               PAC97STREAMR3 pStreamCC, bool fForce)
    21382153{
    21392154    int                 rc = VINF_SUCCESS;
     
    22302245                if (RT_SUCCESS(rc))
    22312246                {
    2232                     ichac97R3MixerRemoveDrvStreams(pThisCC, pMixSink, Cfg.enmDir, Cfg.u);
    2233 
    2234                     rc = ichac97R3MixerAddDrvStreams(pThisCC, pMixSink, &Cfg);
     2247                    ichac97R3MixerRemoveDrvStreams(pDevIns, pThisCC, pMixSink, Cfg.enmDir, Cfg.u);
     2248
     2249                    rc = ichac97R3MixerAddDrvStreams(pDevIns, pThisCC, pMixSink, &Cfg);
    22352250                    if (RT_SUCCESS(rc))
    22362251                        rc = PDMAudioStrmCfgCopy(&pStreamCC->State.Cfg, &Cfg);
     
    22642279 *
    22652280 * @returns VBox status code.
    2266  * @param   pThis               The shared AC'97 device state.
    2267  * @param   pThisCC             The ring-3 AC'97 device state.
    2268  * @param   pStream             The AC'97 stream to re-open (shared).
    2269  * @param   pStreamCC           The AC'97 stream to re-open (ring-3).
    2270  * @param   fForce              Whether to force re-opening the stream or not.
    2271  *                              Otherwise re-opening only will happen if the PCM properties have changed.
    2272  */
    2273 static int ichac97R3StreamReOpen(PAC97STATE pThis, PAC97STATER3 pThisCC,
     2281 * @param   pDevIns     The device instance.
     2282 * @param   pThis       The shared AC'97 device state.
     2283 * @param   pThisCC     The ring-3 AC'97 device state.
     2284 * @param   pStream     The AC'97 stream to re-open (shared).
     2285 * @param   pStreamCC   The AC'97 stream to re-open (ring-3).
     2286 * @param   fForce      Whether to force re-opening the stream or not.
     2287 *                      Otherwise re-opening only will happen if the PCM properties have changed.
     2288 */
     2289static int ichac97R3StreamReOpen(PPDMDEVINS pDevIns, PAC97STATE pThis, PAC97STATER3 pThisCC,
    22742290                                 PAC97STREAM pStream, PAC97STREAMR3 pStreamCC, bool fForce)
    22752291{
     
    22812297    int rc = ichac97R3StreamClose(pStream);
    22822298    if (RT_SUCCESS(rc))
    2283         rc = ichac97R3StreamOpen(pThis, pThisCC, pStream, pStreamCC, fForce);
     2299        rc = ichac97R3StreamOpen(pDevIns, pThis, pThisCC, pStream, pStreamCC, fForce);
    22842300
    22852301    return rc;
     
    32443260                            Assert((pRegs->cr & AC97_CR_RPBM) == 0);
    32453261
    3246                             ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
     3262                            ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
    32473263                            ichac97R3StreamReset(pThis, pStream, pStreamCC);
    32483264
     
    32573273                                Log3Func(("[SD%RU8] Disable\n", pStream->u8SD));
    32583274
    3259                                 ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
     3275                                ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, false /* fEnable */);
    32603276
    32613277                                pRegs->sr |= AC97_SR_DCH;
     
    32753291                                ichac97R3BDLEDumpAll(pDevIns, pStream->Regs.bdbar, pStream->Regs.lvi + 1);
    32763292# endif
    3277                                 ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, true /* fEnable */);
     3293                                ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, true /* fEnable */);
    32783294
    32793295                                /* Arm the timer for this stream. */
     
    35573573                    {
    35583574                        ichac97MixerSet(pThis, AC97_PCM_Front_DAC_Rate, 0xbb80); /* Set default (48000 Hz). */
    3559                         ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
     3575                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
    35603576                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
    35613577
    35623578                        ichac97MixerSet(pThis, AC97_PCM_LR_ADC_Rate, 0xbb80); /* Set default (48000 Hz). */
    3563                         ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
     3579                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
    35643580                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
    35653581                    }
     
    35733589                    {
    35743590                        ichac97MixerSet(pThis, AC97_MIC_ADC_Rate, 0xbb80); /* Set default (48000 Hz). */
    3575                         ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
     3591                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
    35763592                                              &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
    35773593                    }
     
    35913607                        LogRel2(("AC97: Setting front DAC rate to 0x%x\n", u32));
    35923608                        ichac97MixerSet(pThis, offPort, u32);
    3593                         ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
     3609                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PO_INDEX],
    35943610                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PO_INDEX], true /* fForce */);
    35953611                    }
     
    36063622                        LogRel2(("AC97: Setting microphone ADC rate to 0x%x\n", u32));
    36073623                        ichac97MixerSet(pThis, offPort, u32);
    3608                         ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
     3624                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_MC_INDEX],
    36093625                                              &pThisCC->aStreams[AC97SOUNDSOURCE_MC_INDEX], true /* fForce */);
    36103626                    }
     
    36213637                        LogRel2(("AC97: Setting line-in ADC rate to 0x%x\n", u32));
    36223638                        ichac97MixerSet(pThis, offPort, u32);
    3623                         ichac97R3StreamReOpen(pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
     3639                        ichac97R3StreamReOpen(pDevIns, pThis, pThisCC, &pThis->aStreams[AC97SOUNDSOURCE_PI_INDEX],
    36243640                                              &pThisCC->aStreams[AC97SOUNDSOURCE_PI_INDEX], true /* fForce */);
    36253641                    }
     
    38013817        const PAC97STREAMR3 pStreamCC = &pThisCC->aStreams[i];
    38023818
    3803         rc2 = ichac97R3StreamEnable(pThis, pThisCC, pStream, pStreamCC, fEnable);
     3819        rc2 = ichac97R3StreamEnable(pDevIns, pThis, pThisCC, pStream, pStreamCC, fEnable);
    38043820        AssertRC(rc2);
    38053821        if (   fEnable
     
    38513867    /* Note: Involves mixer stream / sink destruction, so also do this here
    38523868     *       instead of in ichac97R3Destruct(). */
    3853     ichac97R3StreamsDestroy(pThis, pThisCC);
     3869    ichac97R3StreamsDestroy(pDevIns, pThis, pThisCC);
    38543870
    38553871    /*
     
    38603876    if (pThisCC->pMixer)
    38613877    {
    3862         AudioMixerDestroy(pThisCC->pMixer);
     3878        AudioMixerDestroy(pThisCC->pMixer, pDevIns);
    38633879        pThisCC->pMixer = NULL;
    38643880    }
     
    38913907    for (unsigned i = 0; i < AC97_MAX_STREAMS; i++)
    38923908    {
    3893         ichac97R3StreamEnable(pThis, pThisCC, &pThis->aStreams[i], &pThisCC->aStreams[i], false /* fEnable */);
     3909        ichac97R3StreamEnable(pDevIns, pThis, pThisCC, &pThis->aStreams[i], &pThisCC->aStreams[i], false /* fEnable */);
    38943910        ichac97R3StreamReset(pThis, &pThis->aStreams[i], &pThisCC->aStreams[i]);
    38953911    }
     
    39884004 *
    39894005 * @returns VBox status code.
     4006 * @param   pDevIns     The device instance.
    39904007 * @param   pThisCC     The ring-3 AC'97 device state.
    39914008 * @param   pDrv        Driver to detach from device.
    39924009 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    39934010 */
    3994 static int ichac97R3DetachInternal(PAC97STATER3 pThisCC, PAC97DRIVER pDrv, uint32_t fFlags)
     4011static int ichac97R3DetachInternal(PPDMDEVINS pDevIns, PAC97STATER3 pThisCC, PAC97DRIVER pDrv, uint32_t fFlags)
    39954012{
    39964013    RT_NOREF(fFlags);
     
    39984015    /* First, remove the driver from our list and destory it's associated streams.
    39994016     * This also will un-set the driver as a recording source (if associated). */
    4000     ichac97R3MixerRemoveDrv(pThisCC, pDrv);
     4017    ichac97R3MixerRemoveDrv(pDevIns, pThisCC, pDrv);
    40014018
    40024019    /* Next, search backwards for a capable (attached) driver which now will be the
     
    40544071    int rc2 = ichac97R3AttachInternal(pDevIns, pThisCC, iLUN, fFlags, &pDrv);
    40554072    if (RT_SUCCESS(rc2))
    4056         rc2 = ichac97R3MixerAddDrv(pThisCC, pDrv);
     4073        rc2 = ichac97R3MixerAddDrv(pDevIns, pThisCC, pDrv);
    40574074
    40584075    if (RT_FAILURE(rc2))
     
    40814098        if (pDrv->uLUN == iLUN)
    40824099        {
    4083             int rc2 = ichac97R3DetachInternal(pThisCC, pDrv, fFlags);
     4100            int rc2 = ichac97R3DetachInternal(pDevIns, pThisCC, pDrv, fFlags);
    40844101            if (RT_SUCCESS(rc2))
    40854102            {
     
    43124329    AssertRCReturn(rc, rc);
    43134330
    4314     rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThisCC->pSinkLineIn);
     4331    rc = AudioMixerCreateSink(pThisCC->pMixer, "Line In",
     4332                              AUDMIXSINKDIR_INPUT, pDevIns, &pThisCC->pSinkLineIn);
    43154333    AssertRCReturn(rc, rc);
    4316     rc = AudioMixerCreateSink(pThisCC->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThisCC->pSinkMicIn);
     4334    rc = AudioMixerCreateSink(pThisCC->pMixer, "Microphone In",
     4335                              AUDMIXSINKDIR_INPUT, pDevIns, &pThisCC->pSinkMicIn);
    43174336    AssertRCReturn(rc, rc);
    4318     rc = AudioMixerCreateSink(pThisCC->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThisCC->pSinkOut);
     4337    rc = AudioMixerCreateSink(pThisCC->pMixer, "PCM Output",
     4338                              AUDMIXSINKDIR_OUTPUT, pDevIns, &pThisCC->pSinkOut);
    43194339    AssertRCReturn(rc, rc);
    43204340
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r88300 r88307  
    14281428            pStream->Out.cbBackendMaxWritable = cbWritable;
    14291429    }
     1430    pStream->Out.Stats.cbBackendWritableBefore = cbWritable;
    14301431
    14311432    /*
     
    14581459
    14591460        pStream->tsLastPlayedCapturedNs = RTTimeNanoTS();
     1461        pStream->Out.Stats.cbBackendWritableAfter = pThis->pHostDrvAudio->pfnStreamGetWritable(pThis->pHostDrvAudio,
     1462                                                                                               pStream->pvBackend);
    14601463    }
    14611464    else
     
    26462649     * Register statistics.
    26472650     */
     2651    PPDMDRVINS const pDrvIns = pThis->pDrvIns;
     2652    /** @todo expose config and more. */
     2653    if (pCfgGuest->enmDir == PDMAUDIODIR_OUT)
     2654    {
     2655        PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Out.Stats.cbBackendWritableBefore, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
     2656                               "Host side: Free space in backend buffer before play",  "%s/HostBackedBufFreeBefore", pStream->szName);
     2657        PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Out.Stats.cbBackendWritableAfter, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
     2658                               "Host side: Free space in backend buffer after play",   "%s/HostBackedBufFreeAfter", pStream->szName);
     2659    }
     2660    PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Host.Cfg.Backend.cFramesBufferSize, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
     2661                           "Host side: The size of the backend buffer (in frames)", "%s/HostBackedBufSize", pStream->szName);
     2662    PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Host.MixBuf.cFrames, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
     2663                           "Host side: The size of the mixer buffer (in frames)",   "%s/HostMixBufSize", pStream->szName);
     2664    PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Host.MixBuf.cUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
     2665                           "Host side: Number of frames in the mixer buffer",       "%s/HostMixBufUsed", pStream->szName);
     2666    PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Guest.MixBuf.cFrames, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
     2667                           "Guest side: The size of the mixer buffer (in frames)",  "%s/GuestMixBufSize", pStream->szName);
     2668    PDMDrvHlpSTAMRegisterF(pDrvIns, &pStream->Guest.MixBuf.cUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE,
     2669                           "Guest side: Number of frames in the mixer buffer",      "%s/GuestMixBufUsed", pStream->szName);
     2670
    26482671#ifdef VBOX_WITH_STATISTICS
    26492672    char szStatName[255];
     
    26512674    {
    26522675        RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalFramesCaptured", pStream->szName);
    2653         PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->In.Stats.TotalFramesCaptured,
     2676        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->In.Stats.TotalFramesCaptured,
    26542677                                  szStatName, STAMUNIT_COUNT, "Total frames played.");
    26552678        RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalTimesCaptured", pStream->szName);
    2656         PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->In.Stats.TotalTimesCaptured,
     2679        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->In.Stats.TotalTimesCaptured,
    26572680                                  szStatName, STAMUNIT_COUNT, "Total number of playbacks.");
    26582681        RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalFramesRead", pStream->szName);
    2659         PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->In.Stats.TotalFramesRead,
     2682        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->In.Stats.TotalFramesRead,
    26602683                                  szStatName, STAMUNIT_COUNT, "Total frames read.");
    26612684        RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalTimesRead", pStream->szName);
    2662         PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->In.Stats.TotalTimesRead,
     2685        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->In.Stats.TotalTimesRead,
    26632686                                  szStatName, STAMUNIT_COUNT, "Total number of reads.");
    26642687    }
     
    26672690        Assert(pCfgGuest->enmDir == PDMAUDIODIR_OUT);
    26682691        RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalFramesPlayed", pStream->szName);
    2669         PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->Out.Stats.TotalFramesPlayed,
     2692        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->Out.Stats.TotalFramesPlayed,
    26702693                                  szStatName, STAMUNIT_COUNT, "Total frames played.");
    26712694
    26722695        RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalTimesPlayed", pStream->szName);
    2673         PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->Out.Stats.TotalTimesPlayed,
     2696        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->Out.Stats.TotalTimesPlayed,
    26742697                                  szStatName, STAMUNIT_COUNT, "Total number of playbacks.");
    26752698        RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalFramesWritten", pStream->szName);
    2676         PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->Out.Stats.TotalFramesWritten,
     2699        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->Out.Stats.TotalFramesWritten,
    26772700                                  szStatName, STAMUNIT_COUNT, "Total frames written.");
    26782701
    26792702        RTStrPrintf(szStatName, sizeof(szStatName), "Guest/%s/TotalTimesWritten", pStream->szName);
    2680         PDMDrvHlpSTAMRegCounterEx(pThis->pDrvIns, &pStream->Out.Stats.TotalTimesWritten,
     2703        PDMDrvHlpSTAMRegCounterEx(pDrvIns, &pStream->Out.Stats.TotalTimesWritten,
    26812704                                  szStatName, STAMUNIT_COUNT, "Total number of writes.");
    26822705    }
     
    32033226    }
    32043227
     3228    PPDMDRVINS const pDrvIns = pThis->pDrvIns;
    32053229    if (pStream->enmDir == PDMAUDIODIR_IN)
    32063230    {
    32073231#ifdef VBOX_WITH_STATISTICS
    3208         PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->In.Stats.TotalFramesCaptured);
    3209         PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->In.Stats.TotalTimesCaptured);
    3210         PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->In.Stats.TotalFramesRead);
    3211         PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->In.Stats.TotalTimesRead);
     3232        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->In.Stats.TotalFramesCaptured);
     3233        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->In.Stats.TotalTimesCaptured);
     3234        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->In.Stats.TotalFramesRead);
     3235        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->In.Stats.TotalTimesRead);
    32123236#endif
    32133237        if (pThis->In.Cfg.Dbg.fEnabled)
     
    32243248        Assert(pStream->enmDir == PDMAUDIODIR_OUT);
    32253249#ifdef VBOX_WITH_STATISTICS
    3226         PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->Out.Stats.TotalFramesPlayed);
    3227         PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->Out.Stats.TotalTimesPlayed);
    3228         PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->Out.Stats.TotalFramesWritten);
    3229         PDMDrvHlpSTAMDeregister(pThis->pDrvIns, &pStream->Out.Stats.TotalTimesWritten);
     3250        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.TotalFramesPlayed);
     3251        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.TotalTimesPlayed);
     3252        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.TotalFramesWritten);
     3253        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.TotalTimesWritten);
    32303254#endif
    32313255        if (pThis->Out.Cfg.Dbg.fEnabled)
     
    32373261            pStream->Out.Dbg.pFileStreamWrite = NULL;
    32383262        }
    3239     }
     3263        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.cbBackendWritableAfter);
     3264        PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Out.Stats.cbBackendWritableBefore);
     3265    }
     3266    PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Host.Cfg.Backend.cFramesBufferSize);
     3267    PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Host.MixBuf.cFrames);
     3268    PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Host.MixBuf.cUsed);
     3269    PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Guest.MixBuf.cFrames);
     3270    PDMDrvHlpSTAMDeregister(pDrvIns, &pStream->Guest.MixBuf.cUsed);
    32403271
    32413272    LogFlowFunc(("Returning %Rrc\n", rc));
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