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