Andrew Eikum : dsound: Compute mix buffer's size more accurately.
Alexandre Julliard
julliard at winehq.org
Tue May 15 12:55:58 CDT 2012
Module: wine
Branch: master
Commit: 20356f7458334e777f98ce20e873c8070f78b160
URL: http://source.winehq.org/git/wine.git/?a=commit;h=20356f7458334e777f98ce20e873c8070f78b160
Author: Andrew Eikum <aeikum at 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,
More information about the wine-cvs
mailing list