Module: wine Branch: master Commit: f393a98a8a6cbb585101ac0338723151a6e135c1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f393a98a8a6cbb585101ac0338...
Author: Andrew Eikum aeikum@codeweavers.com Date: Tue May 1 15:01:06 2012 -0500
dsound: Convert from fixed to floating point.
---
dlls/dsound/buffer.c | 4 +- dlls/dsound/dsound_private.h | 7 ++--- dlls/dsound/mixer.c | 47 ++++++++++++++++++++++------------------- dlls/dsound/primary.c | 2 +- 4 files changed, 31 insertions(+), 29 deletions(-)
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index 630d60e..376fff3 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -252,7 +252,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *i oldFreq = This->freq; This->freq = freq; if (freq != oldFreq) { - This->freqAdjust = ((DWORD64)This->freq << DSOUND_FREQSHIFT) / This->device->pwfx->nSamplesPerSec; + This->freqAdjust = This->freq / (float)This->device->pwfx->nSamplesPerSec; This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign; DSOUND_RecalcFormat(This); } @@ -912,7 +912,7 @@ HRESULT IDirectSoundBufferImpl_Create( dsb->buf_mixpos = dsb->sec_mixpos = 0; dsb->state = STATE_STOPPED;
- dsb->freqAdjust = ((DWORD64)dsb->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec; + dsb->freqAdjust = dsb->freq / (float)device->pwfx->nSamplesPerSec; dsb->nAvgBytesPerSec = dsb->freq * dsbd->lpwfxFormat->nBlockAlign;
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 5d1d62a..7577610 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -182,7 +182,8 @@ struct IDirectSoundBufferImpl DSVOLUMEPAN volpan; DSBUFFERDESC dsbd; /* used for frequency conversion (PerfectPitch) */ - ULONG freqneeded, freqAdjust, freqAcc, freqAccNext; + ULONG freqneeded; + float freqAcc, freqAccNext, freqAdjust; /* used for mixing */ DWORD primary_mixpos, buf_mixpos, sec_mixpos; /* IDirectSoundNotify fields */ @@ -296,7 +297,7 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN; void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN; void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN; -DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, DWORD* overshot) DECLSPEC_HIDDEN; +DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, float *overshot) DECLSPEC_HIDDEN;
void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) DECLSPEC_HIDDEN;
@@ -315,8 +316,6 @@ HRESULT DSOUND_CaptureCreate8(REFIID riid, LPDIRECTSOUNDCAPTURE8 *ppDSC8) DECLSP #define STATE_CAPTURING 2 #define STATE_STOPPING 3
-#define DSOUND_FREQSHIFT (20) - extern CRITICAL_SECTION DSOUND_renderers_lock DECLSPEC_HIDDEN; extern CRITICAL_SECTION DSOUND_capturers_lock DECLSPEC_HIDDEN; extern struct list DSOUND_capturers DECLSPEC_HIDDEN; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 5fa15b2..dddd1e3 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -115,23 +115,21 @@ DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice* device, DWORD pos) * secmixpos is used to decide which freqAcc is needed * overshot tells what the 'actual' secpos is now (optional) */ -DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, DWORD* overshot) +DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, float* overshot) { DWORD64 framelen = secpos / dsb->pwfx->nBlockAlign; - DWORD64 freqAdjust = dsb->freqAdjust; - DWORD64 acc, freqAcc; + float acc, freqAcc;
if (secpos < secmixpos) freqAcc = dsb->freqAccNext; - else freqAcc = dsb->freqAcc; - acc = (framelen << DSOUND_FREQSHIFT) + (freqAdjust - 1 - freqAcc); - acc /= freqAdjust; + else + freqAcc = dsb->freqAcc; + acc = ceil((framelen - freqAcc) / dsb->freqAdjust); if (overshot) { - DWORD64 oshot = acc * freqAdjust + freqAcc; - assert(oshot >= framelen << DSOUND_FREQSHIFT); - oshot -= framelen << DSOUND_FREQSHIFT; - *overshot = (DWORD)oshot; + *overshot = acc * dsb->freqAdjust + freqAcc; + assert(*overshot >= framelen); + *overshot -= framelen; assert(*overshot < dsb->freqAdjust); } return (DWORD)acc * dsb->device->pwfx->nBlockAlign; @@ -146,8 +144,7 @@ static DWORD DSOUND_bufpos_to_secpos(const IDirectSoundBufferImpl *dsb, DWORD bu DWORD64 acc;
framelen = bufpos/oAdv; - acc = framelen * (DWORD64)dsb->freqAdjust + (DWORD64)dsb->freqAcc; - acc = acc >> DSOUND_FREQSHIFT; + acc = ((DWORD64)framelen) * dsb->freqAdjust + dsb->freqAcc; pos = (DWORD)acc * iAdv; if (pos >= dsb->buflen) { /* FIXME: can this happen at all? */ @@ -167,7 +164,7 @@ static void DSOUND_RecalcFreqAcc(IDirectSoundBufferImpl *dsb) if (!dsb->freqneeded) return; dsb->freqAcc = dsb->freqAccNext; dsb->tmp_buffer_len = DSOUND_secpos_to_bufpos(dsb, dsb->buflen, 0, &dsb->freqAccNext); - TRACE("New freqadjust: %04x, new buflen: %d\n", dsb->freqAccNext, dsb->tmp_buffer_len); + TRACE("New freqadjust: %f, new buflen: %d\n", dsb->freqAccNext, dsb->tmp_buffer_len); }
/** @@ -298,27 +295,33 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len } }
+static inline float get_current_sample(const IDirectSoundBufferImpl *dsb, + DWORD mixpos, DWORD channel) +{ + if (mixpos >= dsb->buflen && !(dsb->playflags & DSBPLAY_LOOPING)) + return 0.0f; + return dsb->get(dsb, mixpos % dsb->buflen, channel); +} + /** * Copy frames from the given input buffer to the given output buffer. * Translate 8 <-> 16 bits and mono <-> stereo */ static inline void cp_fields(const IDirectSoundBufferImpl *dsb, - UINT ostride, UINT count, UINT freqAcc) + UINT ostride, UINT count, float freqAcc) { DWORD ipos = dsb->sec_mixpos; UINT istride = dsb->pwfx->nBlockAlign; - UINT adj = dsb->freqAdjust; - ULONG adv; DWORD opos = 0;
while (count-- > 0) { DWORD channel; for (channel = 0; channel < dsb->mix_channels; channel++) - dsb->put(dsb, opos, channel, dsb->get(dsb, ipos, channel)); - freqAcc += adj; - adv = (freqAcc >> DSOUND_FREQSHIFT); - freqAcc &= (1 << DSOUND_FREQSHIFT) - 1; - ipos += adv * istride; + dsb->put(dsb, opos, channel, + get_current_sample(dsb, ipos, channel)); + freqAcc += dsb->freqAdjust; + ipos += ((DWORD)freqAcc) * istride; + freqAcc -= truncf(freqAcc); opos += ostride; } } @@ -355,7 +358,7 @@ static void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD tmp_l { INT oAdvance = dsb->device->pwfx->nBlockAlign; INT size = tmp_len / oAdvance; - DWORD freqAcc; + float freqAcc;
if (dsb->device->tmp_buffer_len < tmp_len || !dsb->device->tmp_buffer) { diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index 4851ac2..c39da8a 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -535,7 +535,7 @@ opened: /* **** */ RtlAcquireResourceExclusive(&(*dsb)->lock, TRUE);
- (*dsb)->freqAdjust = ((DWORD64)(*dsb)->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec; + (*dsb)->freqAdjust = (*dsb)->freq / (float)device->pwfx->nSamplesPerSec; DSOUND_RecalcFormat((*dsb)); (*dsb)->primary_mixpos = 0;