I am trying to initialize an audio capture client. If I use the following code, IsFormatSupported returns S_OK and Initialize returns E_INVALIDARG.

WAVEFORMATEX wfx;
wfx.cbSize = sizeof(WAVEFORMATEX);
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = 44100;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

WAVEFORMATEX* pwfx = reinterpret_cast<WAVEFORMATEX*>(&wfx);
WAVEFORMATEX* pWfxout = nullptr;

hr = pAudioClient->IsFormatSupported(
    AUDCLNT_SHAREMODE_EXCLUSIVE,
    &wfx,
    &pWfxout
);

assert(hr == S_OK);

hr = pAudioClient->Initialize(
    AUDCLNT_SHAREMODE_EXCLUSIVE,
    0,
    hnsRequestedDuration,
    0,
    pwfx,
    nullptr);

assert(hr == E_INVALIDARG);

After struggling with this for a few hours (in addition to a few more trying out a shared mode device, but that's a subject for another post) I vaguely recalled that if you use WAVEFORMATEXTENSIBLE things are less painful. So I modified the code like this.

WAVEFORMATEXTENSIBLE wfex;
wfex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE);
wfex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfex.Format.nChannels = 2;
wfex.Format.nSamplesPerSec = 44100;
wfex.Format.wBitsPerSample = 16;
wfex.Format.nBlockAlign = wfex.Format.nChannels * wfex.Format.wBitsPerSample / 8;
wfex.Format.nAvgBytesPerSec = wfex.Format.nSamplesPerSec * wfex.Format.nBlockAlign;
wfex.Samples.wValidBitsPerSample = wfex.Format.wBitsPerSample;
wfex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
wfex.dwChannelMask = 0;

WAVEFORMATEX* pwfx = reinterpret_cast<WAVEFORMATEX*>(&wfex);
WAVEFORMATEX* pWfxout = nullptr;

hr = pAudioClient->IsFormatSupported(
    AUDCLNT_SHAREMODE_EXCLUSIVE,
    pwfx,
    &pWfxout
);

assert(hr == S_OK);

hr = pAudioClient->Initialize(
    AUDCLNT_SHAREMODE_EXCLUSIVE,
    0,
    hnsRequestedDuration,
    0,
    pwfx,
    nullptr);

assert(hr == S_OK);

And both calls succeeds with S_OK.

(1) Why is this happening? This is especially troubling because in this case the WAVEFORMATEXTENSIBLE conceptually describes the same format as the WAVEFORMATEX. (2) Should we just not use WAVEFORMATEX because it was deprecated? I thought it was okay to use if it can indeed describe the format that you need (good ol' Stereo CD PCM in this case).

0

There are 0 best solutions below