VirtualBox

Changeset 89421 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jun 1, 2021 8:17:01 AM (4 years ago)
Author:
vboxsync
Message:

DrvHostAudioDSound: Multi channel support. bugref:9890

File:
1 edited

Legend:

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

    r89344 r89421  
    2727#include <mmdeviceapi.h>
    2828#include <functiondiscoverykeys_devpkey.h>
     29#include <iprt/win/mmreg.h> /* WAVEFORMATEXTENSIBLE */
    2930
    3031#include <iprt/alloc.h>
     
    12851286
    12861287/**
    1287  * Converts from PDM stream config to windows WAVEFORMATEX struct.
     1288 * Converts from PDM stream config to windows WAVEFORMATEXTENSIBLE struct.
    12881289 *
    12891290 * @param   pCfg    The PDM audio stream config to convert from.
    12901291 * @param   pFmt    The windows structure to initialize.
    12911292 */
    1292 static void dsoundWaveFmtFromCfg(PCPDMAUDIOSTREAMCFG pCfg, PWAVEFORMATEX pFmt)
     1293static void dsoundWaveFmtFromCfg(PCPDMAUDIOSTREAMCFG pCfg, PWAVEFORMATEXTENSIBLE pFmt)
    12931294{
    12941295    RT_ZERO(*pFmt);
    1295     pFmt->wFormatTag      = WAVE_FORMAT_PCM;
    1296     pFmt->nChannels       = PDMAudioPropsChannels(&pCfg->Props);
    1297     pFmt->wBitsPerSample  = PDMAudioPropsSampleBits(&pCfg->Props);
    1298     pFmt->nSamplesPerSec  = PDMAudioPropsHz(&pCfg->Props);
    1299     pFmt->nBlockAlign     = PDMAudioPropsFrameSize(&pCfg->Props);
    1300     pFmt->nAvgBytesPerSec = PDMAudioPropsFramesToBytes(&pCfg->Props, PDMAudioPropsHz(&pCfg->Props));
    1301     pFmt->cbSize          = 0; /* No extra data specified. */
     1296    pFmt->Format.wFormatTag      = WAVE_FORMAT_PCM;
     1297    pFmt->Format.nChannels       = PDMAudioPropsChannels(&pCfg->Props);
     1298    pFmt->Format.wBitsPerSample  = PDMAudioPropsSampleBits(&pCfg->Props);
     1299    pFmt->Format.nSamplesPerSec  = PDMAudioPropsHz(&pCfg->Props);
     1300    pFmt->Format.nBlockAlign     = PDMAudioPropsFrameSize(&pCfg->Props);
     1301    pFmt->Format.nAvgBytesPerSec = PDMAudioPropsFramesToBytes(&pCfg->Props, PDMAudioPropsHz(&pCfg->Props));
     1302    pFmt->Format.cbSize          = 0; /* No extra data specified. */
     1303
     1304    /*
     1305     * We need to use the extensible structure if there are more than two channels
     1306     * or if the channels have non-standard assignments.
     1307     */
     1308    if (   pFmt->Format.nChannels > 2
     1309        || (  pFmt->Format.nChannels == 1
     1310            ?    pCfg->Props.aidChannels[0] != PDMAUDIOCHANNELID_MONO
     1311            :    pCfg->Props.aidChannels[0] != PDMAUDIOCHANNELID_FRONT_LEFT
     1312              || pCfg->Props.aidChannels[1] != PDMAUDIOCHANNELID_FRONT_RIGHT))
     1313    {
     1314        pFmt->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
     1315        pFmt->Format.cbSize     = sizeof(*pFmt) - sizeof(pFmt->Format);
     1316        pFmt->Samples.wValidBitsPerSample = PDMAudioPropsSampleBits(&pCfg->Props);
     1317        pFmt->SubFormat         = KSDATAFORMAT_SUBTYPE_PCM;
     1318        pFmt->dwChannelMask     = 0;
     1319        unsigned const cSrcChannels = pFmt->Format.nChannels;
     1320        for (unsigned i = 0; i < cSrcChannels; i++)
     1321            if (   pCfg->Props.aidChannels[i] >= PDMAUDIOCHANNELID_FIRST_STANDARD
     1322                && pCfg->Props.aidChannels[i] <  PDMAUDIOCHANNELID_END_STANDARD)
     1323                pFmt->dwChannelMask |= RT_BIT_32(pCfg->Props.aidChannels[i] - PDMAUDIOCHANNELID_FIRST_STANDARD);
     1324            else
     1325                pFmt->Format.nChannels -= 1;
     1326    }
    13021327}
    13031328
     
    14221447 * @param   pCfgAcq     Where to return the actual stream config.  This is a
    14231448 *                      copy of @a *pCfgReq when called.
    1424  * @param   pWaveFmtX   On input the requested stream format.
    1425  *                      Updated to the actual stream format on successful
    1426  *                      return.
    1427  */
    1428 static HRESULT drvHostDSoundStreamCreateCapture(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS,
    1429                                                 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq, WAVEFORMATEX *pWaveFmtX)
     1449 * @param   pWaveFmtExt On input the requested stream format. Updated to the
     1450 *                      actual stream format on successful return.
     1451 */
     1452static HRESULT drvHostDSoundStreamCreateCapture(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, PPDMAUDIOSTREAMCFG pCfgReq,
     1453                                                PPDMAUDIOSTREAMCFG pCfgAcq, WAVEFORMATEXTENSIBLE *pWaveFmtExt)
    14301454{
    14311455    Assert(pStreamDS->In.pDSCB == NULL);
     
    14541478        /*.dwBufferBytes =*/    PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize),
    14551479        /*.dwReserved = */      0,
    1456         /*.lpwfxFormat = */     pWaveFmtX,
     1480        /*.lpwfxFormat = */     &pWaveFmtExt->Format,
    14571481        /*.dwFXCount = */       0,
    14581482        /*.lpDSCFXDesc = */     NULL
     
    14911515    }
    14921516#endif
    1493     RT_ZERO(*pWaveFmtX);
    1494     hrc = IDirectSoundCaptureBuffer8_GetFormat(pStreamDS->In.pDSCB, pWaveFmtX, sizeof(*pWaveFmtX), NULL);
     1517    RT_ZERO(*pWaveFmtExt);
     1518    hrc = IDirectSoundCaptureBuffer8_GetFormat(pStreamDS->In.pDSCB, &pWaveFmtExt->Format, sizeof(*pWaveFmtExt), NULL);
    14951519    if (SUCCEEDED(hrc))
    14961520    {
     
    15421566 * @param   pCfgAcq     Where to return the actual stream config.  This is a
    15431567 *                      copy of @a *pCfgReq when called.
    1544  * @param   pWaveFmt On input the requested stream format.
     1568 * @param   pWaveFmtExt On input the requested stream format.
    15451569 *                      Updated to the actual stream format on successful
    15461570 *                      return.
    15471571 */
    1548 static HRESULT drvHostDSoundStreamCreatePlayback(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS,
    1549                                                  PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq, WAVEFORMATEX *pWaveFmtX)
     1572static HRESULT drvHostDSoundStreamCreatePlayback(PDRVHOSTDSOUND pThis, PDSOUNDSTREAM pStreamDS, PPDMAUDIOSTREAMCFG pCfgReq,
     1573                                                 PPDMAUDIOSTREAMCFG pCfgAcq, WAVEFORMATEXTENSIBLE *pWaveFmtExt)
    15501574{
    15511575    Assert(pStreamDS->Out.pDSB == NULL);
     
    15841608        /*.dwBufferBytes = */   PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize),
    15851609        /*.dwReserved = */      0,
    1586         /*.lpwfxFormat = */     pWaveFmtX
     1610        /*.lpwfxFormat = */     &pWaveFmtExt->Format,
    15871611        /*.guid3DAlgorithm =    {0, 0, 0, {0,0,0,0, 0,0,0,0}} */
    15881612    };
     
    16101634     * Query the actual stream parameters, they may differ from what we requested.
    16111635     */
    1612     RT_ZERO(*pWaveFmtX);
    1613     hrc = IDirectSoundBuffer8_GetFormat(pStreamDS->Out.pDSB, pWaveFmtX, sizeof(*pWaveFmtX), NULL);
     1636    RT_ZERO(*pWaveFmtExt);
     1637    hrc = IDirectSoundBuffer8_GetFormat(pStreamDS->Out.pDSB, &pWaveFmtExt->Format, sizeof(*pWaveFmtExt), NULL);
    16141638    if (SUCCEEDED(hrc))
    16151639    {
     
    16881712             PDMAudioPropsToString(&pCfgReq->Props, szTmp, sizeof(szTmp))));
    16891713
    1690     WAVEFORMATEX WaveFmtX;
    1691     dsoundWaveFmtFromCfg(pCfgReq, &WaveFmtX);
     1714    WAVEFORMATEXTENSIBLE WaveFmtExt;
     1715    dsoundWaveFmtFromCfg(pCfgReq, &WaveFmtExt);
    16921716    LogRel2(("DSound: Requested %s format for '%s':\n"
    16931717             "DSound:   wFormatTag      = %RU16\n"
     
    16981722             "DSound:   wBitsPerSample  = %RU16\n"
    16991723             "DSound:   cbSize          = %RU16\n",
    1700              pszStreamType, pCfgReq->szName, WaveFmtX.wFormatTag, WaveFmtX.nChannels, WaveFmtX.nSamplesPerSec,
    1701              WaveFmtX.nAvgBytesPerSec, WaveFmtX.nBlockAlign, WaveFmtX.wBitsPerSample, WaveFmtX.cbSize));
     1724             pszStreamType, pCfgReq->szName, WaveFmtExt.Format.wFormatTag, WaveFmtExt.Format.nChannels,
     1725             WaveFmtExt.Format.nSamplesPerSec, WaveFmtExt.Format.nAvgBytesPerSec, WaveFmtExt.Format.nBlockAlign,
     1726             WaveFmtExt.Format.wBitsPerSample, WaveFmtExt.Format.cbSize));
     1727    if (WaveFmtExt.Format.cbSize != 0)
     1728        LogRel2(("DSound:   dwChannelMask   = %#RX32\n"
     1729                 "DSound:   wValidBitsPerSample = %RU16\n",
     1730                 WaveFmtExt.dwChannelMask, WaveFmtExt.Samples.wValidBitsPerSample));
    17021731
    17031732    HRESULT hrc;
    17041733    if (pCfgReq->enmDir == PDMAUDIODIR_IN)
    1705         hrc = drvHostDSoundStreamCreateCapture(pThis, pStreamDS, pCfgReq, pCfgAcq, &WaveFmtX);
     1734        hrc = drvHostDSoundStreamCreateCapture(pThis, pStreamDS, pCfgReq, pCfgAcq, &WaveFmtExt);
    17061735    else
    1707         hrc = drvHostDSoundStreamCreatePlayback(pThis, pStreamDS, pCfgReq, pCfgAcq, &WaveFmtX);
     1736        hrc = drvHostDSoundStreamCreatePlayback(pThis, pStreamDS, pCfgReq, pCfgAcq, &WaveFmtExt);
    17081737    int rc;
    17091738    if (SUCCEEDED(hrc))
     
    17171746                 "DSound:   wBitsPerSample  = %RU16\n"
    17181747                 "DSound:   cbSize          = %RU16\n",
    1719                  pszStreamType, pCfgReq->szName, WaveFmtX.wFormatTag, WaveFmtX.nChannels, WaveFmtX.nSamplesPerSec,
    1720                  WaveFmtX.nAvgBytesPerSec, WaveFmtX.nBlockAlign, WaveFmtX.wBitsPerSample, WaveFmtX.cbSize));
     1748                 pszStreamType, pCfgReq->szName, WaveFmtExt.Format.wFormatTag, WaveFmtExt.Format.nChannels,
     1749                 WaveFmtExt.Format.nSamplesPerSec, WaveFmtExt.Format.nAvgBytesPerSec, WaveFmtExt.Format.nBlockAlign,
     1750                 WaveFmtExt.Format.wBitsPerSample, WaveFmtExt.Format.cbSize));
     1751        if (WaveFmtExt.Format.cbSize != 0)
     1752        {
     1753            LogRel2(("DSound:   dwChannelMask   = %#RX32\n"
     1754                     "DSound:   wValidBitsPerSample = %RU16\n",
     1755                     WaveFmtExt.dwChannelMask, WaveFmtExt.Samples.wValidBitsPerSample));
     1756
     1757            /* Update the channel count and map here. */
     1758            PDMAudioPropsSetChannels(&pCfgAcq->Props, WaveFmtExt.Format.nChannels);
     1759            uint8_t idCh = 0;
     1760            for (unsigned iBit = 0; iBit < 32 && idCh < WaveFmtExt.Format.nChannels; iBit++)
     1761                if (WaveFmtExt.dwChannelMask & RT_BIT_32(iBit))
     1762                {
     1763                    pCfgAcq->Props.aidChannels[idCh] = (unsigned)PDMAUDIOCHANNELID_FIRST_STANDARD + iBit;
     1764                    idCh++;
     1765                }
     1766            Assert(idCh == WaveFmtExt.Format.nChannels);
     1767        }
    17211768
    17221769        /*
     
    18351882                    pStreamDS->In.pDSCB = NULL;
    18361883
    1837                     PDMAUDIOSTREAMCFG   CfgReq = pStreamDS->Cfg;
    1838                     PDMAUDIOSTREAMCFG   CfgAcq = pStreamDS->Cfg;
    1839                     WAVEFORMATEX        WaveFmtX;
    1840                     dsoundWaveFmtFromCfg(&pStreamDS->Cfg, &WaveFmtX);
    1841                     hrc = drvHostDSoundStreamCreateCapture(pThis, pStreamDS, &CfgReq, &CfgAcq, &WaveFmtX);
     1884                    PDMAUDIOSTREAMCFG       CfgReq = pStreamDS->Cfg;
     1885                    PDMAUDIOSTREAMCFG       CfgAcq = pStreamDS->Cfg;
     1886                    WAVEFORMATEXTENSIBLE    WaveFmtExt;
     1887                    dsoundWaveFmtFromCfg(&pStreamDS->Cfg, &WaveFmtExt);
     1888                    hrc = drvHostDSoundStreamCreateCapture(pThis, pStreamDS, &CfgReq, &CfgAcq, &WaveFmtExt);
    18421889                    if (SUCCEEDED(hrc))
    18431890                    {
     
    22762323                cbFree = pStreamDS->cbBufSize;
    22772324
    2278             DSLOGREL(("DSound: offPlayCursor=%RU32, offWriteCursor=%RU32, offWritePos=%RU32 -> cbFree=%RI32\n",
    2279                       offPlayCursor, offWriteCursor, pStreamDS->Out.offWritePos, cbFree));
     2325            LogRel2(("DSound: offPlayCursor=%RU32, offWriteCursor=%RU32, offWritePos=%RU32 -> cbFree=%RI32\n",
     2326                     offPlayCursor, offWriteCursor, pStreamDS->Out.offWritePos, cbFree));
    22802327
    22812328            *pdwFree = cbFree;
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