diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index 0bfd56671cd..a8244777f8e 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -440,35 +440,24 @@ HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LP return DS_OK; } -static DWORD DSOUND_GetFormatSize(LPCWAVEFORMATEX wfex) +WAVEFORMATEX *DSOUND_CopyFormat(const WAVEFORMATEX *wfex) { - if (wfex->wFormatTag == WAVE_FORMAT_PCM) - return sizeof(WAVEFORMATEX); - else - return sizeof(WAVEFORMATEX) + wfex->cbSize; -} + WAVEFORMATEX *pwfx; + if(wfex->wFormatTag == WAVE_FORMAT_PCM){ + pwfx = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEFORMATEX)); + CopyMemory(pwfx, wfex, sizeof(PCMWAVEFORMAT)); + pwfx->cbSize = 0; + }else{ + pwfx = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEFORMATEX) + wfex->cbSize); + CopyMemory(pwfx, wfex, sizeof(WAVEFORMATEX) + wfex->cbSize); + } -LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex) -{ - DWORD size = DSOUND_GetFormatSize(wfex); - LPWAVEFORMATEX pwfx = HeapAlloc(GetProcessHeap(),0,size); - if (pwfx == NULL) { - WARN("out of memory\n"); - } else if (wfex->wFormatTag != WAVE_FORMAT_PCM) { - CopyMemory(pwfx, wfex, size); - } else { - CopyMemory(pwfx, wfex, sizeof(PCMWAVEFORMAT)); - pwfx->cbSize=0; - if (pwfx->nBlockAlign != pwfx->nChannels * pwfx->wBitsPerSample/8) { - WARN("Fixing bad nBlockAlign (%u)\n", pwfx->nBlockAlign); - pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample/8; - } - if (pwfx->nAvgBytesPerSec != pwfx->nSamplesPerSec * pwfx->nBlockAlign) { - WARN("Fixing bad nAvgBytesPerSec (%u)\n", pwfx->nAvgBytesPerSec); - pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; - } - } - return pwfx; + if(pwfx->wFormatTag == WAVE_FORMAT_PCM || + (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE && + IsEqualGUID(&((const WAVEFORMATEXTENSIBLE*)pwfx)->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))) + pwfx->nBlockAlign = (pwfx->nChannels * pwfx->wBitsPerSample) / 8; + + return pwfx; } HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passed_fmt) @@ -545,27 +534,9 @@ done: device->primary_pwfx = old_fmt; else HeapFree(GetProcessHeap(), 0, old_fmt); - } else if (passed_fmt->wFormatTag == WAVE_FORMAT_PCM || - passed_fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { - /* Fill in "real" values to primary_pwfx */ - WAVEFORMATEX *fmt = device->primary_pwfx; - - *fmt = *device->pwfx; - fmtex = (void*)device->pwfx; - - if (IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) && - passed_fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { - fmt->wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - } else { - fmt->wFormatTag = WAVE_FORMAT_PCM; - fmt->wBitsPerSample = 16; - } - fmt->nBlockAlign = fmt->nChannels * fmt->wBitsPerSample / 8; - fmt->nAvgBytesPerSec = fmt->nBlockAlign * fmt->nSamplesPerSec; - fmt->cbSize = 0; } else { - device->primary_pwfx = HeapReAlloc(GetProcessHeap(), 0, device->primary_pwfx, sizeof(*fmtex)); - memcpy(device->primary_pwfx, device->pwfx, sizeof(*fmtex)); + HeapFree(GetProcessHeap(), 0, device->primary_pwfx); + device->primary_pwfx = DSOUND_CopyFormat(passed_fmt); } out: diff --git a/dlls/dsound/tests/dsound.c b/dlls/dsound/tests/dsound.c index 4291e7a114d..bca0d76267f 100644 --- a/dlls/dsound/tests/dsound.c +++ b/dlls/dsound/tests/dsound.c @@ -1348,6 +1348,15 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid) rc = IDirectSoundBuffer_SetFormat(primary, &wfx); ok(rc == S_OK, "SetFormat: %08x\n", rc); + rc = IDirectSoundBuffer_GetFormat(primary, &wfx, sizeof(wfx), NULL); + ok(rc == S_OK, "GetFormat: %08x\n", rc); + ok(wfx.wFormatTag == WAVE_FORMAT_PCM, "format: 0x%x\n", wfx.wFormatTag); + ok(wfx.nChannels == 2, "channels: %u\n", wfx.nChannels); + ok(wfx.nSamplesPerSec == 44100, "rate: %u\n", wfx.nSamplesPerSec); + ok(wfx.wBitsPerSample == 16, "bps: %u\n", wfx.wBitsPerSample); + ok(wfx.nBlockAlign == 4, "blockalign: %u\n", wfx.nBlockAlign); + ok(wfx.nAvgBytesPerSec == 44100 * 4 + 1, "avgbytes: %u\n", wfx.nAvgBytesPerSec); + wfx.nChannels = 2; wfx.nSamplesPerSec = 44100; wfx.wBitsPerSample = 16; @@ -1356,6 +1365,15 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid) rc = IDirectSoundBuffer_SetFormat(primary, &wfx); ok(rc == S_OK, "SetFormat: %08x\n", rc); + rc = IDirectSoundBuffer_GetFormat(primary, &wfx, sizeof(wfx), NULL); + ok(rc == S_OK, "GetFormat: %08x\n", rc); + ok(wfx.wFormatTag == WAVE_FORMAT_PCM, "format: 0x%x\n", wfx.wFormatTag); + ok(wfx.nChannels == 2, "channels: %u\n", wfx.nChannels); + ok(wfx.nSamplesPerSec == 44100, "rate: %u\n", wfx.nSamplesPerSec); + ok(wfx.wBitsPerSample == 16, "bps: %u\n", wfx.wBitsPerSample); + ok(wfx.nBlockAlign == 4, "blockalign: %u\n", wfx.nBlockAlign); + ok(wfx.nAvgBytesPerSec == 44100 * 4 - 1, "avgbytes: %u\n", wfx.nAvgBytesPerSec); + wfx.nChannels = 2; wfx.nSamplesPerSec = 44100; wfx.wBitsPerSample = 16; @@ -1364,6 +1382,33 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid) rc = IDirectSoundBuffer_SetFormat(primary, &wfx); ok(rc == S_OK, "SetFormat: %08x\n", rc); + rc = IDirectSoundBuffer_GetFormat(primary, &wfx, sizeof(wfx), NULL); + ok(rc == S_OK, "GetFormat: %08x\n", rc); + ok(wfx.wFormatTag == WAVE_FORMAT_PCM, "format: 0x%x\n", wfx.wFormatTag); + ok(wfx.nChannels == 2, "channels: %u\n", wfx.nChannels); + ok(wfx.nSamplesPerSec == 44100, "rate: %u\n", wfx.nSamplesPerSec); + ok(wfx.wBitsPerSample == 16, "bps: %u\n", wfx.wBitsPerSample); + ok(wfx.nBlockAlign == 4, "blockalign: %u\n", wfx.nBlockAlign); + ok(wfx.nAvgBytesPerSec == 44100 * 4 + 1, "avgbytes: %u\n", wfx.nAvgBytesPerSec); + + wfx.wFormatTag = WAVE_FORMAT_ALAW; + wfx.nChannels = 2; + wfx.nSamplesPerSec = 44100; + wfx.wBitsPerSample = 16; + wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + rc = IDirectSoundBuffer_SetFormat(primary, &wfx); + ok(rc == S_OK, "SetFormat: %08x\n", rc); + + rc = IDirectSoundBuffer_GetFormat(primary, &wfx, sizeof(wfx), NULL); + ok(rc == S_OK, "GetFormat: %08x\n", rc); + ok(wfx.wFormatTag == WAVE_FORMAT_ALAW, "format: 0x%x\n", wfx.wFormatTag); + ok(wfx.nChannels == 2, "channels: %u\n", wfx.nChannels); + ok(wfx.nSamplesPerSec == 44100, "rate: %u\n", wfx.nSamplesPerSec); + ok(wfx.wBitsPerSample == 16, "bps: %u\n", wfx.wBitsPerSample); + ok(wfx.nBlockAlign == 4, "blockalign: %u\n", wfx.nBlockAlign); + ok(wfx.nAvgBytesPerSec == 44100 * 4, "avgbytes: %u\n", wfx.nAvgBytesPerSec); + fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; fmtex.Format.nChannels = 2; @@ -1377,6 +1422,19 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid) rc = IDirectSoundBuffer_SetFormat(primary, (WAVEFORMATEX*)&fmtex); ok(rc == S_OK, "SetFormat: %08x\n", rc); + rc = IDirectSoundBuffer_GetFormat(primary, (WAVEFORMATEX*)&fmtex, sizeof(fmtex), NULL); + ok(rc == S_OK, "GetFormat: %08x\n", rc); + ok(fmtex.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "format: 0x%x\n", fmtex.Format.wFormatTag); + ok(fmtex.Format.nChannels == 2, "channels: %u\n", fmtex.Format.nChannels); + ok(fmtex.Format.nSamplesPerSec == 44100, "rate: %u\n", fmtex.Format.nSamplesPerSec); + ok(fmtex.Format.wBitsPerSample == 16, "bps: %u\n", fmtex.Format.wBitsPerSample); + ok(fmtex.Format.nBlockAlign == 4, "blockalign: %u\n", fmtex.Format.nBlockAlign); + ok(fmtex.Format.nAvgBytesPerSec == 44100 * 4, "avgbytes: %u\n", fmtex.Format.nAvgBytesPerSec); + ok(fmtex.Samples.wValidBitsPerSample == 0 || /* <= XP */ + fmtex.Samples.wValidBitsPerSample == 16, /* >= Vista */ + "validbits: %u\n", fmtex.Samples.wValidBitsPerSample); + ok(IsEqualGUID(&fmtex.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM), "subtype incorrect\n"); + fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; fmtex.Format.nChannels = 2; @@ -1390,6 +1448,17 @@ static HRESULT test_invalid_fmts(LPGUID lpGuid) rc = IDirectSoundBuffer_SetFormat(primary, (WAVEFORMATEX*)&fmtex); ok(rc == S_OK, "SetFormat: %08x\n", rc); + rc = IDirectSoundBuffer_GetFormat(primary, (WAVEFORMATEX*)&fmtex, sizeof(fmtex), NULL); + ok(rc == S_OK, "GetFormat: %08x\n", rc); + ok(fmtex.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "format: 0x%x\n", fmtex.Format.wFormatTag); + ok(fmtex.Format.nChannels == 2, "channels: %u\n", fmtex.Format.nChannels); + ok(fmtex.Format.nSamplesPerSec == 44100, "rate: %u\n", fmtex.Format.nSamplesPerSec); + ok(fmtex.Format.wBitsPerSample == 24, "bps: %u\n", fmtex.Format.wBitsPerSample); + ok(fmtex.Format.nBlockAlign == 6, "blockalign: %u\n", fmtex.Format.nBlockAlign); + ok(fmtex.Format.nAvgBytesPerSec == 44100 * 6, "avgbytes: %u\n", fmtex.Format.nAvgBytesPerSec); + ok(fmtex.Samples.wValidBitsPerSample == 20, "validbits: %u\n", fmtex.Samples.wValidBitsPerSample); + ok(IsEqualGUID(&fmtex.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM), "subtype incorrect\n"); + fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; fmtex.Format.nChannels = 2;