Formats with more than two channels require WAVEFORMATEXTENSIBLE according to tests.
Fix Viking: Battle for Asgard (211160) audio cracking in its intro video.
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/dsound/tests/dsound.c | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/dlls/dsound/tests/dsound.c b/dlls/dsound/tests/dsound.c index 9656a458415..c957f3a8a4b 100644 --- a/dlls/dsound/tests/dsound.c +++ b/dlls/dsound/tests/dsound.c @@ -1481,6 +1481,51 @@ static void perform_invalid_fmt_tests(const char *testname, IDirectSound *dso, I fmtex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; rc = do_invalid_fmt_test(dso, buf, (WAVEFORMATEX*)&fmtex, &got_buf); ok(rc == E_INVALIDARG, "%s: SetFormat: %08lx\n", testname, rc); + + /* The following 4 tests show that formats with more than two channels require WAVEFORMATEXTENSIBLE */ + 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; + rc = do_invalid_fmt_test(dso, buf, &wfx, &got_buf); + ok(rc == S_OK, "%s: SetFormat: %08lx\n", testname, rc); + IDirectSoundBuffer_Release(got_buf); + + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = 4; + wfx.nSamplesPerSec = 44100; + wfx.wBitsPerSample = 16; + wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + rc = do_invalid_fmt_test(dso, buf, &wfx, &got_buf); + todo_wine + ok(rc == (buf ? DSERR_ALLOCATED : DSERR_INVALIDPARAM), "%s: SetFormat: %08lx\n", testname, rc); + + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = 6; + wfx.nSamplesPerSec = 44100; + wfx.wBitsPerSample = 16; + wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + rc = do_invalid_fmt_test(dso, buf, &wfx, &got_buf); + todo_wine + ok(rc == (buf ? DSERR_ALLOCATED : DSERR_INVALIDPARAM), "%s: SetFormat: %08lx\n", testname, rc); + + fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + fmtex.Format.nChannels = 6; + fmtex.Format.nSamplesPerSec = 44100; + fmtex.Format.wBitsPerSample = 16; + fmtex.Format.nBlockAlign = fmtex.Format.nChannels * fmtex.Format.wBitsPerSample / 8; + fmtex.Format.nAvgBytesPerSec = fmtex.Format.nSamplesPerSec * fmtex.Format.nBlockAlign; + fmtex.Samples.wValidBitsPerSample = fmtex.Format.wBitsPerSample; + fmtex.dwChannelMask = KSAUDIO_SPEAKER_5POINT1; + fmtex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + rc = do_invalid_fmt_test(dso, buf, (WAVEFORMATEX *)&fmtex, &got_buf); + ok(rc == S_OK, "%s: SetFormat: %08lx\n", testname, rc); + IDirectSoundBuffer_Release(got_buf); }
static HRESULT test_invalid_fmts(LPGUID lpGuid)
From: Zhiyi Zhang zzhang@codeweavers.com
Formats with more than two channels require WAVEFORMATEXTENSIBLE according to tests.
Fix Viking: Battle for Asgard (211160) audio cracking in its intro video. --- dlls/dsound/dsound.c | 3 +++ dlls/dsound/primary.c | 3 +++ dlls/dsound/tests/dsound.c | 2 -- 3 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c index b35f9c7cbdd..356f211d7bb 100644 --- a/dlls/dsound/dsound.c +++ b/dlls/dsound/dsound.c @@ -490,6 +490,9 @@ static HRESULT DirectSoundDevice_CreateSoundBuffer( return DSERR_INVALIDPARAM; }
+ if (dsbd->lpwfxFormat->nChannels > 2 && dsbd->lpwfxFormat->wFormatTag != WAVE_FORMAT_EXTENSIBLE) + return DSERR_INVALIDPARAM; + if (dsbd->lpwfxFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { WAVEFORMATEXTENSIBLE *pwfxe = (WAVEFORMATEXTENSIBLE*)dsbd->lpwfxFormat; diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index 2e2473b4db2..6bb7b2ffba4 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -465,6 +465,9 @@ HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passe return DSERR_INVALIDPARAM; }
+ if (passed_fmt->nChannels > 2 && passed_fmt->wFormatTag != WAVE_FORMAT_EXTENSIBLE) + return DSERR_ALLOCATED; + /* **** */ AcquireSRWLockExclusive(&device->buffer_list_lock); EnterCriticalSection(&(device->mixlock)); diff --git a/dlls/dsound/tests/dsound.c b/dlls/dsound/tests/dsound.c index c957f3a8a4b..500bc19f655 100644 --- a/dlls/dsound/tests/dsound.c +++ b/dlls/dsound/tests/dsound.c @@ -1500,7 +1500,6 @@ static void perform_invalid_fmt_tests(const char *testname, IDirectSound *dso, I wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; rc = do_invalid_fmt_test(dso, buf, &wfx, &got_buf); - todo_wine ok(rc == (buf ? DSERR_ALLOCATED : DSERR_INVALIDPARAM), "%s: SetFormat: %08lx\n", testname, rc);
wfx.wFormatTag = WAVE_FORMAT_PCM; @@ -1510,7 +1509,6 @@ static void perform_invalid_fmt_tests(const char *testname, IDirectSound *dso, I wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; rc = do_invalid_fmt_test(dso, buf, &wfx, &got_buf); - todo_wine ok(rc == (buf ? DSERR_ALLOCATED : DSERR_INVALIDPARAM), "%s: SetFormat: %08lx\n", testname, rc);
fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
This merge request was approved by Huw Davies.