Author: akhaldi Date: Mon Sep 30 11:38:41 2013 New Revision: 60474
URL: http://svn.reactos.org/svn/reactos?rev=60474&view=rev Log: [DSOUND] * Sync with Wine 1.7.1. CORE-7469
Modified: trunk/reactos/dll/directx/wine/dsound/CMakeLists.txt trunk/reactos/dll/directx/wine/dsound/capture.c trunk/reactos/dll/directx/wine/dsound/dsound.c trunk/reactos/dll/directx/wine/dsound/dsound_main.c trunk/reactos/dll/directx/wine/dsound/dsound_private.h trunk/reactos/dll/directx/wine/dsound/primary.c trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/directx/wine/dsound/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dsound/CMa... ============================================================================== --- trunk/reactos/dll/directx/wine/dsound/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dsound/CMakeLists.txt [iso-8859-1] Mon Sep 30 11:38:41 2013 @@ -5,7 +5,6 @@ -D__WINESRC__)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) - spec2def(dsound.dll dsound.spec ADD_IMPORTLIB)
add_library(dsound SHARED @@ -19,10 +18,9 @@ primary.c propset.c sound3d.c - version.rc ${CMAKE_CURRENT_BINARY_DIR}/dsound.def)
-set_module_type(dsound win32dll) +set_module_type(dsound win32dll version.rc) target_link_libraries(dsound dxguid uuid wine) -add_importlibs(dsound winmm ole32 advapi32 user32 msvcrt kernel32 ntdll) +add_importlibs(dsound ole32 advapi32 user32 msvcrt kernel32 ntdll) add_cd_file(TARGET dsound DESTINATION reactos/system32 FOR all)
Modified: trunk/reactos/dll/directx/wine/dsound/capture.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dsound/cap... ============================================================================== --- trunk/reactos/dll/directx/wine/dsound/capture.c [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dsound/capture.c [iso-8859-1] Mon Sep 30 11:38:41 2013 @@ -62,6 +62,8 @@ /* IDirectSoundNotify fields */ DSBPOSITIONNOTIFY *notifies; int nrofnotifies; + HANDLE thread; + HANDLE sleepev; } IDirectSoundCaptureBufferImpl;
/* DirectSoundCaptureDevice implementation structure */ @@ -75,7 +77,6 @@ WAVEFORMATEX *pwfx; IDirectSoundCaptureBufferImpl *capture_buffer; DWORD state; - UINT timerID; CRITICAL_SECTION lock; IMMDevice *mmdevice; IAudioClient *client; @@ -83,11 +84,19 @@ struct list entry; };
+static DWORD WINAPI DSOUND_capture_thread(void *user);
static void capturebuffer_destroy(IDirectSoundCaptureBufferImpl *This) { if (This->device->state == STATE_CAPTURING) This->device->state = STATE_STOPPING; + + if(This->thread){ + SetEvent(This->sleepev); + WaitForSingleObject(This->thread, INFINITE); + CloseHandle(This->thread); + } + CloseHandle(This->sleepev);
HeapFree(GetProcessHeap(),0, This->pdscbd);
@@ -742,8 +751,8 @@ }
err = IAudioClient_Initialize(device->client, - AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST, - 200 * 100000, 50000, device->pwfx, NULL); + AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, + 200 * 100000, 0, device->pwfx, NULL); if(FAILED(err)){ WARN("Initialize failed: %08x\n", err); IAudioClient_Release(device->client); @@ -756,12 +765,27 @@ return err; }
+ This->sleepev = CreateEventW(NULL, 0, 0, NULL); + + err = IAudioClient_SetEventHandle(device->client, This->sleepev); + if(FAILED(err)){ + WARN("SetEventHandle failed: %08x\n", err); + IAudioClient_Release(device->client); + device->client = NULL; + CloseHandle(This->sleepev); + HeapFree(GetProcessHeap(), 0, This->pdscbd); + This->device->capture_buffer = 0; + HeapFree( GetProcessHeap(), 0, This ); + return err; + } + err = IAudioClient_GetService(device->client, &IID_IAudioCaptureClient, (void**)&device->capture); if(FAILED(err)){ WARN("GetService failed: %08x\n", err); IAudioClient_Release(device->client); device->client = NULL; + CloseHandle(This->sleepev); HeapFree(GetProcessHeap(), 0, This->pdscbd); This->device->capture_buffer = 0; HeapFree( GetProcessHeap(), 0, This ); @@ -779,6 +803,7 @@ device->client = NULL; IAudioCaptureClient_Release(device->capture); device->capture = NULL; + CloseHandle(This->sleepev); HeapFree(GetProcessHeap(), 0, This->pdscbd); This->device->capture_buffer = 0; HeapFree( GetProcessHeap(), 0, This ); @@ -786,6 +811,7 @@ } device->buffer = newbuf; device->buflen = buflen; + This->thread = CreateThread(NULL, 0, DSOUND_capture_thread, This, 0, NULL); }
IDirectSoundCaptureBuffer_AddRef(&This->IDirectSoundCaptureBuffer8_iface); @@ -832,9 +858,6 @@
if (!ref) { TRACE("deleting object\n"); - - timeKillEvent(device->timerID); - timeEndPeriod(DS_TIME_RES);
EnterCriticalSection(&DSOUND_capturers_lock); list_remove(&device->entry); @@ -854,29 +877,19 @@ return ref; }
-static void CALLBACK DSOUND_capture_timer(UINT timerID, UINT msg, DWORD_PTR user, - DWORD_PTR dw1, DWORD_PTR dw2) -{ - DirectSoundCaptureDevice *device = (DirectSoundCaptureDevice*)user; - UINT32 packet_frames, packet_bytes, avail_bytes; +static HRESULT DSOUND_capture_data(DirectSoundCaptureDevice *device) +{ + HRESULT hr; + UINT32 packet_frames, packet_bytes, avail_bytes, skip_bytes = 0; DWORD flags; BYTE *buf; - HRESULT hr; - - if(!device->ref) - return; - - EnterCriticalSection(&device->lock); - - if(!device->capture_buffer || device->state == STATE_STOPPED){ - LeaveCriticalSection(&device->lock); - return; - } + + if(!device->capture_buffer || device->state == STATE_STOPPED) + return S_FALSE;
if(device->state == STATE_STOPPING){ device->state = STATE_STOPPED; - LeaveCriticalSection(&device->lock); - return; + return S_FALSE; }
if(device->state == STATE_STARTING) @@ -885,24 +898,28 @@ hr = IAudioCaptureClient_GetBuffer(device->capture, &buf, &packet_frames, &flags, NULL, NULL); if(FAILED(hr)){ - LeaveCriticalSection(&device->lock); WARN("GetBuffer failed: %08x\n", hr); - return; + return hr; }
packet_bytes = packet_frames * device->pwfx->nBlockAlign; + if(packet_bytes > device->buflen){ + TRACE("audio glitch: dsound buffer too small for data\n"); + skip_bytes = packet_bytes - device->buflen; + packet_bytes = device->buflen; + }
avail_bytes = device->buflen - device->write_pos_bytes; if(avail_bytes > packet_bytes) avail_bytes = packet_bytes;
- memcpy(device->buffer + device->write_pos_bytes, buf, avail_bytes); + memcpy(device->buffer + device->write_pos_bytes, buf + skip_bytes, avail_bytes); capture_CheckNotify(device->capture_buffer, device->write_pos_bytes, avail_bytes);
packet_bytes -= avail_bytes; if(packet_bytes > 0){ if(device->capture_buffer->flags & DSCBSTART_LOOPING){ - memcpy(device->buffer, buf + avail_bytes, packet_bytes); + memcpy(device->buffer, buf + skip_bytes + avail_bytes, packet_bytes); capture_CheckNotify(device->capture_buffer, 0, packet_bytes); }else{ device->state = STATE_STOPPED; @@ -915,12 +932,44 @@
hr = IAudioCaptureClient_ReleaseBuffer(device->capture, packet_frames); if(FAILED(hr)){ - LeaveCriticalSection(&device->lock); WARN("ReleaseBuffer failed: %08x\n", hr); - return; - } - - LeaveCriticalSection(&device->lock); + return hr; + } + + return S_OK; +} + +static DWORD WINAPI DSOUND_capture_thread(void *user) +{ + IDirectSoundCaptureBufferImpl *buffer = user; + HRESULT hr; + DWORD ret, wait_ms; + REFERENCE_TIME period; + + hr = IAudioClient_GetDevicePeriod(buffer->device->client, &period, NULL); + if(FAILED(hr)){ + WARN("GetDevicePeriod failed: %08x\n", hr); + wait_ms = 5; + }else + wait_ms = MulDiv(5, period, 10000); + + while(buffer->ref){ + ret = WaitForSingleObject(buffer->sleepev, wait_ms); + + if(!buffer->device->ref) + break; + + if(ret == WAIT_OBJECT_0){ + EnterCriticalSection(&buffer->device->lock); + + DSOUND_capture_data(buffer->device); + + LeaveCriticalSection(&buffer->device->lock); + }else if(ret != WAIT_TIMEOUT) + WARN("WaitForSingleObject failed: %u\n", GetLastError()); + } + + return 0; }
static struct _TestFormat { @@ -984,14 +1033,6 @@
EnterCriticalSection(&DSOUND_capturers_lock);
- LIST_FOR_EACH_ENTRY(device, &DSOUND_capturers, DirectSoundCaptureDevice, entry){ - if(IsEqualGUID(&device->guid, &devGUID)){ - IMMDevice_Release(mmdevice); - LeaveCriticalSection(&DSOUND_capturers_lock); - return DSERR_ALLOCATED; - } - } - hr = DirectSoundCaptureDevice_Create(&device); if (hr != DS_OK) { WARN("DirectSoundCaptureDevice_Create failed\n"); @@ -1025,8 +1066,6 @@ } } IAudioClient_Release(client); - - device->timerID = DSOUND_create_timer(DSOUND_capture_timer, (DWORD_PTR)device);
list_add_tail(&DSOUND_capturers, &device->entry);
Modified: trunk/reactos/dll/directx/wine/dsound/dsound.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dsound/dso... ============================================================================== --- trunk/reactos/dll/directx/wine/dsound/dsound.c [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dsound/dsound.c [iso-8859-1] Mon Sep 30 11:38:41 2013 @@ -738,30 +738,6 @@ return hr == S_OK; }
-UINT DSOUND_create_timer(LPTIMECALLBACK cb, DWORD_PTR user) -{ - UINT triggertime = DS_TIME_DEL, res = DS_TIME_RES, id; - TIMECAPS time; - - timeGetDevCaps(&time, sizeof(TIMECAPS)); - TRACE("Minimum timer resolution: %u, max timer: %u\n", time.wPeriodMin, time.wPeriodMax); - if (triggertime < time.wPeriodMin) - triggertime = time.wPeriodMin; - if (res < time.wPeriodMin) - res = time.wPeriodMin; - if (timeBeginPeriod(res) == TIMERR_NOCANDO) - WARN("Could not set minimum resolution, don't expect sound\n"); - id = timeSetEvent(triggertime, res, cb, user, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS); - if (!id) - { - WARN("Timer not created! Retrying without TIME_KILL_SYNCHRONOUS\n"); - id = timeSetEvent(triggertime, res, cb, user, TIME_PERIODIC); - if (!id) - ERR("Could not create timer, sound playback will not occur\n"); - } - return id; -} - HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGUID lpcGUID) { HRESULT hr = DS_OK;
Modified: trunk/reactos/dll/directx/wine/dsound/dsound_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dsound/dso... ============================================================================== --- trunk/reactos/dll/directx/wine/dsound/dsound_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dsound/dsound_main.c [iso-8859-1] Mon Sep 30 11:38:41 2013 @@ -800,20 +800,16 @@
switch (fdwReason) { case DLL_PROCESS_ATTACH: - TRACE("DLL_PROCESS_ATTACH\n"); instance = hInstDLL; DisableThreadLibraryCalls(hInstDLL); /* Increase refcount on dsound by 1 */ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)hInstDLL, &hInstDLL); break; case DLL_PROCESS_DETACH: - TRACE("DLL_PROCESS_DETACH\n"); + if (lpvReserved) break; DeleteCriticalSection(&DSOUND_renderers_lock); DeleteCriticalSection(&DSOUND_capturers_lock); break; - default: - TRACE("UNKNOWN REASON\n"); - break; } return TRUE; }
Modified: trunk/reactos/dll/directx/wine/dsound/dsound_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dsound/dso... ============================================================================== --- trunk/reactos/dll/directx/wine/dsound/dsound_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dsound/dsound_private.h [iso-8859-1] Mon Sep 30 11:38:41 2013 @@ -261,6 +261,5 @@
BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate, DWORD depth, WORD channels) DECLSPEC_HIDDEN; -UINT DSOUND_create_timer(LPTIMECALLBACK cb, DWORD_PTR user) DECLSPEC_HIDDEN; HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids, LPDSENUMCALLBACKW cb, void *user) DECLSPEC_HIDDEN;
Modified: trunk/reactos/dll/directx/wine/dsound/primary.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/wine/dsound/pri... ============================================================================== --- trunk/reactos/dll/directx/wine/dsound/primary.c [iso-8859-1] (original) +++ trunk/reactos/dll/directx/wine/dsound/primary.c [iso-8859-1] Mon Sep 30 11:38:41 2013 @@ -443,35 +443,24 @@ return DS_OK; }
-static DWORD DSOUND_GetFormatSize(LPCWAVEFORMATEX wfex) -{ - if (wfex->wFormatTag == WAVE_FORMAT_PCM) - return sizeof(WAVEFORMATEX); - else - return 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; +WAVEFORMATEX *DSOUND_CopyFormat(const WAVEFORMATEX *wfex) +{ + 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); + } + + 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) @@ -548,27 +537,9 @@ 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:
Modified: trunk/reactos/media/doc/README.WINE URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=6... ============================================================================== --- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original) +++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Mon Sep 30 11:38:41 2013 @@ -39,7 +39,7 @@ reactos/dll/directx/wine/dmusic # Synced to Wine-1.5.26 reactos/dll/directx/wine/dplay # Synced to Wine-1.5.26 reactos/dll/directx/wine/dplayx # Synced to Wine-1.5.26 -reactos/dll/directx/wine/dsound # Synced to Wine-1.5.26 +reactos/dll/directx/wine/dsound # Synced to Wine-1.7.1 reactos/dll/directx/wine/dxdiagn # Synced to Wine-0_9_5 reactos/dll/directx/wine/dxgi # Synced to Wine-1.7.1 reactos/dll/directx/wine/msdmo # Autosync