Module: wine Branch: master Commit: 88dd3b4f6e4ed10413b8d93055801a6e60fbc5e8 URL: http://source.winehq.org/git/wine.git/?a=commit;h=88dd3b4f6e4ed10413b8d93055...
Author: Andrew Eikum aeikum@codeweavers.com Date: Thu May 19 09:11:13 2016 -0500
dsound: Support downmixing 5.1 to stereo.
Signed-off-by: Andrew Eikum aeikum@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/dsound/dsound_convert.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ dlls/dsound/dsound_private.h | 2 ++ dlls/dsound/mixer.c | 8 ++++++++ 3 files changed, 56 insertions(+)
diff --git a/dlls/dsound/dsound_convert.c b/dlls/dsound/dsound_convert.c index 4ae83ba..3b4d2e5 100644 --- a/dlls/dsound/dsound_convert.c +++ b/dlls/dsound/dsound_convert.c @@ -157,6 +157,13 @@ void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, floa *fbuf = value; }
+void putieee32_sum(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +{ + BYTE *buf = (BYTE *)dsb->device->tmp_buffer; + float *fbuf = (float*)(buf + pos + sizeof(float) * channel); + *fbuf += value; +} + void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) { dsb->put_aux(dsb, pos, 0, value); @@ -206,6 +213,45 @@ void put_stereo2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD c } }
+void put_surround512stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) +{ + /* based on pulseaudio's downmix algorithm */ + switch(channel){ + + case 4: /* back left */ + value *= 0.056f; /* (1/9) / (sum of left volumes) */ + dsb->put_aux(dsb, pos, 0, value); + break; + + case 0: /* front left */ + value *= 0.503; /* 1 / (sum of left volumes) */ + dsb->put_aux(dsb, pos, 0, value); + break; + + case 5: /* back right */ + value *= 0.056f; /* (1/9) / (sum of right volumes) */ + dsb->put_aux(dsb, pos, 1, value); + break; + + case 1: /* front right */ + value *= 0.503f; /* 1 / (sum of right volumes) */ + dsb->put_aux(dsb, pos, 1, value); + break; + + case 2: /* front centre */ + value *= 0.252f; /* 0.5 / (sum of left/right volumes) */ + dsb->put_aux(dsb, pos, 0, value); + dsb->put_aux(dsb, pos, 1, value); + break; + + case 3: /* LFE */ + value *= 0.189f; /* 0.375 / (sum of left/right volumes) */ + dsb->put_aux(dsb, pos, 0, value); + dsb->put_aux(dsb, pos, 1, value); + break; + } +} + void mixieee32(float *src, float *dst, unsigned samples) { TRACE("%p - %p %d\n", src, dst, samples); diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index d063046..49e98ba 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -47,6 +47,7 @@ typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD); typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD, float); extern const bitsgetfunc getbpp[5] DECLSPEC_HIDDEN; void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN; +void putieee32_sum(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[4] DECLSPEC_HIDDEN; @@ -177,6 +178,7 @@ void put_mono2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, void put_stereo2quad(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN; void put_mono2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN; void put_stereo2surround51(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN; +void put_surround512stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
HRESULT secondarybuffer_create(DirectSoundDevice *device, const DSBUFFERDESC *dsbd, IDirectSoundBuffer **buffer) DECLSPEC_HIDDEN; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 217d4ce..4f05ee2 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -173,6 +173,12 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) dsb->mix_channels = 2; dsb->put = put_stereo2surround51; } + else if (ichannels == 6 && ochannels == 2) + { + dsb->mix_channels = 6; + dsb->put = put_surround512stereo; + dsb->put_aux = putieee32_sum; + } else { if (ichannels > 2) @@ -495,6 +501,8 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, float *mix_buffer, /* Resample buffer to temporary buffer specifically allocated for this purpose, if needed */ oldpos = dsb->sec_mixpos;
+ if(dsb->put_aux == putieee32_sum) + memset(dsb->device->tmp_buffer, 0, dsb->device->tmp_buffer_len); DSOUND_MixToTemporary(dsb, frames); ibuf = dsb->device->tmp_buffer;