>From 3adcc1cf4fc8b22b7f9a9000df0ad1a3341e3769 Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Thu, 15 Dec 2011 11:51:38 -0600 Subject: [PATCH 6/9] dsound: convert from fixed to floating point --- dlls/dsound/buffer.c | 4 ++-- dlls/dsound/dsound_private.h | 7 +++---- dlls/dsound/mixer.c | 36 +++++++++++++++--------------------- dlls/dsound/primary.c | 2 +- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index e2f2cc2..26e34f4 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -293,7 +293,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); } @@ -967,7 +967,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 6c97031..143adf2 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -184,7 +184,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; @@ -357,7 +358,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; @@ -376,8 +377,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 77388b4..33b2ce1 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); } /** @@ -303,22 +300,19 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len * 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; + freqAcc += dsb->freqAdjust; + ipos += ((DWORD)freqAcc) * istride; + freqAcc -= truncf(freqAcc); opos += ostride; } } @@ -355,7 +349,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 a726ec8..8960efb 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -509,7 +509,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; -- 1.7.3.4