[PATCH 0/2] MR5116: dsound: Reject WAVEFORMATEX formats with more than two channels.
Formats with more than two channels require WAVEFORMATEXTENSIBLE according to tests. Fix Viking: Battle for Asgard (211160) audio cracking in its intro video. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5116
From: Zhiyi Zhang <zzhang(a)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) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5116
From: Zhiyi Zhang <zzhang(a)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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5116
This merge request was approved by Huw Davies. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5116
participants (3)
-
Huw Davies (@huw) -
Zhiyi Zhang -
Zhiyi Zhang (@zhiyi)