Commit 3f1498fc authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

Fixes more use before set races.

Work around for queue reordering feature. Stop recording on reset. Better debug info. Dsound callback capture state fix.
parent 136fa03f
......@@ -81,6 +81,13 @@ static ICOM_VTABLE(IDirectSoundFullDuplex) dsfdvt;
static IDirectSoundCaptureImpl* dsound_capture = NULL;
static const char * captureStateString[] = {
"STATE_STOPPED",
"STATE_STARTING",
"STATE_CAPTURING",
"STATE_STOPPING"
};
/***************************************************************************
* DirectSoundCaptureCreate [DSOUND.6]
*
......@@ -314,7 +321,8 @@ DSOUND_capture_callback(
if (msg == MM_WIM_DATA) {
EnterCriticalSection( &(This->lock) );
TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%ld, old This->index=%d\n",This->state,This->index);
TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%s, old This->index=%d\n",
captureStateString[This->state],This->index);
if (This->state != STATE_STOPPED) {
int index = This->index;
if (This->state == STATE_STARTING) {
......@@ -337,10 +345,14 @@ DSOUND_capture_callback(
if (This->state == STATE_CAPTURING) {
waveInPrepareHeader(hwi,&(This->pwave[index]),sizeof(WAVEHDR));
waveInAddBuffer(hwi, &(This->pwave[index]), sizeof(WAVEHDR));
}
} else if (This->state == STATE_STOPPING) {
TRACE("stopping\n");
This->state = STATE_STOPPED;
}
}
}
TRACE("DirectSoundCapture new This->state=%ld, new This->index=%d\n",This->state,This->index);
TRACE("DirectSoundCapture new This->state=%s, new This->index=%d\n",
captureStateString[This->state],This->index);
LeaveCriticalSection( &(This->lock) );
}
......@@ -408,15 +420,15 @@ IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface )
if ( uRef == 0 ) {
TRACE("deleting object\n");
if (This->capture_buffer)
IDirectSoundCaptureBufferImpl_Release(
(LPDIRECTSOUNDCAPTUREBUFFER8) This->capture_buffer);
if (This->driver) {
IDsCaptureDriver_Close(This->driver);
IDsCaptureDriver_Release(This->driver);
}
if (This->capture_buffer)
IDirectSoundCaptureBufferImpl_Release(
(LPDIRECTSOUNDCAPTUREBUFFER8) This->capture_buffer);
if (This->pwfx)
HeapFree(GetProcessHeap(), 0, This->pwfx);
......@@ -1094,7 +1106,7 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition(
}
} else if (This->dsound->hwi) {
EnterCriticalSection(&(This->dsound->lock));
TRACE("old This->dsound->state=%ld\n",This->dsound->state);
TRACE("old This->dsound->state=%s\n",captureStateString[This->dsound->state]);
if (lpdwCapturePosition) {
MMTIME mtime;
mtime.wType = TIME_BYTES;
......@@ -1113,7 +1125,7 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition(
}
*lpdwReadPosition = This->dsound->read_position;
}
TRACE("new This->dsound->state=%ld\n",This->dsound->state);
TRACE("new This->dsound->state=%s\n",captureStateString[This->dsound->state]);
LeaveCriticalSection(&(This->dsound->lock));
if (lpdwCapturePosition) TRACE("*lpdwCapturePosition=%ld\n",*lpdwCapturePosition);
if (lpdwReadPosition) TRACE("*lpdwReadPosition=%ld\n",*lpdwReadPosition);
......@@ -1193,14 +1205,16 @@ IDirectSoundCaptureBufferImpl_GetStatus(
*lpdwStatus = 0;
EnterCriticalSection(&(This->dsound->lock));
TRACE("old This->dsound->state=%ld, old lpdwStatus=%08lx\n",This->dsound->state,*lpdwStatus);
TRACE("old This->dsound->state=%s, old lpdwStatus=%08lx\n",
captureStateString[This->dsound->state],*lpdwStatus);
if ((This->dsound->state == STATE_STARTING) ||
(This->dsound->state == STATE_CAPTURING)) {
*lpdwStatus |= DSCBSTATUS_CAPTURING;
if (This->flags & DSCBSTART_LOOPING)
*lpdwStatus |= DSCBSTATUS_LOOPING;
}
TRACE("new This->dsound->state=%ld, new lpdwStatus=%08lx\n",This->dsound->state,*lpdwStatus);
TRACE("new This->dsound->state=%s, new lpdwStatus=%08lx\n",
captureStateString[This->dsound->state],*lpdwStatus);
LeaveCriticalSection(&(This->dsound->lock));
TRACE("status=%lx\n", *lpdwStatus);
......@@ -1318,12 +1332,12 @@ IDirectSoundCaptureBufferImpl_Start(
EnterCriticalSection(&(This->dsound->lock));
This->flags = dwFlags;
TRACE("old This->dsound->state=%ld\n",This->dsound->state);
TRACE("old This->dsound->state=%s\n",captureStateString[This->dsound->state]);
if (This->dsound->state == STATE_STOPPED)
This->dsound->state = STATE_STARTING;
else if (This->dsound->state == STATE_STOPPING)
This->dsound->state = STATE_CAPTURING;
TRACE("new This->dsound->state=%ld\n",This->dsound->state);
TRACE("new This->dsound->state=%s\n",captureStateString[This->dsound->state]);
LeaveCriticalSection(&(This->dsound->lock));
......@@ -1455,12 +1469,12 @@ IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
EnterCriticalSection(&(This->dsound->lock));
TRACE("old This->dsound->state=%ld\n",This->dsound->state);
TRACE("old This->dsound->state=%s\n",captureStateString[This->dsound->state]);
if (This->dsound->state == STATE_CAPTURING)
This->dsound->state = STATE_STOPPING;
else if (This->dsound->state == STATE_STARTING)
This->dsound->state = STATE_STOPPED;
TRACE("new This->dsound->state=%ld\n",This->dsound->state);
TRACE("new This->dsound->state=%s\n",captureStateString[This->dsound->state]);
LeaveCriticalSection(&(This->dsound->lock));
......
......@@ -1011,7 +1011,9 @@ static int OSS_PeekRingMessage(OSS_MSG_RING* omr,
*/
static DWORD wodNotifyClient(WINE_WAVEOUT* wwo, WORD wMsg, DWORD dwParam1, DWORD dwParam2)
{
TRACE("wMsg = 0x%04x dwParm1 = %04lX dwParam2 = %04lX\n", wMsg, dwParam1, dwParam2);
TRACE("wMsg = 0x%04x (%s) dwParm1 = %04lX dwParam2 = %04lX\n", wMsg,
wMsg == WOM_OPEN ? "WOM_OPEN" : wMsg == WOM_CLOSE ? "WOM_CLOSE" :
wMsg == WOM_DONE ? "WOM_DONE" : "Unknown", dwParam1, dwParam2);
switch (wMsg) {
case WOM_OPEN:
......@@ -1178,7 +1180,7 @@ static BOOL wodPlayer_WriteMaxFrags(WINE_WAVEOUT* wwo, DWORD* bytes)
}
*bytes -= written;
wwo->dwWrittenTotal += written;
TRACE("dwWrittenTotal=%lu\n", wwo->dwWrittenTotal);
return ret;
}
......@@ -2555,7 +2557,9 @@ static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid)
*/
static DWORD widNotifyClient(WINE_WAVEIN* wwi, WORD wMsg, DWORD dwParam1, DWORD dwParam2)
{
TRACE("wMsg = 0x%04x dwParm1 = %04lX dwParam2 = %04lX\n", wMsg, dwParam1, dwParam2);
TRACE("wMsg = 0x%04x (%s) dwParm1 = %04lX dwParam2 = %04lX\n", wMsg,
wMsg == WIM_OPEN ? "WIM_OPEN" : wMsg == WIM_CLOSE ? "WIM_CLOSE" :
wMsg == WIM_DATA ? "WIM_DATA" : "Unknown", dwParam1, dwParam2);
switch (wMsg) {
case WIM_OPEN:
......@@ -2595,6 +2599,34 @@ static DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPSA lpCaps, DWORD dwSize)
}
/**************************************************************************
* widRecorder_ReadHeaders [internal]
*/
static void widRecorder_ReadHeaders(WINE_WAVEIN * wwi)
{
enum win_wm_message tmp_msg;
DWORD tmp_param;
HANDLE tmp_ev;
WAVEHDR* lpWaveHdr;
while (OSS_RetrieveRingMessage(&wwi->msgRing, &tmp_msg, &tmp_param, &tmp_ev)) {
if (tmp_msg == WINE_WM_HEADER) {
LPWAVEHDR* wh;
lpWaveHdr = (LPWAVEHDR)tmp_param;
lpWaveHdr->lpNext = 0;
if (wwi->lpQueuePtr == 0)
wwi->lpQueuePtr = lpWaveHdr;
else {
for (wh = &(wwi->lpQueuePtr); *wh; wh = &((*wh)->lpNext));
*wh = lpWaveHdr;
}
} else {
ERR("should only have headers left\n");
}
}
}
/**************************************************************************
* widRecorder [internal]
*/
static DWORD CALLBACK widRecorder(LPVOID pmt)
......@@ -2677,8 +2709,9 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
lpWaveHdr->dwFlags |= WHDR_DONE;
wwi->lpQueuePtr = lpNext;
widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
lpWaveHdr = wwi->lpQueuePtr = lpNext;
lpWaveHdr = lpNext;
}
}
}
......@@ -2816,6 +2849,10 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", wwi->ossdev->dev_name, strerror(errno));
}
}
/* read any headers in queue */
widRecorder_ReadHeaders(wwi);
/* return current buffer to app */
lpWaveHdr = wwi->lpQueuePtr;
if (lpWaveHdr)
......@@ -2824,24 +2861,42 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
TRACE("stop %p %p\n", lpWaveHdr, lpWaveHdr->lpNext);
lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
lpWaveHdr->dwFlags |= WHDR_DONE;
widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
wwi->lpQueuePtr = lpNext;
widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
}
}
wwi->state = WINE_WS_STOPPED;
SetEvent(ev);
break;
case WINE_WM_RESETTING:
if (wwi->state != WINE_WS_STOPPED)
{
if (wwi->ossdev->bTriggerSupport)
{
/* stop the recording */
wwi->ossdev->bInputEnabled = FALSE;
enable = getEnables(wwi->ossdev);
if (ioctl(wwi->ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
wwi->ossdev->bInputEnabled = FALSE;
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", wwi->ossdev->dev_name, strerror(errno));
}
}
}
wwi->state = WINE_WS_STOPPED;
wwi->dwTotalRecorded = 0;
/* read any headers in queue */
widRecorder_ReadHeaders(wwi);
/* return all buffers to the app */
for (lpWaveHdr = wwi->lpQueuePtr; lpWaveHdr; lpWaveHdr = lpWaveHdr->lpNext) {
TRACE("reset %p %p\n", lpWaveHdr, lpWaveHdr->lpNext);
lpWaveHdr->dwFlags &= ~WHDR_INQUEUE;
lpWaveHdr->dwFlags |= WHDR_DONE;
wwi->lpQueuePtr = lpWaveHdr->lpNext;
widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0);
}
wwi->lpQueuePtr = NULL;
SetEvent(ev);
break;
......@@ -2978,6 +3033,7 @@ static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
}
wwi->dwFragmentSize = fragment_size;
TRACE("dwFragmentSize=%lu\n", wwi->dwFragmentSize);
TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%lu, nSamplesPerSec=%lu, nChannels=%u nBlockAlign=%u!\n",
wwi->format.wBitsPerSample, wwi->format.wf.nAvgBytesPerSec,
wwi->format.wf.nSamplesPerSec, wwi->format.wf.nChannels,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment