VirtualBox

Changeset 89393 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 31, 2021 11:05:46 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144744
Message:

DrvHostAudioWasApi: Multi-channel support. bugref:9890

File:
1 edited

Legend:

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

    r89325 r89393  
    662662
    663663/**
    664  * Converts from PDM stream config to windows WAVEFORMATEX struct.
     664 * Converts from PDM stream config to windows WAVEFORMATEXTENSIBLE struct.
    665665 *
    666666 * @param   pProps  The PDM audio PCM properties to convert from.
    667667 * @param   pFmt    The windows structure to initialize.
    668668 */
    669 static void drvHostAudioWasWaveFmtExFromProps(PCPDMAUDIOPCMPROPS pProps, PWAVEFORMATEX pFmt)
     669static void drvHostAudioWasWaveFmtExtFromProps(PCPDMAUDIOPCMPROPS pProps, PWAVEFORMATEXTENSIBLE pFmt)
    670670{
    671671    RT_ZERO(*pFmt);
    672     pFmt->wFormatTag      = WAVE_FORMAT_PCM;
    673     pFmt->nChannels       = PDMAudioPropsChannels(pProps);
    674     pFmt->wBitsPerSample  = PDMAudioPropsSampleBits(pProps);
    675     pFmt->nSamplesPerSec  = PDMAudioPropsHz(pProps);
    676     pFmt->nBlockAlign     = PDMAudioPropsFrameSize(pProps);
    677     pFmt->nAvgBytesPerSec = PDMAudioPropsFramesToBytes(pProps, PDMAudioPropsHz(pProps));
    678     pFmt->cbSize          = 0; /* No extra data specified. */
     672    pFmt->Format.wFormatTag      = WAVE_FORMAT_PCM;
     673    pFmt->Format.nChannels       = PDMAudioPropsChannels(pProps);
     674    pFmt->Format.wBitsPerSample  = PDMAudioPropsSampleBits(pProps);
     675    pFmt->Format.nSamplesPerSec  = PDMAudioPropsHz(pProps);
     676    pFmt->Format.nBlockAlign     = PDMAudioPropsFrameSize(pProps);
     677    pFmt->Format.nAvgBytesPerSec = PDMAudioPropsFramesToBytes(pProps, PDMAudioPropsHz(pProps));
     678    pFmt->Format.cbSize          = 0; /* No extra data specified. */
     679
     680    /*
     681     * We need to use the extensible structure if there are more than two channels
     682     * or if the channels have non-standard assignments.
     683     */
     684    if (   pFmt->Format.nChannels > 2
     685        || (  pFmt->Format.nChannels == 1 ? pProps->aidChannels[0] != PDMAUDIOCHANNELID_MONO
     686            : pProps->aidChannels[0] != PDMAUDIOCHANNELID_FRONT_LEFT || pProps->aidChannels[2] != PDMAUDIOCHANNELID_FRONT_RIGHT))
     687    {
     688        pFmt->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
     689        pFmt->Format.cbSize     = sizeof(*pFmt) - sizeof(pFmt->Format);
     690        pFmt->Samples.wValidBitsPerSample = PDMAudioPropsSampleBits(pProps);
     691        pFmt->SubFormat         = KSDATAFORMAT_SUBTYPE_PCM;
     692        pFmt->dwChannelMask     = 0;
     693        unsigned const cSrcChannels = pFmt->Format.nChannels;
     694        for (unsigned i = 0; i < cSrcChannels; i++)
     695            if (   pProps->aidChannels[i] >= PDMAUDIOCHANNELID_FIRST_STANDARD
     696                && pProps->aidChannels[i] <  PDMAUDIOCHANNELID_END_STANDARD)
     697                pFmt->dwChannelMask |= RT_BIT_32(pProps->aidChannels[i] - PDMAUDIOCHANNELID_FIRST_STANDARD);
     698            else
     699                pFmt->Format.nChannels -= 1;
     700    }
    679701}
    680702
     
    946968    }
    947969
    948     WAVEFORMATEX  WaveFmtEx;
    949     drvHostAudioWasWaveFmtExFromProps(&pDevCfg->Props, &WaveFmtEx);
     970    WAVEFORMATEXTENSIBLE WaveFmtExt;
     971    drvHostAudioWasWaveFmtExtFromProps(&pDevCfg->Props, &WaveFmtExt);
    950972
    951973    PWAVEFORMATEX pClosestMatch = NULL;
    952     hrc = pIAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &WaveFmtEx, &pClosestMatch);
     974    hrc = pIAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &WaveFmtExt.Format, &pClosestMatch);
    953975
    954976    /*
    955977     * If the format is supported, go ahead and initialize the client instance.
    956978     */
    957     if (SUCCEEDED(hrc))
    958     {
    959         if (hrc == S_OK)
     979    if (SUCCEEDED(hrc) || hrc == AUDCLNT_E_UNSUPPORTED_FORMAT)
     980    {
     981        if (hrc == S_OK || hrc == AUDCLNT_E_UNSUPPORTED_FORMAT)
    960982            Log8Func(("IsFormatSupport(,%s,) -> S_OK + %p: requested format is supported\n", pDevCfg->szProps, pClosestMatch));
    961983        else
     
    968990                                                  | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY;
    969991        hrc = pIAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, fInitFlags, cBufferSizeInNtTicks,
    970                                         0 /*cPeriodicityInNtTicks*/, &WaveFmtEx, NULL /*pAudioSessionGuid*/);
     992                                        0 /*cPeriodicityInNtTicks*/, &WaveFmtExt.Format, NULL /*pAudioSessionGuid*/);
    971993        Log8Func(("Initialize(,%x, %RI64, %s,) -> %Rhrc\n", fInitFlags, cBufferSizeInNtTicks, pDevCfg->szProps, hrc));
    972994        if (SUCCEEDED(hrc))
     
    17881810     * Do configuration conversion.
    17891811     */
    1790     WAVEFORMATEX WaveFmtX;
    1791     drvHostAudioWasWaveFmtExFromProps(&pCfgReq->Props, &WaveFmtX);
     1812    WAVEFORMATEXTENSIBLE WaveFmtExt;
     1813    drvHostAudioWasWaveFmtExtFromProps(&pCfgReq->Props, &WaveFmtExt);
    17921814    LogRel2(("WasAPI: Requested %s format for '%s':\n"
    1793              "WasAPI:   wFormatTag      = %RU16\n"
     1815             "WasAPI:   wFormatTag      = %#RX16\n"
    17941816             "WasAPI:   nChannels       = %RU16\n"
    17951817             "WasAPI:   nSamplesPerSec  = %RU32\n"
     
    17991821             "WasAPI:   cbSize          = %RU16\n"
    18001822             "WasAPI:   cBufferSizeInNtTicks = %RU64\n",
    1801              pszStreamType, pCfgReq->szName, WaveFmtX.wFormatTag, WaveFmtX.nChannels, WaveFmtX.nSamplesPerSec,
    1802              WaveFmtX.nAvgBytesPerSec, WaveFmtX.nBlockAlign, WaveFmtX.wBitsPerSample, WaveFmtX.cbSize,
     1823             pszStreamType, pCfgReq->szName, WaveFmtExt.Format.wFormatTag, WaveFmtExt.Format.nChannels,
     1824             WaveFmtExt.Format.nSamplesPerSec, WaveFmtExt.Format.nAvgBytesPerSec, WaveFmtExt.Format.nBlockAlign,
     1825             WaveFmtExt.Format.wBitsPerSample, WaveFmtExt.Format.cbSize,
    18031826             PDMAudioPropsFramesToNtTicks(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize) ));
     1827    if (WaveFmtExt.Format.cbSize != 0)
     1828        LogRel2(("WasAPI:   dwChannelMask   = %#RX32\n"
     1829                 "WasAPI:   wValidBitsPerSample = %RU16\n",
     1830                 WaveFmtExt.dwChannelMask, WaveFmtExt.Samples.wValidBitsPerSample));
     1831
     1832    /* Set up the acquired format here as channel count + layout may have
     1833       changed and need to be communicated to caller and used in cache lookup. */
     1834    *pCfgAcq = *pCfgReq;
     1835    if (WaveFmtExt.Format.cbSize != 0)
     1836    {
     1837        PDMAudioPropsSetChannels(&pCfgAcq->Props, WaveFmtExt.Format.nChannels);
     1838        uint8_t idCh = 0;
     1839        for (unsigned iBit = 0; iBit < 32 && idCh < WaveFmtExt.Format.nChannels; iBit++)
     1840            if (WaveFmtExt.dwChannelMask & RT_BIT_32(iBit))
     1841            {
     1842                pCfgAcq->Props.aidChannels[idCh] = (unsigned)PDMAUDIOCHANNELID_FIRST_STANDARD + iBit;
     1843                idCh++;
     1844            }
     1845        Assert(idCh == WaveFmtExt.Format.nChannels);
     1846    }
    18041847
    18051848    /*
     
    18381881     *        was invalidated/changed while we where working on it here. */
    18391882    PDRVHOSTAUDIOWASCACHEDEVCFG pDevCfg = NULL;
    1840     int rc = drvHostAudioWasCacheLookupOrCreate(pThis, pIDevice, pCfgReq, false /*fOnWorker*/, &pDevCfg);
     1883    int rc = drvHostAudioWasCacheLookupOrCreate(pThis, pIDevice, pCfgAcq, false /*fOnWorker*/, &pDevCfg);
    18411884
    18421885    pIDevice->Release();
Note: See TracChangeset for help on using the changeset viewer.

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