[PATCH 0/5] MR10146: dsound: Speed up resampling, part 1
From: Anton Baskanov <baskanov@gmail.com> --- dlls/dsound/dsound_private.h | 1 - 1 file changed, 1 deletion(-) diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 647f2273838..8a829c9f7c1 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -146,7 +146,6 @@ struct IDirectSoundBufferImpl DSVOLUMEPAN volpan; DSBUFFERDESC dsbd; /* used for frequency conversion (PerfectPitch) */ - ULONG freqneeded; DWORD firstep; float firgain; LONG64 freqAdjustNum,freqAdjustDen; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10146
From: Anton Baskanov <baskanov@gmail.com> --- dlls/dsound/mixer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 623c15496a8..260954444a3 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -377,11 +377,11 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 * UINT ipos = int_fir_steps / dsbfirstep; UINT idx = (ipos + 1) * dsbfirstep - int_fir_steps - 1; - float rem = int_fir_steps + 1.0 - total_fir_steps; + float rem = int_fir_steps + 1.0f - total_fir_steps; int fir_used = 0; while (idx < fir_len - 1) { - fir_copy[fir_used++] = fir[idx] * (1.0 - rem) + fir[idx + 1] * rem; + fir_copy[fir_used++] = fir[idx] * (1.0f - rem) + fir[idx + 1] * rem; idx += dsb->firstep; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10146
From: Anton Baskanov <baskanov@gmail.com> --- dlls/dsound/mixer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 260954444a3..c62d198ef0b 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -372,12 +372,12 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 * } for(i = 0; i < count; ++i) { - UINT int_fir_steps = (freqAcc_start + i * dsb->freqAdjustNum) * dsbfirstep / dsb->freqAdjustDen; - float total_fir_steps = (freqAcc_start + i * dsb->freqAdjustNum) * dsbfirstep / (float)dsb->freqAdjustDen; + LONG64 fir_steps_num = (freqAcc_start + i * dsb->freqAdjustNum) * dsbfirstep; + UINT int_fir_steps = fir_steps_num / dsb->freqAdjustDen; UINT ipos = int_fir_steps / dsbfirstep; UINT idx = (ipos + 1) * dsbfirstep - int_fir_steps - 1; - float rem = int_fir_steps + 1.0f - total_fir_steps; + float rem = 1.0f - (fir_steps_num - int_fir_steps * dsb->freqAdjustDen) / (float)dsb->freqAdjustDen; int fir_used = 0; while (idx < fir_len - 1) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10146
From: Anton Baskanov <baskanov@gmail.com> --- dlls/dsound/mixer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index c62d198ef0b..5da79e02a97 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -376,8 +376,8 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 * UINT int_fir_steps = fir_steps_num / dsb->freqAdjustDen; UINT ipos = int_fir_steps / dsbfirstep; - UINT idx = (ipos + 1) * dsbfirstep - int_fir_steps - 1; - float rem = 1.0f - (fir_steps_num - int_fir_steps * dsb->freqAdjustDen) / (float)dsb->freqAdjustDen; + UINT idx = dsbfirstep - 1 - int_fir_steps % dsbfirstep; + float rem = 1.0f - fir_steps_num % dsb->freqAdjustDen / (float)dsb->freqAdjustDen; int fir_used = 0; while (idx < fir_len - 1) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10146
From: Anton Baskanov <baskanov@gmail.com> --- dlls/dsound/mixer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 5da79e02a97..b90a7e98469 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -372,12 +372,12 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 * } for(i = 0; i < count; ++i) { - LONG64 fir_steps_num = (freqAcc_start + i * dsb->freqAdjustNum) * dsbfirstep; - UINT int_fir_steps = fir_steps_num / dsb->freqAdjustDen; - UINT ipos = int_fir_steps / dsbfirstep; + LONG64 ipos_num = freqAcc_start + i * dsb->freqAdjustNum; + UINT ipos = ipos_num / dsb->freqAdjustDen; - UINT idx = dsbfirstep - 1 - int_fir_steps % dsbfirstep; - float rem = 1.0f - fir_steps_num % dsb->freqAdjustDen / (float)dsb->freqAdjustDen; + UINT idx_num = ipos_num % dsb->freqAdjustDen * dsbfirstep; + UINT idx = dsbfirstep - 1 - idx_num / dsb->freqAdjustDen; + float rem = 1.0f - idx_num % dsb->freqAdjustDen / (float)dsb->freqAdjustDen; int fir_used = 0; while (idx < fir_len - 1) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10146
Matteo Bruni (@Mystral) commented about dlls/dsound/mixer.c:
}
for(i = 0; i < count; ++i) { - LONG64 fir_steps_num = (freqAcc_start + i * dsb->freqAdjustNum) * dsbfirstep; - UINT int_fir_steps = fir_steps_num / dsb->freqAdjustDen; - UINT ipos = int_fir_steps / dsbfirstep; + LONG64 ipos_num = freqAcc_start + i * dsb->freqAdjustNum; + UINT ipos = ipos_num / dsb->freqAdjustDen;
- UINT idx = dsbfirstep - 1 - int_fir_steps % dsbfirstep; - float rem = 1.0f - fir_steps_num % dsb->freqAdjustDen / (float)dsb->freqAdjustDen; + UINT idx_num = ipos_num % dsb->freqAdjustDen * dsbfirstep;
I had a hard time decoding the modulo here and I kept thinking that sometimes it might not give an exact result. For the former, after the modulo we have a number in the range `[0,freqAdjustDen)` representing the position within the specific input sample. Multiplying it by `dsbfirstep / freqAdjustDen` we compute `idx` in the expected `dsbfirstep` units. For the latter, I guess this works out fine in practice, with `freqAdjustDen` >> `dsbfirstep`. I don't know that there is anything to change here. I guess some kind of comment might be nice, although I'm hard pressed with coming up with a good comment myself. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10146#note_130090
This merge request was approved by Matteo Bruni. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10146
On Fri Feb 20 16:21:45 2026 +0000, Matteo Bruni wrote:
I had a hard time decoding the modulo here and I kept thinking that sometimes it might not give an exact result. For the former, after the modulo we have a number in the range `[0,freqAdjustDen)` representing the position within the specific input sample. Multiplying it by `dsbfirstep / freqAdjustDen` we compute `idx` in the expected `dsbfirstep` units. For the latter, I guess this works out fine in practice, with `freqAdjustDen` >> `dsbfirstep`. I don't know that there is anything to change here. I guess some kind of comment might be nice, although I'm hard pressed with coming up with a good comment myself. The resulting values should be identical. Here is a proof:
New value: `idx = dsbfirstep - 1 - (freqAcc_start + i * dsb->freqAdjustNum) % dsb->freqAdjustDen * dsbfirstep / dsb->freqAdjustDen` Old value: `idx = dsbfirstep - 1 - (freqAcc_start + i * dsb->freqAdjustNum) * dsbfirstep / dsb->freqAdjustDen % dsbfirstep` Let's denote `S = dsbfirstep, a = freqAcc_start + i * dsb->freqAdjustNum, D = dsb->freqAdjustDen`, so we have to prove that `S - 1 - a % D * S / D == S - 1 - a * S / D % S`. Subtract `S - 1` from both sides and multiply them by `-1`: `a % D * S / D == a * S / D % S`. Rewrite `a` as `a % D + a / D * D`: `(a % D + a / D * D) % D * S / D == (a % D + a / D * D) * S / D % S`. Adding a multiple of `D` doesn't change the modulus: `a % D * S / D == (a % D + a / D * D) * S / D % S`. Expand the parentheses on the right side: `a % D * S / D == a % D * S / D % S + a / D * D * S / D % S`. `a % D` is always less than `D`, so `a % D * S / D` is always less than `S`, which means that we can eliminate the `% S` in the first term on the right side: `a % D * S / D == a % D * S / D + a / D * D * S / D % S`. `D / D` cancels out in the second term on the right side: `a % D * S / D == a % D * S / D + a / D * S % S`. The second term on the right side is zero as it's a multiple of `S` modulo `S`: `a % D * S / D == a % D * S / D`. Q.E.D. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10146#note_130160
This merge request was approved by Huw Davies. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10146
participants (4)
-
Anton Baskanov -
Anton Baskanov (@baskanov) -
Huw Davies (@huw) -
Matteo Bruni (@Mystral)