Module: wine Branch: master Commit: 09890d7142a2c612b025ab9ff60358d036f9999b URL: http://source.winehq.org/git/wine.git/?a=commit;h=09890d7142a2c612b025ab9ff6...
Author: Maarten Lankhorst wine@mblankhorst.nl Date: Thu May 12 08:43:44 2016 -0500
dsound: Mix float natively.
Signed-off-by: Andrew Eikum aeikum@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/dsound/dsound.c | 1 - dlls/dsound/dsound_convert.c | 20 +---------------- dlls/dsound/dsound_private.h | 4 ++-- dlls/dsound/mixer.c | 53 ++++++++++++++++++++++++-------------------- dlls/dsound/primary.c | 14 +----------- 5 files changed, 33 insertions(+), 59 deletions(-)
diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c index 2d145a6..0b5c3b4 100644 --- a/dlls/dsound/dsound.c +++ b/dlls/dsound/dsound.c @@ -238,7 +238,6 @@ static ULONG DirectSoundDevice_Release(DirectSoundDevice * device) IAudioStreamVolume_Release(device->volume);
HeapFree(GetProcessHeap(), 0, device->tmp_buffer); - HeapFree(GetProcessHeap(), 0, device->mix_buffer); HeapFree(GetProcessHeap(), 0, device->buffer); RtlDeleteResource(&device->buffer_list_lock); device->mixlock.DebugInfo->Spare[0] = 0; diff --git a/dlls/dsound/dsound_convert.c b/dlls/dsound/dsound_convert.c index 5accba6..4ae83ba 100644 --- a/dlls/dsound/dsound_convert.c +++ b/dlls/dsound/dsound_convert.c @@ -263,27 +263,9 @@ static void norm32(float *src, INT *dst, unsigned len) } }
-static void normieee32(float *src, float *dst, unsigned len) -{ - TRACE("%p - %p %d\n", src, dst, len); - len /= 4; - while (len--) - { - if(*src > 1) - *dst = 1; - else if(*src < -1) - *dst = -1; - else - *dst = *src; - ++dst; - ++src; - } -} - -const normfunc normfunctions[5] = { +const normfunc normfunctions[4] = { (normfunc)norm8, (normfunc)norm16, (normfunc)norm24, (normfunc)norm32, - (normfunc)normieee32 }; diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 918839e..b980453 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -49,7 +49,7 @@ extern const bitsgetfunc getbpp[5] DECLSPEC_HIDDEN; void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN; void mixieee32(float *src, float *dst, unsigned samples) DECLSPEC_HIDDEN; typedef void (*normfunc)(const void *, void *, unsigned); -extern const normfunc normfunctions[5] DECLSPEC_HIDDEN; +extern const normfunc normfunctions[4] DECLSPEC_HIDDEN;
typedef struct _DSVOLUMEPAN { @@ -87,7 +87,7 @@ struct DirectSoundDevice int speaker_num[DS_MAX_CHANNELS]; int num_speakers; int lfe_channel; - float *mix_buffer, *tmp_buffer; + float *tmp_buffer; DWORD tmp_buffer_len, mix_buffer_len;
DSVOLUMEPAN volpan; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 6ac4e3d..dec8ffd 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -468,7 +468,7 @@ static void DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT frames) * writepos = position (offset) in device buffer to write at * fraglen = number of bytes to mix */ -static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD fraglen) +static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, float *mix_buffer, DWORD writepos, DWORD fraglen) { INT len = fraglen; float *ibuf; @@ -493,7 +493,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO /* Apply volume if needed */ DSOUND_MixerVol(dsb, frames);
- mixieee32(ibuf, dsb->device->mix_buffer, frames * dsb->device->pwfx->nChannels); + mixieee32(ibuf, mix_buffer, frames * dsb->device->pwfx->nChannels);
/* check for notification positions */ if (dsb->dsbd.dwFlags & DSBCAPS_CTRLPOSITIONNOTIFY && @@ -517,7 +517,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO * * Returns: the number of bytes beyond the writepos that were mixed. */ -static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen) +static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, float *mix_buffer, DWORD writepos, DWORD mixlen) { DWORD primary_done = 0;
@@ -544,7 +544,7 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mi /* First try to mix to the end of the buffer if possible * Theoretically it would allow for better optimization */ - primary_done += DSOUND_MixInBuffer(dsb, writepos, mixlen); + primary_done += DSOUND_MixInBuffer(dsb, mix_buffer, writepos, mixlen);
TRACE("total mixed data=%d\n", primary_done);
@@ -559,14 +559,12 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mi * writepos = the current safe-to-write position in the primary buffer * mixlen = the maximum amount to mix into the primary buffer * (beyond the current writepos) - * recover = true if the sound device may have been reset and the write - * position in the device buffer changed * all_stopped = reports back if all buffers have stopped * * Returns: the length beyond the writepos that was mixed to. */
-static void DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos, DWORD mixlen, BOOL recover, BOOL *all_stopped) +static void DSOUND_MixToPrimary(const DirectSoundDevice *device, float *mix_buffer, DWORD writepos, DWORD mixlen, BOOL *all_stopped) { INT i; IDirectSoundBufferImpl *dsb; @@ -574,7 +572,7 @@ static void DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos, /* unless we find a running buffer, all have stopped */ *all_stopped = TRUE;
- TRACE("(%d,%d,%d)\n", writepos, mixlen, recover); + TRACE("(%d,%d)\n", writepos, mixlen); for (i = 0; i < device->nrofbuffers; i++) { dsb = device->buffers[i];
@@ -594,7 +592,7 @@ static void DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos, dsb->state = STATE_PLAYING;
/* mix next buffer into the main buffer */ - DSOUND_MixOne(dsb, writepos, mixlen); + DSOUND_MixOne(dsb, mix_buffer, writepos, mixlen);
*all_stopped = FALSE; } @@ -646,8 +644,7 @@ done: * secondary->buffer (secondary format) * =[Resample]=> device->tmp_buffer (float format) * =[Volume]=> device->tmp_buffer (float format) - * =[Mix]=> device->mix_buffer (float format) - * =[Reformat]=> device->buffer (device format) + * =[Reformat]=> device->buffer (device format, skipped on float) */ static void DSOUND_PerformMix(DirectSoundDevice *device) { @@ -686,7 +683,7 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) if (device->priolevel != DSSCL_WRITEPRIMARY) { BOOL all_stopped = FALSE; int nfiller; - DWORD bpp = device->pwfx->wBitsPerSample>>3; + void *buffer = NULL;
/* the sound of silence */ nfiller = device->pwfx->wBitsPerSample == 8 ? 128 : 0; @@ -700,24 +697,32 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) TRACE("Buffer restarting\n"); }
- memset(device->mix_buffer, nfiller, maxq); + hr = IAudioRenderClient_GetBuffer(device->render, maxq / block, (void*)&buffer); + if(FAILED(hr)){ + WARN("GetBuffer failed: %08x\n", hr); + LeaveCriticalSection(&device->mixlock); + return; + }
- /* do the mixing */ - DSOUND_MixToPrimary(device, writepos, maxq, TRUE, &all_stopped); + memset(buffer, nfiller, maxq);
- if (maxq + writepos > device->buflen) { - DWORD todo = device->buflen - writepos; + if (!device->normfunction) + DSOUND_MixToPrimary(device, buffer, writepos, maxq, &all_stopped); + else { + memset(device->buffer, nfiller, device->buflen);
- device->normfunction(device->mix_buffer, device->buffer + writepos, todo); - DSOUND_WaveQueue(device, device->buffer + writepos, todo); + /* do the mixing */ + DSOUND_MixToPrimary(device, (float*)device->buffer, writepos, maxq, &all_stopped);
- device->normfunction(device->mix_buffer + todo / bpp, device->buffer, (maxq - todo)); - DSOUND_WaveQueue(device, device->buffer, maxq - todo); - } else { - device->normfunction(device->mix_buffer, device->buffer + writepos, maxq); - DSOUND_WaveQueue(device, device->buffer + writepos, maxq); + device->normfunction(device->buffer, buffer, maxq); }
+ hr = IAudioRenderClient_ReleaseBuffer(device->render, maxq / block, 0); + if(FAILED(hr)) + ERR("ReleaseBuffer failed: %08x\n", hr); + + device->pad += maxq; + if (maxq) { if (device->state == STATE_STARTING || device->state == STATE_STOPPED) { diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index bdab0ee..1925d0c 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -338,11 +338,7 @@ HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) device->buflen = ds_hel_buflen; device->buflen -= device->buflen % device->pwfx->nBlockAlign;
- HeapFree(GetProcessHeap(), 0, device->mix_buffer); device->mix_buffer_len = (device->buflen / (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;
if (device->state == STATE_PLAYING) device->state = STATE_STARTING; else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED; @@ -370,21 +366,13 @@ HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE && IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))) - device->normfunction = normfunctions[4]; + device->normfunction = NULL; else device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0); - FillMemory(device->mix_buffer, device->mix_buffer_len, 0); device->playpos = 0;
- if (device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT || - (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE && - IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))) - device->normfunction = normfunctions[4]; - else - device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1]; - for (i = 0; i < device->nrofbuffers; i++) { RtlAcquireResourceExclusive(&dsb[i]->lock, TRUE); DSOUND_RecalcFormat(dsb[i]);