mirror of
https://github.com/storytold/soundcraft.git
synced 2026-10-24 10:36:46 -06:00
Merge pull request #573 from DCubix/fix/resampler-block-edge
Fix stale sample read at the end of each mix block when device and session rates differ
This commit is contained in:
@@ -362,7 +362,8 @@ impl AudioState {
|
|||||||
let sample = |c: usize| {
|
let sample = |c: usize| {
|
||||||
let ch = self.pending.get(c);
|
let ch = self.pending.get(c);
|
||||||
let a = ch.and_then(|v| v.get(i0)).copied().unwrap_or(0.0);
|
let a = ch.and_then(|v| v.get(i0)).copied().unwrap_or(0.0);
|
||||||
let b = ch.and_then(|v| v.get(i0 + 1)).copied().unwrap_or(a);
|
// `pending` is BLOCK long; only `pending_len` frames are valid. Hold the last one at the edge.
|
||||||
|
let b = if i0 + 1 < self.pending_len { ch.and_then(|v| v.get(i0 + 1)).copied().unwrap_or(a) } else { a };
|
||||||
a + (b - a) * fr
|
a + (b - a) * fr
|
||||||
};
|
};
|
||||||
if channels < nch {
|
if channels < nch {
|
||||||
@@ -1223,6 +1224,26 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn resampling_at_a_short_block_edge_does_not_mix_in_stale_frames() {
|
||||||
|
use soundcraft_model::ChannelFormat;
|
||||||
|
// DC for the first long block, then silence. The device runs slower than the session, so
|
||||||
|
// reads land between frames; a short block leaves the long block's DC past `pending_len`.
|
||||||
|
let mut st = audio_output_state(ChannelFormat::Stereo, vec![vec![0.8; BLOCK]; 2]);
|
||||||
|
st.device_rate = 44_100.0;
|
||||||
|
let mut long = vec![0.0; 2 * 470];
|
||||||
|
st.fill(&mut long, 2);
|
||||||
|
assert_eq!(st.pending_len, BLOCK);
|
||||||
|
let mut short = [0.0; 2 * 8];
|
||||||
|
for call in 0..20 {
|
||||||
|
st.fill(&mut short, 2);
|
||||||
|
assert!(st.pending_len < BLOCK);
|
||||||
|
// The first frame of the first short call still reads the DC block's last frame.
|
||||||
|
let from = if call == 0 { 2 } else { 0 };
|
||||||
|
assert!(short[from..].iter().all(|x| x.abs() < 1e-6), "call {call}: {short:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mono_device_preserves_centered_mono_level_and_includes_surround_right_channels() {
|
fn mono_device_preserves_centered_mono_level_and_includes_surround_right_channels() {
|
||||||
use soundcraft_model::ChannelFormat;
|
use soundcraft_model::ChannelFormat;
|
||||||
|
|||||||
Reference in New Issue
Block a user