Author: akhaldi Date: Mon Jan 27 11:38:02 2014 New Revision: 61851
URL: http://svn.reactos.org/svn/reactos?rev=61851&view=rev Log: [DSOUND] * Revert r60474 until Johannes has time to look into it.
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 Jan 27 11:38:02 2014 @@ -5,6 +5,7 @@ -D__WINESRC__)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) + spec2def(dsound.dll dsound.spec ADD_IMPORTLIB)
add_library(dsound SHARED @@ -24,5 +25,5 @@
set_module_type(dsound win32dll) target_link_libraries(dsound dxguid uuid wine) -add_importlibs(dsound ole32 advapi32 user32 msvcrt kernel32 ntdll) +add_importlibs(dsound winmm 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 Jan 27 11:38:02 2014 @@ -43,8 +43,6 @@ /* IDirectSoundNotify fields */ DSBPOSITIONNOTIFY *notifies; int nrofnotifies; - HANDLE thread; - HANDLE sleepev; } IDirectSoundCaptureBufferImpl;
/* DirectSoundCaptureDevice implementation structure */ @@ -58,6 +56,7 @@ WAVEFORMATEX *pwfx; IDirectSoundCaptureBufferImpl *capture_buffer; DWORD state; + UINT timerID; CRITICAL_SECTION lock; IMMDevice *mmdevice; IAudioClient *client; @@ -65,19 +64,11 @@ 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);
@@ -732,8 +723,8 @@ }
err = IAudioClient_Initialize(device->client, - AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, - 200 * 100000, 0, device->pwfx, NULL); + AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST, + 200 * 100000, 50000, device->pwfx, NULL); if(FAILED(err)){ WARN("Initialize failed: %08x\n", err); IAudioClient_Release(device->client); @@ -746,27 +737,12 @@ 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 ); @@ -784,7 +760,6 @@ 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 ); @@ -792,7 +767,6 @@ } device->buffer = newbuf; device->buflen = buflen; - This->thread = CreateThread(NULL, 0, DSOUND_capture_thread, This, 0, NULL); }
IDirectSoundCaptureBuffer_AddRef(&This->IDirectSoundCaptureBuffer8_iface); @@ -839,6 +813,9 @@
if (!ref) { TRACE("deleting object\n"); + + timeKillEvent(device->timerID); + timeEndPeriod(DS_TIME_RES);
EnterCriticalSection(&DSOUND_capturers_lock); list_remove(&device->entry); @@ -858,19 +835,29 @@ return ref; }
-static HRESULT DSOUND_capture_data(DirectSoundCaptureDevice *device) -{ - HRESULT hr; - UINT32 packet_frames, packet_bytes, avail_bytes, skip_bytes = 0; +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; DWORD flags; BYTE *buf; - - if(!device->capture_buffer || device->state == STATE_STOPPED) - return S_FALSE; + HRESULT hr; + + if(!device->ref) + return; + + EnterCriticalSection(&device->lock); + + if(!device->capture_buffer || device->state == STATE_STOPPED){ + LeaveCriticalSection(&device->lock); + return; + }
if(device->state == STATE_STOPPING){ device->state = STATE_STOPPED; - return S_FALSE; + LeaveCriticalSection(&device->lock); + return; }
if(device->state == STATE_STARTING) @@ -879,28 +866,24 @@ hr = IAudioCaptureClient_GetBuffer(device->capture, &buf, &packet_frames, &flags, NULL, NULL); if(FAILED(hr)){ + LeaveCriticalSection(&device->lock); WARN("GetBuffer failed: %08x\n", hr); - return hr; + return; }
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 + skip_bytes, avail_bytes); + memcpy(device->buffer + device->write_pos_bytes, buf, 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 + skip_bytes + avail_bytes, packet_bytes); + memcpy(device->buffer, buf + avail_bytes, packet_bytes); capture_CheckNotify(device->capture_buffer, 0, packet_bytes); }else{ device->state = STATE_STOPPED; @@ -913,44 +896,12 @@
hr = IAudioCaptureClient_ReleaseBuffer(device->capture, packet_frames); if(FAILED(hr)){ + LeaveCriticalSection(&device->lock); WARN("ReleaseBuffer failed: %08x\n", hr); - 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; + return; + } + + LeaveCriticalSection(&device->lock); }
static struct _TestFormat { @@ -1014,6 +965,14 @@
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"); @@ -1047,6 +1006,8 @@ } } 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 Jan 27 11:38:02 2014 @@ -715,6 +715,30 @@ 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 Jan 27 11:38:02 2014 @@ -768,16 +768,20 @@
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: - if (lpvReserved) break; + TRACE("DLL_PROCESS_DETACH\n"); 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 Jan 27 11:38:02 2014 @@ -287,5 +287,6 @@
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 Jan 27 11:38:02 2014 @@ -425,24 +425,35 @@ return DS_OK; }
-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; +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; }
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passed_fmt) @@ -519,9 +530,27 @@ 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 { - HeapFree(GetProcessHeap(), 0, device->primary_pwfx); - device->primary_pwfx = DSOUND_CopyFormat(passed_fmt); + device->primary_pwfx = HeapReAlloc(GetProcessHeap(), 0, device->primary_pwfx, sizeof(*fmtex)); + memcpy(device->primary_pwfx, device->pwfx, sizeof(*fmtex)); }
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 Jan 27 11:38:02 2014 @@ -40,7 +40,7 @@ reactos/dll/directx/wine/dmusic # Synced to Wine-1.7.1 reactos/dll/directx/wine/dplay # Synced to Wine-1.7.1 reactos/dll/directx/wine/dplayx # Synced to Wine-1.7.1 -reactos/dll/directx/wine/dsound # Synced to Wine-1.7.1 +reactos/dll/directx/wine/dsound # Synced to Wine-1.5.26 reactos/dll/directx/wine/dxdiagn # Synced to Wine-1.7.1 reactos/dll/directx/wine/dxgi # Synced to Wine-1.7.1 reactos/dll/directx/wine/msdmo # Synced to Wine-1.7.1