HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) { UINT prebuf_frames; REFERENCE_TIME prebuf_rt; HRESULT hres; TRACE("(%p, %d)\n", device, forcewave); if(device->client){ IAudioClient_Release(device->client); device->client = NULL; } if(device->render){ IAudioRenderClient_Release(device->render); device->render = NULL; } if(device->clock){ IAudioClock_Release(device->clock); device->clock = NULL; } if(device->volume){ IAudioStreamVolume_Release(device->volume); device->volume = NULL; } hres = IMMDevice_Activate(device->mmdevice, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void **)&device->client); if(FAILED(hres)){ WARN("Activate failed: %08x\n", hres); return hres; } prebuf_frames = device->prebuf * DSOUND_fraglen(device->pwfx->nSamplesPerSec, device->pwfx->nBlockAlign) / device->pwfx->nBlockAlign; prebuf_rt = (10000000 * (UINT64)prebuf_frames) / device->pwfx->nSamplesPerSec; hres = IAudioClient_Initialize(device->client, AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST, prebuf_rt, 0, device->pwfx, NULL); if(FAILED(hres)){ IAudioClient_Release(device->client); device->client = NULL; WARN("Initialize failed: %08x\n", hres); return hres; } hres = IAudioClient_GetService(device->client, &IID_IAudioRenderClient, (void**)&device->render); if(FAILED(hres)){ IAudioClient_Release(device->client); device->client = NULL; WARN("GetService failed: %08x\n", hres); return hres; } hres = IAudioClient_GetService(device->client, &IID_IAudioClock, (void**)&device->clock); if(FAILED(hres)){ IAudioClient_Release(device->client); IAudioRenderClient_Release(device->render); device->client = NULL; device->render = NULL; WARN("GetService failed: %08x\n", hres); return hres; } hres = IAudioClient_GetService(device->client, &IID_IAudioStreamVolume, (void**)&device->volume); if(FAILED(hres)){ IAudioClient_Release(device->client); IAudioRenderClient_Release(device->render); IAudioClock_Release(device->clock); device->client = NULL; device->render = NULL; device->clock = NULL; WARN("GetService failed: %08x\n", hres); return hres; } return S_OK; }
static void test_references(void) { IAudioClient *ac; IAudioRenderClient *rc; ISimpleAudioVolume *sav; IAudioStreamVolume *asv; IAudioClock *acl; WAVEFORMATEX *pwfx; HRESULT hr; ULONG ref; /* IAudioRenderClient */ hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac); ok(hr == S_OK, "Activation failed with %08x\n", hr); if(hr != S_OK) return; hr = IAudioClient_GetMixFormat(ac, &pwfx); ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr); if(hr != S_OK) return; hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL); ok(hr == S_OK, "Initialize failed: %08x\n", hr); CoTaskMemFree(pwfx); hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&rc); ok(hr == S_OK, "GetService failed: %08x\n", hr); IAudioRenderClient_AddRef(rc); ref = IAudioRenderClient_Release(rc); ok(ref != 0, "RenderClient_Release gave wrong refcount: %u\n", ref); ref = IAudioClient_Release(ac); ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref); ref = IAudioRenderClient_Release(rc); ok(ref == 0, "RenderClient_Release gave wrong refcount: %u\n", ref); /* ISimpleAudioVolume */ hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac); ok(hr == S_OK, "Activation failed with %08x\n", hr); if(hr != S_OK) return; hr = IAudioClient_GetMixFormat(ac, &pwfx); ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr); hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL); ok(hr == S_OK, "Initialize failed: %08x\n", hr); CoTaskMemFree(pwfx); hr = IAudioClient_GetService(ac, &IID_ISimpleAudioVolume, (void**)&sav); ok(hr == S_OK, "GetService failed: %08x\n", hr); ISimpleAudioVolume_AddRef(sav); ref = ISimpleAudioVolume_Release(sav); ok(ref != 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref); ref = IAudioClient_Release(ac); ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref); ref = ISimpleAudioVolume_Release(sav); ok(ref == 0, "SimpleAudioVolume_Release gave wrong refcount: %u\n", ref); /* IAudioClock */ hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac); ok(hr == S_OK, "Activation failed with %08x\n", hr); if(hr != S_OK) return; hr = IAudioClient_GetMixFormat(ac, &pwfx); ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr); hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL); ok(hr == S_OK, "Initialize failed: %08x\n", hr); CoTaskMemFree(pwfx); hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl); ok(hr == S_OK, "GetService failed: %08x\n", hr); IAudioClock_AddRef(acl); ref = IAudioClock_Release(acl); ok(ref != 0, "AudioClock_Release gave wrong refcount: %u\n", ref); ref = IAudioClient_Release(ac); ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref); ref = IAudioClock_Release(acl); ok(ref == 0, "AudioClock_Release gave wrong refcount: %u\n", ref); /* IAudioStreamVolume */ hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac); ok(hr == S_OK, "Activation failed with %08x\n", hr); if(hr != S_OK) return; hr = IAudioClient_GetMixFormat(ac, &pwfx); ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr); hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL); ok(hr == S_OK, "Initialize failed: %08x\n", hr); hr = IAudioClient_GetService(ac, &IID_IAudioStreamVolume, (void**)&asv); ok(hr == S_OK, "GetService failed: %08x\n", hr); IAudioStreamVolume_AddRef(asv); ref = IAudioStreamVolume_Release(asv); ok(ref != 0, "AudioStreamVolume_Release gave wrong refcount: %u\n", ref); ref = IAudioClient_Release(ac); ok(ref != 0, "Client_Release gave wrong refcount: %u\n", ref); ref = IAudioStreamVolume_Release(asv); ok(ref == 0, "AudioStreamVolume_Release gave wrong refcount: %u\n", ref); }
static void test_clock(void) { HRESULT hr; IAudioClient *ac; IAudioClock *acl; IAudioRenderClient *arc; UINT64 freq, pos, pcpos, last; BYTE *data; WAVEFORMATEX *pwfx; hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac); ok(hr == S_OK, "Activation failed with %08x\n", hr); if(hr != S_OK) return; hr = IAudioClient_GetMixFormat(ac, &pwfx); ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr); if(hr != S_OK) return; hr = IAudioClient_Initialize(ac, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, pwfx, NULL); ok(hr == S_OK, "Initialize failed: %08x\n", hr); hr = IAudioClient_GetService(ac, &IID_IAudioClock, (void**)&acl); ok(hr == S_OK, "GetService(IAudioClock) failed: %08x\n", hr); hr = IAudioClock_GetFrequency(acl, &freq); ok(hr == S_OK, "GetFrequency failed: %08x\n", hr); hr = IAudioClock_GetPosition(acl, NULL, NULL); ok(hr == E_POINTER, "GetPosition wrong error: %08x\n", hr); pcpos = 0; hr = IAudioClock_GetPosition(acl, &pos, &pcpos); ok(hr == S_OK, "GetPosition failed: %08x\n", hr); ok(pos == 0, "GetPosition returned non-zero pos before being started\n"); ok(pcpos != 0, "GetPosition returned zero pcpos\n"); last = pos; hr = IAudioClient_GetService(ac, &IID_IAudioRenderClient, (void**)&arc); ok(hr == S_OK, "GetService(IAudioRenderClient) failed: %08x\n", hr); hr = IAudioRenderClient_GetBuffer(arc, pwfx->nSamplesPerSec / 2., &data); ok(hr == S_OK, "GetBuffer failed: %08x\n", hr); hr = IAudioRenderClient_ReleaseBuffer(arc, pwfx->nSamplesPerSec / 2., AUDCLNT_BUFFERFLAGS_SILENT); ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr); hr = IAudioClock_GetPosition(acl, &pos, NULL); ok(hr == S_OK, "GetPosition failed: %08x\n", hr); ok(pos == 0, "GetPosition returned non-zero pos before being started\n"); hr = IAudioClient_Start(ac); ok(hr == S_OK, "Start failed: %08x\n", hr); Sleep(100); hr = IAudioClock_GetPosition(acl, &pos, NULL); ok(hr == S_OK, "GetPosition failed: %08x\n", hr); ok(pos > 0, "Position should have been further along...\n"); last = pos; hr = IAudioClient_Stop(ac); ok(hr == S_OK, "Stop failed: %08x\n", hr); hr = IAudioClock_GetPosition(acl, &pos, NULL); ok(hr == S_OK, "GetPosition failed: %08x\n", hr); ok(pos >= last, "Position should have been further along...\n"); last = pos; hr = IAudioClient_Start(ac); ok(hr == S_OK, "Start failed: %08x\n", hr); Sleep(100); hr = IAudioClient_Stop(ac); ok(hr == S_OK, "Stop failed: %08x\n", hr); hr = IAudioClock_GetPosition(acl, &pos, NULL); ok(hr == S_OK, "GetPosition failed: %08x\n", hr); ok(pos >= last, "Position should have been further along...\n"); last = pos; hr = IAudioClock_GetPosition(acl, &pos, NULL); ok(hr == S_OK, "GetPosition failed: %08x\n", hr); ok(pos == last, "Position should have been further along...\n"); hr = IAudioClient_Reset(ac); ok(hr == S_OK, "Reset failed: %08x\n", hr); hr = IAudioClock_GetPosition(acl, &pos, NULL); ok(hr == S_OK, "GetPosition failed: %08x\n", hr); ok(pos == 0, "GetPosition returned non-zero pos after Reset\n"); last = pos; hr = IAudioRenderClient_GetBuffer(arc, pwfx->nSamplesPerSec / 2., &data); ok(hr == S_OK, "GetBuffer failed: %08x\n", hr); hr = IAudioRenderClient_ReleaseBuffer(arc, pwfx->nSamplesPerSec / 2., AUDCLNT_BUFFERFLAGS_SILENT); ok(hr == S_OK, "ReleaseBuffer failed: %08x\n", hr); hr = IAudioClock_GetPosition(acl, &pos, NULL); ok(hr == S_OK, "GetPosition failed: %08x\n", hr); ok(pos == 0, "GetPosition returned non-zero pos after Reset\n"); last = pos; hr = IAudioClient_Start(ac); ok(hr == S_OK, "Start failed: %08x\n", hr); Sleep(100); hr = IAudioClock_GetPosition(acl, &pos, NULL); ok(hr == S_OK, "GetPosition failed: %08x\n", hr); ok(pos > last, "Position should have been further along...\n"); hr = IAudioClient_Stop(ac); ok(hr == S_OK, "Stop failed: %08x\n", hr); hr = IAudioClock_GetPosition(acl, &pos, NULL); ok(hr == S_OK, "GetPosition failed: %08x\n", hr); ok(pos >= last, "Position should have been further along...\n"); IAudioClock_Release(acl); IAudioClient_Release(ac); }
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) { UINT prebuf_frames; REFERENCE_TIME prebuf_rt; WAVEFORMATEX *wfx = NULL; HRESULT hres; REFERENCE_TIME period; DWORD period_ms; TRACE("(%p, %d)\n", device, forcewave); if(device->client){ IAudioClient_Release(device->client); device->client = NULL; } if(device->render){ IAudioRenderClient_Release(device->render); device->render = NULL; } if(device->clock){ IAudioClock_Release(device->clock); device->clock = NULL; } if(device->volume){ IAudioStreamVolume_Release(device->volume); device->volume = NULL; } hres = IMMDevice_Activate(device->mmdevice, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void **)&device->client); if(FAILED(hres)) { WARN("Activate failed: %08x\n", hres); return hres; } hres = DSOUND_WaveFormat(device, device->client, forcewave, &wfx); if (FAILED(hres)) { IAudioClient_Release(device->client); device->client = NULL; return hres; } HeapFree(GetProcessHeap(), 0, device->pwfx); device->pwfx = wfx; prebuf_frames = device->prebuf * DSOUND_fraglen(device) / device->pwfx->nBlockAlign; prebuf_rt = (10000000 * (UINT64)prebuf_frames) / device->pwfx->nSamplesPerSec; hres = IAudioClient_Initialize(device->client, AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, prebuf_rt, 0, device->pwfx, NULL); if(FAILED(hres)){ IAudioClient_Release(device->client); device->client = NULL; WARN("Initialize failed: %08x\n", hres); return hres; } IAudioClient_SetEventHandle(device->client, device->sleepev); hres = IAudioClient_GetService(device->client, &IID_IAudioRenderClient, (void**)&device->render); if(FAILED(hres)){ IAudioClient_Release(device->client); device->client = NULL; WARN("GetService failed: %08x\n", hres); return hres; } hres = IAudioClient_GetService(device->client, &IID_IAudioClock, (void**)&device->clock); if(FAILED(hres)){ IAudioClient_Release(device->client); IAudioRenderClient_Release(device->render); device->client = NULL; device->render = NULL; WARN("GetService failed: %08x\n", hres); return hres; } hres = IAudioClient_GetService(device->client, &IID_IAudioStreamVolume, (void**)&device->volume); if(FAILED(hres)){ IAudioClient_Release(device->client); IAudioRenderClient_Release(device->render); IAudioClock_Release(device->clock); device->client = NULL; device->render = NULL; device->clock = NULL; WARN("GetService failed: %08x\n", hres); return hres; } /* Now kick off the timer so the event fires periodically */ hres = IAudioClient_Start(device->client); if (FAILED(hres)) WARN("starting failed with %08x\n", hres); hres = IAudioClient_GetStreamLatency(device->client, &period); if (FAILED(hres)) { WARN("GetStreamLatency failed with %08x\n", hres); period_ms = 10; } else period_ms = (period + 9999) / 10000; TRACE("period %u ms fraglen %u prebuf %u\n", period_ms, device->fraglen, device->prebuf); if (period_ms < 3) device->sleeptime = 5; else device->sleeptime = period_ms * 5 / 2; return S_OK; }