dsound: Use smaller buffers for wavein capture.
This commit is contained in:
parent
290869b03d
commit
3bafbb22b8
|
@ -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,6 @@ HRESULT WINAPI IDirectSoundCaptureImpl_Initialize(
|
|||
WARN("already initialized\n");
|
||||
return DSERR_ALREADYINITIALIZED;
|
||||
}
|
||||
|
||||
return DirectSoundCaptureDevice_Initialize(&This->device, lpcGUID);
|
||||
}
|
||||
|
||||
|
@ -895,28 +917,18 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition(
|
|||
if (hres != DS_OK)
|
||||
WARN("IDsCaptureDriverBuffer_GetPosition failed\n");
|
||||
} else if (This->device->hwi) {
|
||||
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;
|
||||
}
|
||||
DWORD pos;
|
||||
|
||||
EnterCriticalSection(&(This->device->lock));
|
||||
if (lpdwReadPosition) {
|
||||
if (This->device->state == STATE_STARTING) {
|
||||
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)
|
||||
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));
|
||||
*lpdwCapturePosition = pos;
|
||||
|
||||
if (lpdwReadPosition)
|
||||
*lpdwReadPosition = (This->device->pwave[This->device->index].dwBufferLength + pos) % This->device->buflen;
|
||||
LeaveCriticalSection(&This->device->lock);
|
||||
|
||||
if (lpdwCapturePosition) TRACE("*lpdwCapturePosition=%d\n",*lpdwCapturePosition);
|
||||
if (lpdwReadPosition) TRACE("*lpdwReadPosition=%d\n",*lpdwReadPosition);
|
||||
} else {
|
||||
|
@ -1122,99 +1134,47 @@ IDirectSoundCaptureBufferImpl_Start(
|
|||
DirectSoundCaptureDevice *device = This->device;
|
||||
|
||||
if (device->buffer) {
|
||||
if (This->nrofnotifies) {
|
||||
int c;
|
||||
|
||||
device->nrofpwaves = This->nrofnotifies;
|
||||
TRACE("nrofnotifies=%d\n", This->nrofnotifies);
|
||||
DWORD blocksize = DSOUND_fraglen(device->pwfx->nSamplesPerSec, device->pwfx->nBlockAlign);
|
||||
device->nrofpwaves = device->buflen / blocksize + !!(device->buflen % blocksize);
|
||||
TRACE("nrofpwaves=%d\n", device->nrofpwaves);
|
||||
|
||||
/* prepare headers */
|
||||
if (device->pwave)
|
||||
device->pwave = HeapReAlloc(GetProcessHeap(),0,device->pwave,
|
||||
device->nrofpwaves*sizeof(WAVEHDR));
|
||||
device->pwave = HeapReAlloc(GetProcessHeap(), 0,device->pwave, device->nrofpwaves*sizeof(WAVEHDR));
|
||||
else
|
||||
device->pwave = HeapAlloc(GetProcessHeap(),0,
|
||||
device->nrofpwaves*sizeof(WAVEHDR));
|
||||
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;
|
||||
}
|
||||
for (c = 0; c < device->nrofpwaves; ++c) {
|
||||
device->pwave[c].lpData = (char *)device->buffer + c * blocksize;
|
||||
device->pwave[c].dwBufferLength = blocksize;
|
||||
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)));
|
||||
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));
|
||||
waveInUnprepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR));
|
||||
break;
|
||||
}
|
||||
|
||||
hres = mmErr(waveInAddBuffer(device->hwi,
|
||||
&(device->pwave[c]), sizeof(WAVEHDR)));
|
||||
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));
|
||||
waveInUnprepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (device->buflen % blocksize)
|
||||
device->pwave[device->nrofpwaves - 1].dwBufferLength = device->buflen % blocksize;
|
||||
|
||||
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)));
|
||||
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));
|
||||
}
|
||||
}
|
||||
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 +1260,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;
|
||||
}
|
||||
|
|
|
@ -253,7 +253,6 @@ struct DirectSoundCaptureDevice
|
|||
/* more stuff */
|
||||
LPBYTE buffer;
|
||||
DWORD buflen;
|
||||
DWORD read_position;
|
||||
|
||||
PWAVEFORMATEX pwfx;
|
||||
|
||||
|
@ -420,6 +419,7 @@ HRESULT DSOUND_Create8(REFIID riid, LPDIRECTSOUND8 *ppDS);
|
|||
|
||||
/* primary.c */
|
||||
|
||||
DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign);
|
||||
HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device);
|
||||
HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device);
|
||||
HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device);
|
||||
|
|
|
@ -36,36 +36,44 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
|
||||
|
||||
static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
|
||||
/** Calculate how long a fragment length of about 10 ms should be in frames
|
||||
*
|
||||
* nSamplesPerSec: Frequency rate in samples per second
|
||||
* nBlockAlign: Size of a single blockalign
|
||||
*
|
||||
* Returns:
|
||||
* Size in bytes of a single fragment
|
||||
*/
|
||||
DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign)
|
||||
{
|
||||
DWORD nBlockAlign;
|
||||
DWORD fraglen;
|
||||
TRACE("(%p)\n", device);
|
||||
|
||||
nBlockAlign = device->pwfx->nBlockAlign;
|
||||
/* Alsa doesn't have continuous buffers, instead it has buffers with power of 2,
|
||||
* If DS_TIME_DEL is about 10 ms, 512 * nBlockAlign is roughly correct */
|
||||
fraglen = 512 * nBlockAlign;
|
||||
DWORD fraglen = 512 * nBlockAlign;
|
||||
|
||||
/* Compensate for only being roughly accurate */
|
||||
if (device->pwfx->nSamplesPerSec <= 26000)
|
||||
if (nSamplesPerSec <= 26000)
|
||||
fraglen /= 2;
|
||||
|
||||
if (device->pwfx->nSamplesPerSec <= 12000)
|
||||
if (nSamplesPerSec <= 12000)
|
||||
fraglen /= 2;
|
||||
|
||||
if (device->pwfx->nSamplesPerSec >= 80000)
|
||||
if (nSamplesPerSec >= 80000)
|
||||
fraglen *= 2;
|
||||
|
||||
device->fraglen = fraglen;
|
||||
device->helfrags = device->buflen / fraglen;
|
||||
return fraglen;
|
||||
}
|
||||
|
||||
static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
|
||||
{
|
||||
TRACE("(%p)\n", device);
|
||||
|
||||
device->fraglen = DSOUND_fraglen(device->pwfx->nSamplesPerSec, device->pwfx->nBlockAlign);
|
||||
device->helfrags = device->buflen / device->fraglen;
|
||||
TRACE("fraglen=%d helfrags=%d\n", device->fraglen, device->helfrags);
|
||||
|
||||
if (device->hwbuf && device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD)
|
||||
device->writelead = 0;
|
||||
else
|
||||
/* calculate the 10ms write lead */
|
||||
device->writelead = (device->pwfx->nSamplesPerSec / 100) * nBlockAlign;
|
||||
device->writelead = (device->pwfx->nSamplesPerSec / 100) * device->pwfx->nBlockAlign;
|
||||
}
|
||||
|
||||
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
|
||||
|
|
Loading…
Reference in New Issue