VirtualBox

Changeset 61166 in vbox for trunk


Ignore:
Timestamp:
May 24, 2016 3:26:06 PM (9 years ago)
Author:
vboxsync
Message:

Audio: Implemented ability to specify two different audio formats via PDMIAUDIOCONNECTOR::CreateStream, renamed AudioMixerCreateStream() to AudioMixerSinkCreateStream().

Location:
trunk
Files:
9 edited

Legend:

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

    r61157 r61166  
    637637     * @returns VBox status code.
    638638     * @param   pInterface           Pointer to the interface structure containing the called function pointer.
    639      * @param   pszName              Friendly name of this input stream.
    640      * @param   ppGstStrmIn          Pointer where to return the guest guest input stream on success.
    641      */
    642     DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfg, PPDMAUDIOSTREAM *ppStream));
     639     * @param   pCfgHost             Stream configuration for host side.
     640     * @param   pCfgGuest            Stream configuration for guest side.
     641     * @param   ppStream             Pointer where to return the created audio stream on success.
     642     */
     643    DECLR3CALLBACKMEMBER(int, pfnStreamCreate, (PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfgHost, PPDMAUDIOSTREAMCFG pCfgGuest, PPDMAUDIOSTREAM *ppStream));
    643644
    644645    /**
     
    694695
    695696/** PDMIAUDIOCONNECTOR interface ID. */
    696 #define PDMIAUDIOCONNECTOR_IID                  "45620608-5014-4322-8593-A15ACFDA2B12"
     697#define PDMIAUDIOCONNECTOR_IID                  "9CDE2581-41B1-838E-24A5-448B2D0C822E"
    697698
    698699
  • trunk/src/VBox/Devices/Audio/AudioMixer.cpp

    r61157 r61166  
    105105}
    106106
    107 int AudioMixerCreateStream(PAUDIOMIXER pMixer,
    108                            PPDMIAUDIOCONNECTOR pConn, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream)
    109 {
    110     AssertPtrReturn(pMixer, VERR_INVALID_POINTER);
    111     AssertPtrReturn(pConn,  VERR_INVALID_POINTER);
    112     AssertPtrReturn(pCfg,   VERR_INVALID_POINTER);
    113     /** @todo Validate fFlags. */
    114     /* ppStream is optional. */
    115 
    116     PAUDMIXSTREAM pMixStream = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM));
    117     if (!pMixStream)
    118         return VERR_NO_MEMORY;
    119 
    120     pMixStream->pszName = RTStrDup(pCfg->szName);
    121     if (!pMixStream->pszName)
    122     {
    123         RTMemFree(pMixStream);
    124         return VERR_NO_MEMORY;
    125     }
    126 
    127     LogFlowFunc(("[%s]: fFlags=0x%x (enmDir=%ld, %s, %RU8 channels, %RU32Hz)\n",
    128                  pMixer->pszName, fFlags, pCfg->enmDir, DrvAudioAudFmtToStr(pCfg->enmFormat), pCfg->cChannels, pCfg->uHz));
    129 
    130     PPDMAUDIOSTREAM pStream;
    131     int rc = pConn->pfnStreamCreate(pConn, pCfg, &pStream);
    132     if (RT_SUCCESS(rc))
    133     {
    134         /* Save the audio stream pointer to this mixing stream. */
    135         pMixStream->pStream = pStream;
    136 
    137         /* Increase the stream's reference count to let others know
    138          * we're reyling on it to be around now. */
    139         pConn->pfnStreamAddRef(pConn, pStream);
    140     }
    141 
    142     if (RT_SUCCESS(rc))
    143     {
    144         pMixStream->fFlags = fFlags;
    145         pMixStream->pConn  = pConn;
    146 
    147         if (ppStream)
    148             *ppStream = pMixStream;
    149     }
    150     else if (pMixStream)
    151     {
    152         RTStrFree(pMixStream->pszName);
    153         pMixStream->pszName = NULL;
    154 
    155         RTMemFree(pMixStream);
    156         pMixStream = NULL;
    157     }
    158 
    159     return rc;
    160 }
    161 
    162107int AudioMixerCreate(const char *pszName, uint32_t uFlags, PAUDIOMIXER *ppMixer)
    163108{
     
    417362
    418363    LogFlowFunc(("[%s]: cStreams=%RU8, rc=%Rrc\n", pSink->pszName, pSink->cStreams, rc));
     364    return rc;
     365}
     366
     367int AudioMixerSinkCreateStream(PAUDMIXSINK pSink,
     368                               PPDMIAUDIOCONNECTOR pConn, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream)
     369{
     370    AssertPtrReturn(pSink,  VERR_INVALID_POINTER);
     371    AssertPtrReturn(pConn,  VERR_INVALID_POINTER);
     372    AssertPtrReturn(pCfg,   VERR_INVALID_POINTER);
     373    /** @todo Validate fFlags. */
     374    /* ppStream is optional. */
     375
     376    PAUDMIXSTREAM pMixStream = (PAUDMIXSTREAM)RTMemAllocZ(sizeof(AUDMIXSTREAM));
     377    if (!pMixStream)
     378        return VERR_NO_MEMORY;
     379
     380    pMixStream->pszName = RTStrDup(pCfg->szName);
     381    if (!pMixStream->pszName)
     382    {
     383        RTMemFree(pMixStream);
     384        return VERR_NO_MEMORY;
     385    }
     386
     387    LogFlowFunc(("[%s]: fFlags=0x%x (enmDir=%ld, %s, %RU8 channels, %RU32Hz)\n",
     388                 pSink->pszName, fFlags, pCfg->enmDir, DrvAudioAudFmtToStr(pCfg->enmFormat), pCfg->cChannels, pCfg->uHz));
     389
     390    PDMAUDIOSTREAMCFG CfgSink;
     391    int rc = DrvAudioPCMPropsToStreamCfg(&pSink->PCMProps, &CfgSink);
     392    AssertRCReturn(rc, rc);
     393
     394    /* Always use the sink's PCM audio format as the host side when creating a stream for it. */
     395    PPDMAUDIOSTREAM pStream;
     396    rc = pConn->pfnStreamCreate(pConn, &CfgSink, pCfg, &pStream);
     397    if (RT_SUCCESS(rc))
     398    {
     399        /* Save the audio stream pointer to this mixing stream. */
     400        pMixStream->pStream = pStream;
     401
     402        /* Increase the stream's reference count to let others know
     403         * we're reyling on it to be around now. */
     404        pConn->pfnStreamAddRef(pConn, pStream);
     405    }
     406
     407    if (RT_SUCCESS(rc))
     408    {
     409        pMixStream->fFlags = fFlags;
     410        pMixStream->pConn  = pConn;
     411
     412        if (ppStream)
     413            *ppStream = pMixStream;
     414    }
     415    else if (pMixStream)
     416    {
     417        RTStrFree(pMixStream->pszName);
     418        pMixStream->pszName = NULL;
     419
     420        RTMemFree(pMixStream);
     421        pMixStream = NULL;
     422    }
     423
    419424    return rc;
    420425}
  • trunk/src/VBox/Devices/Audio/AudioMixer.h

    r61157 r61166  
    156156int AudioMixerCreate(const char *pszName, uint32_t uFlags, PAUDIOMIXER *ppMixer);
    157157int AudioMixerCreateSink(PAUDIOMIXER pMixer, const char *pszName, AUDMIXSINKDIR enmDir, PAUDMIXSINK *ppSink);
    158 int AudioMixerCreateStream(PAUDIOMIXER pMixer, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream);
    159158void AudioMixerDestroy(PAUDIOMIXER pMixer);
    160159int AudioMixerGetDeviceFormat(PAUDIOMIXER pMixer, PPDMAUDIOSTREAMCFG pCfg);
     
    166165
    167166int AudioMixerSinkAddStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream);
     167int AudioMixerSinkCreateStream(PAUDMIXSINK pSink, PPDMIAUDIOCONNECTOR pConnector, PPDMAUDIOSTREAMCFG pCfg, uint32_t fFlags, PAUDMIXSTREAM *ppStream);
    168168int AudioMixerSinkCtl(PAUDMIXSINK pSink, AUDMIXSINKCMD enmCmd);
    169169void AudioMixerSinkDestroy(PAUDMIXSINK pSink);
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r61157 r61166  
    760760        pStream->pMixStrm = NULL;
    761761
    762         int rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */ , &pStream->pMixStrm);
     762        int rc2 = AudioMixerSinkCreateStream(pSink, pDrv->pConnector, pCfg, 0 /* fFlags */ , &pStream->pMixStrm);
    763763        if (RT_SUCCESS(rc2))
    764764        {
     
    805805        pDrv->Out.pMixStrm = NULL;
    806806
    807         int rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);
     807        int rc2 = AudioMixerSinkCreateStream(pThis->pSinkOutput, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);
    808808        if (RT_SUCCESS(rc2))
    809809        {
  • trunk/src/VBox/Devices/Audio/DevIchHda.cpp

    r61158 r61166  
    37753775
    37763776            PAUDMIXSTREAM pMixStrm;
    3777             rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */, &pMixStrm);
     3777            rc2 = AudioMixerSinkCreateStream(pSink->pMixSink, pDrv->pConnector, pCfg, 0 /* fFlags */, &pMixStrm);
    37783778            if (RT_SUCCESS(rc2))
    37793779            {
  • trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r61157 r61166  
    20542054        pDrv->Out.pMixStrm = NULL;
    20552055
    2056         int rc2 = AudioMixerCreateStream(pThis->pMixer, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);
     2056        int rc2 = AudioMixerSinkCreateStream(pThis->pSinkOutput, pDrv->pConnector, pCfg, 0 /* fFlags */, &pDrv->Out.pMixStrm);
    20572057        if (RT_SUCCESS(rc2))
    20582058        {
  • trunk/src/VBox/Devices/Audio/DrvAudio.cpp

    r61161 r61166  
    14551455#endif
    14561456
    1457 static DECLCALLBACK(int) drvAudioStreamCreate(PPDMIAUDIOCONNECTOR pInterface, PPDMAUDIOSTREAMCFG pCfg,
     1457static DECLCALLBACK(int) drvAudioStreamCreate(PPDMIAUDIOCONNECTOR pInterface,
     1458                                              PPDMAUDIOSTREAMCFG pCfgHost, PPDMAUDIOSTREAMCFG pCfgGuest,
    14581459                                              PPDMAUDIOSTREAM *ppStream)
    14591460{
    14601461    AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
    1461     AssertPtrReturn(pCfg,       VERR_INVALID_POINTER);
     1462    AssertPtrReturn(pCfgHost,   VERR_INVALID_POINTER);
     1463    AssertPtrReturn(pCfgGuest,  VERR_INVALID_POINTER);
    14621464    AssertPtrReturn(ppStream,   VERR_INVALID_POINTER);
    14631465
     
    14681470        return rc;
    14691471
    1470     LogFlowFunc(("szName=%s\n", pCfg->szName));
     1472    LogFlowFunc(("Host=%s, Guest=%s\n", pCfgHost->szName, pCfgGuest->szName));
    14711473#ifdef DEBUG
    1472     DrvAudioStreamCfgPrint(pCfg);
     1474    DrvAudioStreamCfgPrint(pCfgHost);
     1475    DrvAudioStreamCfgPrint(pCfgGuest);
    14731476#endif
    14741477
     
    14861489    do
    14871490    {
    1488         if (!DrvAudioStreamCfgIsValid(pCfg))
     1491        if (   !DrvAudioStreamCfgIsValid(pCfgHost)
     1492            || !DrvAudioStreamCfgIsValid(pCfgGuest))
     1493        {
     1494            RC_BREAK(VERR_INVALID_PARAMETER);
     1495        }
     1496
     1497        /* Make sure that both configurations actually intend the same thing. */
     1498        if (pCfgHost->enmDir != pCfgGuest->enmDir)
    14891499            RC_BREAK(VERR_INVALID_PARAMETER);
    14901500
     
    14921502         *       which the host backend will need. */
    14931503        size_t cbHstStrm;
    1494         if (pCfg->enmDir == PDMAUDIODIR_IN)
     1504        if (pCfgHost->enmDir == PDMAUDIODIR_IN)
    14951505        {
    14961506            if (!pThis->cStreamsFreeIn)
     
    15421552
    15431553        RTStrPrintf(pHstStrm->szName, RT_ELEMENTS(pHstStrm->szName), "%s (Host)",
    1544                     strlen(pCfg->szName) ? pCfg->szName : "<Untitled>");
     1554                    strlen(pCfgHost->szName) ? pCfgHost->szName : "<Untitled>");
    15451555
    15461556        /* Note: Direction is always from child -> parent. */
    15471557        uint32_t cSamples = 0;
    1548         rc = pThis->pHostDrvAudio->pfnStreamCreate(pThis->pHostDrvAudio, pHstStrm, pCfg, &cSamples);
     1558        rc = pThis->pHostDrvAudio->pfnStreamCreate(pThis->pHostDrvAudio, pHstStrm, pCfgHost, &cSamples);
    15491559        if (RT_FAILURE(rc))
    15501560        {
     
    15541564
    15551565        pHstStrm->enmCtx   = PDMAUDIOSTREAMCTX_HOST;
    1556         pHstStrm->enmDir   = pCfg->enmDir;
     1566        pHstStrm->enmDir   = pCfgHost->enmDir;
    15571567        pHstStrm->fStatus |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
    15581568        pHstStrm->pPair    = pGstStrm;
    15591569
    1560         rc = DrvAudioStreamCfgToProps(pCfg, &pHstStrm->Props);
     1570        rc = DrvAudioStreamCfgToProps(pCfgHost, &pHstStrm->Props);
    15611571        AssertRCBreak(rc);
    15621572
     
    15691579
    15701580        RTStrPrintf(pGstStrm->szName, RT_ELEMENTS(pGstStrm->szName), "%s (Guest)",
    1571                     strlen(pCfg->szName) ? pCfg->szName : "<Untitled>");
    1572 
    1573         rc = DrvAudioStreamCfgToProps(pCfg, &pGstStrm->Props);
     1581                    strlen(pCfgGuest->szName) ? pCfgGuest->szName : "<Untitled>");
     1582
     1583        rc = DrvAudioStreamCfgToProps(pCfgGuest, &pGstStrm->Props);
    15741584        AssertRCBreak(rc);
    15751585
     
    15771587        if (RT_SUCCESS(rc))
    15781588        {
    1579             if (pCfg->enmDir == PDMAUDIODIR_IN)
     1589            if (pCfgGuest->enmDir == PDMAUDIODIR_IN)
    15801590            {
    15811591                rc = AudioMixBufLinkTo(&pHstStrm->MixBuf, &pGstStrm->MixBuf);
     
    15881598
    15891599        pGstStrm->enmCtx   = PDMAUDIOSTREAMCTX_GUEST;
    1590         pGstStrm->enmDir   = pCfg->enmDir;
     1600        pGstStrm->enmDir   = pCfgGuest->enmDir;
    15911601        pGstStrm->fStatus |= PDMAUDIOSTRMSTS_FLAG_INITIALIZED;
    15921602        pGstStrm->pPair    = pHstStrm;
     
    16281638        pHstStrm->cRefs = 1;
    16291639
    1630         if (pCfg->enmDir == PDMAUDIODIR_IN)
     1640        if (pCfgHost->enmDir == PDMAUDIODIR_IN)
    16311641        {
    16321642            Assert(pThis->cStreamsFreeIn);
  • trunk/src/VBox/Devices/Audio/DrvAudio.h

    r61157 r61166  
    111111    ( (PDRVAUDIO)((uintptr_t)pInterface - RT_OFFSETOF(DRVAUDIO, IAudioConnector)) )
    112112
     113
     114bool DrvAudioAudFmtIsSigned(PDMAUDIOFMT enmFmt);
     115uint8_t DrvAudioAudFmtToBits(PDMAUDIOFMT enmFmt);
    113116const char *DrvAudioAudFmtToStr(PDMAUDIOFMT enmFmt);
    114117void DrvAudioClearBuf(PPDMPCMPROPS pPCMInfo, void *pvBuf, size_t cbBuf, uint32_t cSamples);
    115 bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pProps1, PPDMPCMPROPS pProps2);
    116 bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pPCMInfo, PPDMAUDIOSTREAMCFG pCfg);
     118bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pPCMProps1, PPDMPCMPROPS pPCMProps2);
     119bool DrvAudioPCMPropsAreEqual(PPDMPCMPROPS pPCMProps, PPDMAUDIOSTREAMCFG pCfg);
     120int DrvAudioPCMPropsToStreamCfg(PPDMPCMPROPS pPCMProps, PPDMAUDIOSTREAMCFG pCfg);
    117121const char *DrvAudRecSrcToStr(PDMAUDIORECSOURCE enmRecSource);
    118122void DrvAudioStreamCfgPrint(PPDMAUDIOSTREAMCFG pCfg);
  • trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp

    r61157 r61166  
    6161#include "AudioMixBuffer.h"
    6262
     63
     64/**
     65 * Retrieves the matching PDMAUDIOFMT for given bits + signing flag.
     66 *
     67 * @return  IPRT status code.
     68 * @return  PDMAUDIOFMT         Resulting audio format or PDMAUDIOFMT_INVALID if invalid.
     69 * @param   cBits               Bits to retrieve audio format for.
     70 * @param   fSigned             Signed flag for bits to retrieve audio format for.
     71 */
     72PDMAUDIOFMT DrvAudioAudFmtBitsToAudFmt(uint8_t cBits, bool fSigned)
     73{
     74    if (fSigned)
     75    {
     76        switch (cBits)
     77        {
     78            case 8:  return PDMAUDIOFMT_S8;
     79            case 16: return PDMAUDIOFMT_S16;
     80            case 32: return PDMAUDIOFMT_S32;
     81            default: break;
     82        }
     83    }
     84    else
     85    {
     86        switch (cBits)
     87        {
     88            case 8:  return PDMAUDIOFMT_U8;
     89            case 16: return PDMAUDIOFMT_U16;
     90            case 32: return PDMAUDIOFMT_U32;
     91            default: break;
     92        }
     93    }
     94
     95    AssertMsgFailed(("Bogus audio bits %RU8\n", cBits));
     96    return PDMAUDIOFMT_INVALID;
     97}
     98
    6399/**
    64100 * Clears a sample buffer by the given amount of audio samples.
     
    150186    AssertMsgFailed(("Invalid recording source %ld\n", enmRecSrc));
    151187    return "Unknown";
     188}
     189
     190/**
     191 * Returns wether the given audio format has signed bits or not.
     192 *
     193 * @return  IPRT status code.
     194 * @return  bool                @true for signed bits, @false for unsigned.
     195 * @param   enmFmt              Audio format to retrieve value for.
     196 */
     197bool DrvAudioAudFmtIsSigned(PDMAUDIOFMT enmFmt)
     198{
     199    switch (enmFmt)
     200    {
     201        case PDMAUDIOFMT_S8:
     202        case PDMAUDIOFMT_S16:
     203        case PDMAUDIOFMT_S32:
     204            return true;
     205
     206        case PDMAUDIOFMT_U8:
     207        case PDMAUDIOFMT_U16:
     208        case PDMAUDIOFMT_U32:
     209            return false;
     210
     211        default:
     212            break;
     213    }
     214
     215    AssertMsgFailed(("Bogus audio format %ld\n", enmFmt));
     216    return false;
     217}
     218
     219/**
     220 * Returns the bits of a given audio format.
     221 *
     222 * @return  IPRT status code.
     223 * @return  uint8_t             Bits of audio format.
     224 * @param   enmFmt              Audio format to retrieve value for.
     225 */
     226uint8_t DrvAudioAudFmtToBits(PDMAUDIOFMT enmFmt)
     227{
     228    switch (enmFmt)
     229    {
     230        case PDMAUDIOFMT_S8:
     231        case PDMAUDIOFMT_U8:
     232            return 8;
     233
     234        case PDMAUDIOFMT_U16:
     235        case PDMAUDIOFMT_S16:
     236            return 16;
     237
     238        case PDMAUDIOFMT_U32:
     239        case PDMAUDIOFMT_S32:
     240            return 32;
     241
     242        default:
     243            break;
     244    }
     245
     246    AssertMsgFailed(("Bogus audio format %ld\n", enmFmt));
     247    return 0;
    152248}
    153249
     
    253349           && pProps1->cBits       == pProps2->cBits
    254350           && pProps1->fSwapEndian == pProps2->fSwapEndian;
     351}
     352
     353/**
     354 * Converts PCM properties to a audio stream configuration.
     355 *
     356 * @return  IPRT status code.
     357 * @param   pPCMProps           Pointer to PCM properties to convert.
     358 * @param   pCfg                Pointer to audio stream configuration to store result into.
     359 */
     360int DrvAudioPCMPropsToStreamCfg(PPDMPCMPROPS pPCMProps, PPDMAUDIOSTREAMCFG pCfg)
     361{
     362    AssertPtrReturn(pPCMProps, VERR_INVALID_POINTER);
     363    AssertPtrReturn(pCfg,      VERR_INVALID_POINTER);
     364
     365    pCfg->uHz           = pPCMProps->uHz;
     366    pCfg->cChannels     = pPCMProps->cChannels;
     367    pCfg->enmFormat     = DrvAudioAudFmtBitsToAudFmt(pPCMProps->cBits, pPCMProps->fSigned);
     368
     369    /** @todo We assume little endian is the default for now. */
     370    pCfg->enmEndianness = pPCMProps->fSwapEndian == false ? PDMAUDIOENDIANNESS_LITTLE : PDMAUDIOENDIANNESS_BIG;
     371    return VINF_SUCCESS;
    255372}
    256373
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