[PATCH] dsound: Use smaller buffers for waveout capture
Maarten Lankhorst
maarten at codeweavers.com
Fri Sep 28 18:54:03 CDT 2007
---
dlls/dsound/capture.c | 199 +++++++++++++++++-------------------------
dlls/dsound/dsound_private.h | 1 -
2 files changed, 80 insertions(+), 120 deletions(-)
diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c
index 684495d..280ece0 100644
--- a/dlls/dsound/capture.c
+++ b/dlls/dsound/capture.c
@@ -384,6 +384,31 @@ DirectSoundCaptureEnumerateW(
return DS_OK;
}
+static void capture_CheckNotify(IDirectSoundCaptureBufferImpl *This, DWORD from, DWORD len)
+{
+ unsigned i;
+ for (i = 0; i < This->nrofnotifies; ++i) {
+ LPDSBPOSITIONNOTIFY event = This->notifies + i;
+ DWORD offset = event->dwOffset;
+ TRACE("checking %d, position %d, event = %p\n", i, offset, event->hEventNotify);
+
+ if (offset == DSBPN_OFFSETSTOP) {
+ if (!from && !len) {
+ SetEvent(event->hEventNotify);
+ TRACE("signalled event %p (%d)\n", event->hEventNotify, i);
+ return;
+ }
+ else return;
+ }
+
+ if (offset >= from && offset < (from + len))
+ {
+ TRACE("signalled event %p (%d)\n", event->hEventNotify, i);
+ SetEvent(event->hEventNotify);
+ }
+ }
+}
+
static void CALLBACK
DSOUND_capture_callback(
HWAVEIN hwi,
@@ -393,27 +418,25 @@ DSOUND_capture_callback(
DWORD dw2 )
{
DirectSoundCaptureDevice * This = (DirectSoundCaptureDevice*)dwUser;
+ IDirectSoundCaptureBufferImpl * Moi = (IDirectSoundCaptureBufferImpl*) This->capture_buffer;
TRACE("(%p,%08x(%s),%08x,%08x,%08x) entering at %d\n",hwi,msg,
msg == MM_WIM_OPEN ? "MM_WIM_OPEN" : msg == MM_WIM_CLOSE ? "MM_WIM_CLOSE" :
msg == MM_WIM_DATA ? "MM_WIM_DATA" : "UNKNOWN",dwUser,dw1,dw2,GetTickCount());
if (msg == MM_WIM_DATA) {
- LPWAVEHDR pHdr = (LPWAVEHDR)dw1;
EnterCriticalSection( &(This->lock) );
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) {
- This->read_position = pHdr->dwBytesRecorded;
+ if (This->state == STATE_STARTING)
This->state = STATE_CAPTURING;
- }
- if (This->capture_buffer->nrofnotifies)
- SetEvent(This->capture_buffer->notifies[This->index].hEventNotify);
- This->index = (This->index + 1) % This->nrofpwaves;
+ capture_CheckNotify(Moi, (DWORD_PTR)This->pwave[index].lpData - (DWORD_PTR)This->buffer, This->pwave[index].dwBufferLength);
+ This->index = (++This->index) % This->nrofpwaves;
if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) {
TRACE("end of buffer\n");
This->state = STATE_STOPPED;
+ capture_CheckNotify(Moi, 0, 0);
} else {
if (This->state == STATE_CAPTURING) {
waveInAddBuffer(hwi, &(This->pwave[index]), sizeof(WAVEHDR));
@@ -574,7 +597,11 @@ HRESULT WINAPI IDirectSoundCaptureImpl_Initialize(
WARN("already initialized\n");
return DSERR_ALREADYINITIALIZED;
}
-
+#if 0
+ WARN("Horrible hack to work around sound bug..\n");
+ if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
+ return DSERR_NODRIVER;
+#endif
return DirectSoundCaptureDevice_Initialize(&This->device, lpcGUID);
}
@@ -895,28 +922,18 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition(
if (hres != DS_OK)
WARN("IDsCaptureDriverBuffer_GetPosition failed\n");
} else if (This->device->hwi) {
+ DWORD pos;
+
+ EnterCriticalSection(&This->device->lock);
+ pos = (DWORD_PTR)This->device->pwave[This->device->index].lpData - (DWORD_PTR)This->device->buffer;
TRACE("old This->device->state=%s\n",captureStateString[This->device->state]);
- if (lpdwCapturePosition) {
- MMTIME mtime;
- mtime.wType = TIME_BYTES;
- waveInGetPosition(This->device->hwi, &mtime, sizeof(mtime));
- TRACE("mtime.u.cb=%d,This->device->buflen=%d\n", mtime.u.cb,
- This->device->buflen);
- mtime.u.cb = mtime.u.cb % This->device->buflen;
- *lpdwCapturePosition = mtime.u.cb;
- }
+ if (lpdwCapturePosition)
+ *lpdwCapturePosition = pos;
+
+ if (lpdwReadPosition)
+ *lpdwReadPosition = (This->device->pwave[This->device->index].dwBufferLength + pos) % This->device->buflen;
+ LeaveCriticalSection(&This->device->lock);
- EnterCriticalSection(&(This->device->lock));
- if (lpdwReadPosition) {
- if (This->device->state == STATE_STARTING) {
- if (lpdwCapturePosition)
- This->device->read_position = *lpdwCapturePosition;
- This->device->state = STATE_CAPTURING;
- }
- *lpdwReadPosition = This->device->read_position;
- }
- TRACE("new This->device->state=%s\n",captureStateString[This->device->state]);
- LeaveCriticalSection(&(This->device->lock));
if (lpdwCapturePosition) TRACE("*lpdwCapturePosition=%d\n",*lpdwCapturePosition);
if (lpdwReadPosition) TRACE("*lpdwReadPosition=%d\n",*lpdwReadPosition);
} else {
@@ -1122,99 +1139,46 @@ IDirectSoundCaptureBufferImpl_Start(
DirectSoundCaptureDevice *device = This->device;
if (device->buffer) {
- if (This->nrofnotifies) {
- int c;
-
- device->nrofpwaves = This->nrofnotifies;
- TRACE("nrofnotifies=%d\n", This->nrofnotifies);
-
- /* prepare headers */
- if (device->pwave)
- device->pwave = HeapReAlloc(GetProcessHeap(),0,device->pwave,
- device->nrofpwaves*sizeof(WAVEHDR));
- else
- device->pwave = HeapAlloc(GetProcessHeap(),0,
- device->nrofpwaves*sizeof(WAVEHDR));
-
- for (c = 0; c < device->nrofpwaves; c++) {
- if (This->notifies[c].dwOffset == DSBPN_OFFSETSTOP) {
- TRACE("got DSBPN_OFFSETSTOP\n");
- device->nrofpwaves = c;
- break;
- }
- if (c == 0) {
- device->pwave[0].lpData = (LPSTR)device->buffer;
- device->pwave[0].dwBufferLength =
- This->notifies[0].dwOffset + 1;
- } else {
- device->pwave[c].lpData = (LPSTR)device->buffer +
- This->notifies[c-1].dwOffset + 1;
- device->pwave[c].dwBufferLength =
- This->notifies[c].dwOffset -
- This->notifies[c-1].dwOffset;
- }
- device->pwave[c].dwBytesRecorded = 0;
- device->pwave[c].dwUser = (DWORD)device;
- device->pwave[c].dwFlags = 0;
- device->pwave[c].dwLoops = 0;
- hres = mmErr(waveInPrepareHeader(device->hwi,
- &(device->pwave[c]),sizeof(WAVEHDR)));
- if (hres != DS_OK) {
- WARN("waveInPrepareHeader failed\n");
- while (c--)
- waveInUnprepareHeader(device->hwi,
- &(device->pwave[c]),sizeof(WAVEHDR));
- break;
- }
-
- hres = mmErr(waveInAddBuffer(device->hwi,
- &(device->pwave[c]), sizeof(WAVEHDR)));
- if (hres != DS_OK) {
- WARN("waveInAddBuffer failed\n");
- while (c--)
- waveInUnprepareHeader(device->hwi,
- &(device->pwave[c]),sizeof(WAVEHDR));
- break;
- }
+ int c;
+ device->nrofpwaves = device->buflen / 2048 + !!(device->buflen % 2048);
+ TRACE("nrofpwaves=%d\n", device->nrofpwaves);
+
+ /* prepare headers */
+ if (device->pwave)
+ device->pwave = HeapReAlloc(GetProcessHeap(), 0,device->pwave, device->nrofpwaves*sizeof(WAVEHDR));
+ else
+ device->pwave = HeapAlloc(GetProcessHeap(), 0, device->nrofpwaves*sizeof(WAVEHDR));
+
+ for (c = 0; c < device->nrofpwaves; ++c) {
+ device->pwave[c].lpData = (char *)device->buffer + c * 2048;
+ device->pwave[c].dwBufferLength = 2048;
+ device->pwave[c].dwBytesRecorded = 0;
+ device->pwave[c].dwUser = (DWORD)device;
+ device->pwave[c].dwFlags = 0;
+ device->pwave[c].dwLoops = 0;
+ hres = mmErr(waveInPrepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR)));
+ if (hres != DS_OK) {
+ WARN("waveInPrepareHeader failed\n");
+ while (c--)
+ waveInUnprepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR));
+ break;
}
- FillMemory(device->buffer, device->buflen,
- (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
- } else {
- TRACE("no notifiers specified\n");
- /* no notifiers specified so just create a single default header */
- device->nrofpwaves = 1;
- if (device->pwave)
- device->pwave = HeapReAlloc(GetProcessHeap(),0,device->pwave,sizeof(WAVEHDR));
- else
- device->pwave = HeapAlloc(GetProcessHeap(),0,sizeof(WAVEHDR));
-
- device->pwave[0].lpData = (LPSTR)device->buffer;
- device->pwave[0].dwBufferLength = device->buflen;
- device->pwave[0].dwBytesRecorded = 0;
- device->pwave[0].dwUser = (DWORD)device;
- device->pwave[0].dwFlags = 0;
- device->pwave[0].dwLoops = 0;
-
- hres = mmErr(waveInPrepareHeader(device->hwi,
- &(device->pwave[0]),sizeof(WAVEHDR)));
+ hres = mmErr(waveInAddBuffer(device->hwi, &(device->pwave[c]), sizeof(WAVEHDR)));
if (hres != DS_OK) {
- WARN("waveInPrepareHeader failed\n");
- waveInUnprepareHeader(device->hwi,
- &(device->pwave[0]),sizeof(WAVEHDR));
- }
- hres = mmErr(waveInAddBuffer(device->hwi,
- &(device->pwave[0]), sizeof(WAVEHDR)));
- if (hres != DS_OK) {
- WARN("waveInAddBuffer failed\n");
- waveInUnprepareHeader(device->hwi,
- &(device->pwave[0]),sizeof(WAVEHDR));
- }
- }
+ WARN("waveInAddBuffer failed\n");
+ while (c--)
+ waveInUnprepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR));
+ break;
+ }
+ }
+ if (device->buflen % 2048)
+ device->pwave[device->nrofpwaves - 1].dwBufferLength = device->buflen % 2048;
+
+ FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
}
device->index = 0;
- device->read_position = 0;
if (hres == DS_OK) {
/* start filling the first buffer */
@@ -1300,10 +1264,7 @@ IDirectSoundCaptureBufferImpl_Unlock(
dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2);
if (hres != DS_OK)
WARN("IDsCaptureDriverBuffer_Unlock failed\n");
- } else if (This->device->hwi) {
- This->device->read_position = (This->device->read_position +
- (dwAudioBytes1 + dwAudioBytes2)) % This->device->buflen;
- } else {
+ } else if (!This->device->hwi) {
WARN("invalid call\n");
hres = DSERR_INVALIDCALL;
}
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index dc21a62..78d2c76 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -253,7 +253,6 @@ struct DirectSoundCaptureDevice
/* more stuff */
LPBYTE buffer;
DWORD buflen;
- DWORD read_position;
PWAVEFORMATEX pwfx;
--
1.5.2.5
--------------010505080001060106040606--
More information about the wine-patches
mailing list