diff options
author | kcgen <kcgen@users.noreply.github.com> | 2022-09-27 23:27:05 +0300 |
---|---|---|
committer | kcgen <kcgen@users.noreply.github.com> | 2022-09-27 23:27:08 +0300 |
commit | b3302ab7795a015c86a46fb7c1260b39380fa7f3 (patch) | |
tree | d23910bcea542e9ce5db6e63765e9a69ba6a6a2a | |
parent | 2d7f26dbee28ac7bcd05f8b504b18888a1053260 (diff) |
Only re-configure the resamplers on rate changeskc/avoid-duplicate-resampler-init-1
Blue Brothers Jukebox performs repeated SB DMA transfers with a silent
but roughly-constant DC-offset stream. Each transfer include the sample
rate for the section, to which the sound blaster's channel rate is set.
On setting the rate, the channel would re-configure the resamplers.
The linear resampler interpolates from the prior sample to the current
sample with the mixer's period being the time step. During these
re-configuration events, the linear resampler's prior sample state
variable is cleared (which makes sense, if the rate is changing because
the data is likely starting fresh).
It was this repeated zero'ing of the prior sample that caused the sound
blaster's DMA stream to spike to zero roughly once every 20
milliseconds, creating the reported grating effect.
This commit avoid reconfiguring the resamplers when they're already set
to the same sampling rate.
-rw-r--r-- | src/hardware/mixer.cpp | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 281987a22..93991449e 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -743,20 +743,27 @@ void MixerChannel::ClearResampler() void MixerChannel::SetSampleRate(const int rate) { - if (rate) { - sample_rate = rate; - } else { - // If the channel rate is zero, then avoid resampling by running - // the channel at the same rate as the mixer - assert(mixer.sample_rate > 0); - sample_rate = mixer.sample_rate; - } + // If the requested rate is zero, then avoid resampling by running the + // channel at the mixer's rate + const auto target_rate = rate ? rate : mixer.sample_rate.load(); + assert(target_rate > 0); - // DEBUG_LOG_MSG("%s: Sample rate set to %d Hz", name.c_str(), sample_rate); + // Nothing to do: the channel is already running at the requested rate + if (target_rate == sample_rate) + return; + + // DEBUG_LOG_MSG("%s: Changing rate from %d to %d Hz", + // name.c_str(), + // sample_rate, + // target_rate); + sample_rate = target_rate; freq_add = (sample_rate << FREQ_SHIFT) / mixer.sample_rate; - envelope.Update(sample_rate, peak_amplitude, - ENVELOPE_MAX_EXPANSION_OVER_MS, ENVELOPE_EXPIRES_AFTER_S); + + envelope.Update(sample_rate, + peak_amplitude, + ENVELOPE_MAX_EXPANSION_OVER_MS, + ENVELOPE_EXPIRES_AFTER_S); ConfigureResampler(); } @@ -1480,6 +1487,18 @@ void MixerChannel::AddSamples(const uint16_t frames, const Type *data) s.pos += s.step; + //DEBUG_LOG_MSG("%s: AddSamples last %.1f:%.1f curr %.1f:%.1f" + // " -> out %.1f:%.1f, pos=%.2f, step=%.2f", + // name.c_str(), + // s.last_frame.left, + // s.last_frame.right, + // curr_frame.left, + // curr_frame.right, + // out_left, + // out_right, + // s.pos, + // s.step); + if (s.pos > 1.0f) { s.pos -= 1.0f; s.last_frame = curr_frame; |