Andrew Eikum : dsound: Convert from fixed to floating point.
Alexandre Julliard
julliard at winehq.org
Wed May 2 14:30:02 CDT 2012
Module: wine
Branch: master
Commit: f393a98a8a6cbb585101ac0338723151a6e135c1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f393a98a8a6cbb585101ac0338723151a6e135c1
Author: Andrew Eikum <aeikum at 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;
More information about the wine-cvs
mailing list