[DSOUND] Use an inline for ring buffer pointer difference
calculation
Maarten Lankhorst
m.b.lankhorst at gmail.com
Wed Feb 21 13:17:22 CST 2007
[DSOUND] Use an inline for ring buffer pointer difference calculation
-------------- next part --------------
>From cff71bdd2f23f8141e46b7eeee7ef140bf62902c Mon Sep 17 00:00:00 2001
From: maarten <maarten at maarten-laptop.(none)>
Date: Sat, 10 Feb 2007 11:47:27 +0100
Subject: [PATCH] Introduce an inline for ring buffer pointer diff calculation
---
dlls/dsound/mixer.c | 54 ++++++++++++++++++++++++++-------------------------
1 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
index 5c5ae2e..77e98bb 100644
--- a/dlls/dsound/mixer.c
+++ b/dlls/dsound/mixer.c
@@ -724,6 +724,19 @@ void DSOUND_ForceRemix(IDirectSoundBuffe
}
/**
+ * Calculate the distance between two buffer offsets, taking wraparound
+ * into account.
+ */
+static inline DWORD DSOUND_BufPtrDiff(DWORD buflen, DWORD ptr1, DWORD ptr2)
+{
+ if (ptr1 >= ptr2) {
+ return ptr1 - ptr2;
+ } else {
+ return buflen + ptr1 - ptr2;
+ }
+}
+
+/**
* Mix some frames from the given secondary buffer "dsb" into the device
* primary buffer.
*
@@ -744,18 +757,10 @@ static DWORD DSOUND_MixOne(IDirectSoundB
/* determine this buffer's write position */
DWORD buf_writepos = DSOUND_CalcPlayPosition(dsb, writepos, writepos);
/* determine how much already-mixed data exists */
- DWORD buf_done =
- ((dsb->buf_mixpos < buf_writepos) ? dsb->buflen : 0) +
- dsb->buf_mixpos - buf_writepos;
- DWORD primary_done =
- ((dsb->primary_mixpos < writepos) ? dsb->device->buflen : 0) +
- dsb->primary_mixpos - writepos;
- DWORD adv_done =
- ((dsb->device->mixpos < writepos) ? dsb->device->buflen : 0) +
- dsb->device->mixpos - writepos;
- DWORD played =
- ((buf_writepos < dsb->playpos) ? dsb->buflen : 0) +
- buf_writepos - dsb->playpos;
+ DWORD buf_done = DSOUND_BufPtrDiff(dsb->buflen, dsb->buf_mixpos, buf_writepos);
+ DWORD primary_done = DSOUND_BufPtrDiff(dsb->device->buflen, dsb->primary_mixpos, writepos);
+ DWORD adv_done = DSOUND_BufPtrDiff(dsb->device->buflen, dsb->device->mixpos, writepos);
+ DWORD played = DSOUND_BufPtrDiff(dsb->buflen, buf_writepos, dsb->playpos);
DWORD buf_left = dsb->buflen - buf_writepos;
int still_behind;
@@ -883,9 +888,7 @@ post_mix:
* advance its underrun detector...*/
if (still_behind) return 0;
if ((mixlen - len) < primary_done) return 0;
- slen = ((dsb->primary_mixpos < dsb->device->mixpos) ?
- dsb->device->buflen : 0) + dsb->primary_mixpos -
- dsb->device->mixpos;
+ slen = DSOUND_BufPtrDiff(dsb->device->buflen, dsb->primary_mixpos, dsb->device->mixpos);
if (slen > mixlen) {
/* the primary_done and still_behind checks above should have worked */
FIXME("problem with advancement calculation (advlen=%d > mixlen=%d)\n", slen, mixlen);
@@ -1087,22 +1090,19 @@ static void DSOUND_PerformMix(DirectSoun
DSOUND_CheckReset(device, writepos);
/* check how much prebuffering is left */
- inq = device->mixpos;
- if (inq < writepos)
- inq += device->buflen;
- inq -= writepos;
+ inq = DSOUND_BufPtrDiff(device->buflen, device->mixpos, writepos);
/* find the maximum we can prebuffer */
- if (!paused) {
- maxq = playpos;
- if (maxq < writepos)
- maxq += device->buflen;
- maxq -= writepos;
- } else maxq = device->buflen;
+ if (!paused)
+ maxq = DSOUND_BufPtrDiff(device->buflen, playpos, writepos);
+ /* If we get the whole buffer, difference is 0, so we need to set whole buffer then */
+ if (paused || !maxq)
+ maxq = device->buflen;
/* clip maxq to device->prebuf */
frag = device->prebuf * device->fraglen;
- if (maxq > frag) maxq = frag;
+ if (maxq > frag)
+ maxq = frag;
/* check for consistency */
if (inq > maxq) {
@@ -1248,7 +1248,7 @@ #endif
playpos = pwplay * fraglen;
mixpos = device->mixpos;
/* check remaining mixed data */
- inq = ((mixpos < playpos) ? buflen : 0) + mixpos - playpos;
+ inq = DSOUND_BufPtrDiff(buflen, mixpos, playpos);
mixq = inq / fraglen;
if ((inq - (mixq * fraglen)) > 0) mixq++;
/* complete the playing buffer */
--
1.4.1
More information about the wine-patches
mailing list