dsound: Simplify IDirectSoundBufferImpl_GetCurrentPosition
Maarten Lankhorst
m.b.lankhorst at gmail.com
Sun Jul 8 11:08:30 CDT 2007
Since the dsound mixer rewrite play position has been reported wrong.
It's not (insert some weird complicated stuff here), but buf_mixpos now.
This should fix bug 8823.
-------------- next part --------------
>From 62ca0942490a2005c2649d077e9257bcad6aa10f Mon Sep 17 00:00:00 2001
From: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Sun, 8 Jul 2007 16:36:46 +0200
Subject: [PATCH] dsound: Simplify getcurrentposition
Since mixer rewrite it DSOUND_CalcPlayPosition isnt reporting the correct positions any more
---
dlls/dsound/buffer.c | 77 +++--------------------------------------
dlls/dsound/dsound_private.h | 6 +---
2 files changed, 7 insertions(+), 76 deletions(-)
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
index 50959e2..aa6ef50 100644
--- a/dlls/dsound/buffer.c
+++ b/dlls/dsound/buffer.c
@@ -409,47 +409,9 @@ static ULONG WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface)
return ref;
}
-DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, DWORD pplay, DWORD pwrite)
+static DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This)
{
DWORD bplay = This->buf_mixpos;
- DWORD pmix = This->primary_mixpos;
- DirectSoundDevice * device = This->device;
- TRACE("(%p, pplay=%u, pwrite=%u)\n", This, pplay, pwrite);
-
- /* the actual primary play position (pplay) is always behind last mixed (pmix),
- * unless the computer is too slow or something */
- /* we need to know how far away we are from there */
- if (pmix < pplay) pmix += device->buflen; /* wraparound */
- pmix -= pplay;
-
- /* detect buffer underrun (sanity) */
- if (pwrite < pplay) pwrite += device->buflen; /* wraparound */
- pwrite -= pplay;
- if (pmix > (ds_snd_queue_max * device->fraglen + pwrite + device->writelead)) {
- ERR("detected an underrun: primary queue was %d\n",pmix);
- pmix = 0;
- }
-
- TRACE("primary back-samples=%d\n",pmix);
-
- /* divide the offset by its sample size */
- pmix /= device->pwfx->nBlockAlign;
-
- /* adjust for our frequency */
- pmix = (pmix * This->freqAdjust) >> DSOUND_FREQSHIFT;
-
- /* multiply by our own sample size */
- pmix *= This->pwfx->nBlockAlign;
-
- TRACE("this back-offset=%d\n", pmix);
-
- /* sanity */
- if(pmix > This->buflen)
- WARN("Mixed length (%d) is longer then buffer length (%d)\n", pmix, This->buflen);
-
- /* subtract from our last mixed position */
- while (bplay < pmix) bplay += This->buflen; /* wraparound */
- bplay -= pmix;
/* check for lead-in */
if (This->leadin && ((bplay < This->startpos) || (bplay > This->buf_mixpos))) {
@@ -481,38 +443,13 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
return hres;
}
} else {
- if (playpos && (This->state != STATE_PLAYING)) {
+ if (playpos && (This->state != STATE_PLAYING))
/* we haven't been merged into the primary buffer (yet) */
*playpos = This->buf_mixpos;
- } else if (playpos) {
- DWORD pplay, pwrite;
-
- /* get primary lock, before messing with primary/device data */
- EnterCriticalSection(&(This->device->mixlock));
-
- /* let's get this exact; first, recursively call GetPosition on the primary */
- if (DSOUND_PrimaryGetPosition(This->device, &pplay, &pwrite) != DS_OK)
- WARN("DSOUND_PrimaryGetPosition failed\n");
- if ((This->dsbd.dwFlags & DSBCAPS_GETCURRENTPOSITION2) || This->device->hwbuf) {
- /* calculate play position using this */
- *playpos = DSOUND_CalcPlayPosition(This, pplay, pwrite);
- } else {
- /* (unless the app isn't using GETCURRENTPOSITION2) */
- /* don't know exactly how this should be handled...
- * the docs says that play cursor is reported as directly
- * behind write cursor, hmm... */
- /* let's just do what might work for Half-Life */
- DWORD wp;
- wp = (This->device->pwplay + This->device->prebuf) * This->device->fraglen;
- wp %= This->device->buflen;
- *playpos = DSOUND_CalcPlayPosition(This, wp, pwrite);
- TRACE("Using non-GETCURRENTPOSITION2\n");
- }
-
- LeaveCriticalSection(&(This->device->mixlock));
- }
+ else if (playpos)
+ *playpos = DSOUND_CalcPlayPosition(This);
if (writepos)
- *writepos = This->buf_mixpos;
+ *writepos = (playpos ? *playpos : This->buf_mixpos);
}
if (writepos) {
if (This->state != STATE_STOPPED) {
@@ -521,11 +458,9 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
}
*writepos %= This->buflen;
}
- if (playpos)
- This->last_playpos = *playpos;
TRACE("playpos = %d, writepos = %d, buflen=%d (%p, time=%d)\n",
- playpos?*playpos:0, writepos?*writepos:0, This->buflen, This, GetTickCount());
+ playpos?*playpos:-1, writepos?*writepos:-1, This->buflen, This, GetTickCount());
return DS_OK;
}
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
index 386ed96..fcd4133 100644
--- a/dlls/dsound/dsound_private.h
+++ b/dlls/dsound/dsound_private.h
@@ -170,7 +170,7 @@ struct IDirectSoundBufferImpl
/* used for frequency conversion (PerfectPitch) */
ULONG freqAdjust, freqAcc;
/* used for intelligent (well, sort of) prebuffering */
- DWORD primary_mixpos, buf_mixpos, last_playpos;
+ DWORD primary_mixpos, buf_mixpos;
/* IDirectSoundNotifyImpl fields */
IDirectSoundNotifyImpl* notify;
@@ -427,10 +427,6 @@ HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex)
HRESULT DSOUND_FullDuplexCreate(REFIID riid, LPDIRECTSOUNDFULLDUPLEX* ppDSFD);
-/* buffer.c */
-
-DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, DWORD pplay, DWORD pwrite);
-
/* mixer.c */
void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, DWORD playpos, int len);
--
1.4.4.2
More information about the wine-patches
mailing list