UINT32 latency;
HANDLE hThread;
DWORD threadId;
+ CRITICAL_SECTION cs;
};
static BOOL rdpsnd_winmm_convert_format(const AUDIO_FORMAT* in, WAVEFORMATEX* out)
static DWORD WINAPI waveOutProc(LPVOID lpParameter)
{
MSG msg;
+ rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*)lpParameter;
while (GetMessage(&msg, NULL, 0, 0))
{
if (msg.message == MM_WOM_CLOSE)
{
/* free buffer */
LPWAVEHDR waveHdr = (LPWAVEHDR)msg.lParam;
+ EnterCriticalSection(&winmm->cs);
waveOutUnprepareHeader((HWAVEOUT)msg.wParam, waveHdr, sizeof(WAVEHDR));
+ LeaveCriticalSection(&winmm->cs);
free(waveHdr->lpData);
free(waveHdr);
}
if (!rdpsnd_winmm_set_format(device, format, latency))
return FALSE;
- winmm->hThread = CreateThread(NULL, 0, waveOutProc, NULL, 0, &winmm->threadId);
+ winmm->hThread = CreateThread(NULL, 0, waveOutProc, winmm, 0, &winmm->threadId);
if (!winmm->hThread)
{
WLog_Print(winmm->log, WLOG_ERROR, "CreateThread failed: %" PRIu32 "", GetLastError());
if (winmm->hWaveOut)
{
+ EnterCriticalSection(&winmm->cs);
+
mmResult = waveOutReset(winmm->hWaveOut);
if (mmResult != MMSYSERR_NOERROR)
WLog_Print(winmm->log, WLOG_ERROR, "waveOutReset failure: %" PRIu32 "", mmResult);
if (mmResult != MMSYSERR_NOERROR)
WLog_Print(winmm->log, WLOG_ERROR, "waveOutClose failure: %" PRIu32 "", mmResult);
+ LeaveCriticalSection(&winmm->cs);
+
winmm->hWaveOut = NULL;
}
if (winmm)
{
rdpsnd_winmm_close(device);
+ DeleteCriticalSection(&winmm->cs);
free(winmm);
}
}
memcpy(lpWaveHdr->lpData, data, size);
lpWaveHdr->dwBufferLength = (DWORD)size;
+ EnterCriticalSection(&winmm->cs);
+
mmResult = waveOutPrepareHeader(winmm->hWaveOut, lpWaveHdr, sizeof(WAVEHDR));
if (mmResult != MMSYSERR_NOERROR)
{
WLog_Print(winmm->log, WLOG_ERROR, "waveOutPrepareHeader failure: %" PRIu32 "", mmResult);
- goto fail;
+ goto failCS;
}
mmResult = waveOutWrite(winmm->hWaveOut, lpWaveHdr, sizeof(WAVEHDR));
{
WLog_Print(winmm->log, WLOG_ERROR, "waveOutWrite failure: %" PRIu32 "", mmResult);
waveOutUnprepareHeader(winmm->hWaveOut, lpWaveHdr, sizeof(WAVEHDR));
- goto fail;
+ goto failCS;
}
+ LeaveCriticalSection(&winmm->cs);
return winmm->latency;
+failCS:
+ LeaveCriticalSection(&winmm->cs);
fail:
if (lpWaveHdr)
free(lpWaveHdr->lpData);
winmm->device.Close = rdpsnd_winmm_close;
winmm->device.Free = rdpsnd_winmm_free;
winmm->log = WLog_Get(TAG);
+ InitializeCriticalSection(&winmm->cs);
args = pEntryPoints->args;
rdpsnd_winmm_parse_addin_args((rdpsndDevicePlugin*)winmm, args);