Module: wine Branch: master Commit: 20356f7458334e777f98ce20e873c8070f78b160 URL: http://source.winehq.org/git/wine.git/?a=commit;h=20356f7458334e777f98ce20e8...
Author: Andrew Eikum aeikum@codeweavers.com Date: Mon May 14 15:20:02 2012 -0500
dsound: Compute mix buffer's size more accurately.
---
dlls/dsound/dsound_private.h | 4 +- dlls/dsound/mixer.c | 44 ++++++++--------------------------------- dlls/dsound/primary.c | 8 +----- 3 files changed, 13 insertions(+), 43 deletions(-)
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 375abac..26e59ff 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -94,7 +94,8 @@ struct DirectSoundDevice CRITICAL_SECTION mixlock; IDirectSoundBufferImpl *primary; DWORD speaker_config; - LPBYTE tmp_buffer, mix_buffer; + LPBYTE tmp_buffer; + float *mix_buffer; DWORD tmp_buffer_len, mix_buffer_len;
DSVOLUMEPAN volpan; @@ -294,7 +295,6 @@ LONG capped_refcount_dec(LONG *ref) DECLSPEC_HIDDEN; HRESULT DSOUND_FullDuplexCreate(REFIID riid, LPDIRECTSOUNDFULLDUPLEX* ppDSFD) DECLSPEC_HIDDEN;
/* mixer.c */ -DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice* device, DWORD pos) DECLSPEC_HIDDEN; void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len) DECLSPEC_HIDDEN; void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN; void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index a940a85..9d4b35b 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -96,19 +96,6 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) TRACE("Vol=%d Pan=%d\n", volpan->lVolume, volpan->lPan); }
-/** Convert a primary buffer position to a pointer position for device->mix_buffer - * device: DirectSoundDevice for which to calculate - * pos: Primary buffer position to converts - * Returns: Offset for mix_buffer - */ -DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice* device, DWORD pos) -{ - DWORD ret = pos * 32 / device->pwfx->wBitsPerSample; - if (device->pwfx->wBitsPerSample == 32) - ret *= 2; - return ret; -} - /** * Recalculate the size for temporary buffer, and new writelead * Should be called when one of the following things occur: @@ -480,7 +467,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO { INT len = fraglen; BYTE *ibuf, *volbuf; - DWORD oldpos, mixbufpos; + DWORD oldpos;
TRACE("sec_mixpos=%d/%d\n", dsb->sec_mixpos, dsb->buflen); TRACE("(%p,%d,%d)\n",dsb,writepos,fraglen); @@ -502,16 +489,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO if (volbuf) ibuf = volbuf;
- mixbufpos = DSOUND_bufpos_to_mixpos(dsb->device, writepos); - /* Now mix the temporary buffer into the devices main buffer */ - if ((writepos + len) <= dsb->device->buflen) - dsb->device->mixfunction(ibuf, dsb->device->mix_buffer + mixbufpos, len); - else - { - DWORD todo = dsb->device->buflen - writepos; - dsb->device->mixfunction(ibuf, dsb->device->mix_buffer + mixbufpos, todo); - dsb->device->mixfunction(ibuf + todo, dsb->device->mix_buffer, len - todo); - } + dsb->device->mixfunction(ibuf, dsb->device->mix_buffer, len);
/* check for notification positions */ if (dsb->dsbd.dwFlags & DSBCAPS_CTRLPOSITIONNOTIFY && @@ -754,7 +732,7 @@ static void DSOUND_PerformMix(DirectSoundDevice *device)
if (device->priolevel != DSSCL_WRITEPRIMARY) { BOOL recover = FALSE, all_stopped = FALSE; - DWORD playpos, writepos, writelead, maxq, prebuff_max, prebuff_left, size1, size2, mixplaypos, mixplaypos2; + DWORD playpos, writepos, writelead, maxq, prebuff_max, prebuff_left, size1, size2; LPVOID buf1, buf2; int nfiller;
@@ -771,9 +749,6 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) playpos,writepos,device->playpos,device->mixpos,device->buflen); assert(device->playpos < device->buflen);
- mixplaypos = DSOUND_bufpos_to_mixpos(device, device->playpos); - mixplaypos2 = DSOUND_bufpos_to_mixpos(device, playpos); - /* calc maximum prebuff */ prebuff_max = (device->prebuf * device->fraglen);
@@ -794,15 +769,12 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) /* reset mix position to write position */ device->mixpos = writepos;
- ZeroMemory(device->mix_buffer, device->mix_buffer_len); ZeroMemory(device->buffer, device->buflen); } else if (playpos < device->playpos) { buf1 = device->buffer + device->playpos; buf2 = device->buffer; size1 = device->buflen - device->playpos; size2 = playpos; - FillMemory(device->mix_buffer + mixplaypos, device->mix_buffer_len - mixplaypos, 0); - FillMemory(device->mix_buffer, mixplaypos2, 0); FillMemory(buf1, size1, nfiller); if (playpos && (!buf2 || !size2)) FIXME("%d: (%d, %d)=>(%d, %d) There should be an additional buffer here!!\n", __LINE__, device->playpos, device->mixpos, playpos, writepos); @@ -812,7 +784,6 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) buf2 = NULL; size1 = playpos - device->playpos; size2 = 0; - FillMemory(device->mix_buffer + mixplaypos, mixplaypos2 - mixplaypos, 0); FillMemory(buf1, size1, nfiller); } device->playpos = playpos; @@ -823,17 +794,20 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) TRACE("prebuff_left = %d, prebuff_max = %dx%d=%d, writelead=%d\n", prebuff_left, device->prebuf, device->fraglen, prebuff_max, writelead);
+ ZeroMemory(device->mix_buffer, device->mix_buffer_len); + /* do the mixing */ DSOUND_MixToPrimary(device, writepos, maxq, recover, &all_stopped);
if (maxq + writepos > device->buflen) { DWORD todo = device->buflen - writepos; - device->normfunction(device->mix_buffer + DSOUND_bufpos_to_mixpos(device, writepos), device->buffer + writepos, todo); - device->normfunction(device->mix_buffer, device->buffer, maxq - todo); + DWORD offs_float = (todo / device->pwfx->nBlockAlign) * device->pwfx->nChannels; + device->normfunction(device->mix_buffer, device->buffer + writepos, todo); + device->normfunction(device->mix_buffer + offs_float, device->buffer, maxq - todo); } else - device->normfunction(device->mix_buffer + DSOUND_bufpos_to_mixpos(device, writepos), device->buffer + writepos, maxq); + device->normfunction(device->mix_buffer, device->buffer + writepos, maxq);
/* update the mix position, taking wrap-around into account */ device->mixpos = writepos + maxq; diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index ff79a70..6633124 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -159,8 +159,8 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
device->helfrags = device->buflen / device->fraglen;
- device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen); - device->mix_buffer = HeapAlloc(GetProcessHeap(), 0, device->mix_buffer_len); + device->mix_buffer_len = ((device->prebuf * device->fraglen) / (device->pwfx->wBitsPerSample / 8)) * sizeof(float); + device->mix_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, device->mix_buffer_len); if (!device->mix_buffer) return DSERR_OUTOFMEMORY;
@@ -512,10 +512,6 @@ opened: WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err); }
- device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen); - device->mix_buffer = HeapReAlloc(GetProcessHeap(), 0, device->mix_buffer, device->mix_buffer_len); - FillMemory(device->mix_buffer, device->mix_buffer_len, 0); - if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT || (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE && IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat,