mod common;
use scsynth::{Options, World};
const SAMPLE_RATE: u32 = 44_100;
const BLOCK: usize = 64;
const CHANNELS: usize = 2;
const FREQ: f32 = 440.0;
#[test]
fn pumps_sine_tone() {
let mut world = World::new(
Options::new()
.real_time(true)
.input_channels(0)
.output_channels(CHANNELS as u32)
.sample_rate(SAMPLE_RATE)
.block_size(BLOCK as u32)
.load_synthdefs(false)
.verbosity(-1),
)
.expect("World_New failed");
let mut scratch = vec![0f32; BLOCK * CHANNELS];
world.send_packet(&common::encode(common::d_recv(common::synthdef_sine(
FREQ, CHANNELS,
))));
common::pump_for_reply(&mut world, "/done", CHANNELS, 200);
world.send_packet(&common::encode(common::s_new("sine", 1000, 0, 0)));
for _ in 0..10 {
world.process(&[], 0, &mut scratch, CHANNELS);
}
let mut output = vec![0f32; BLOCK * 64 * CHANNELS];
world.process(&[], 0, &mut output, CHANNELS);
let sr = SAMPLE_RATE as f32;
for ch in 0..CHANNELS {
let channel: Vec<f32> = output[ch..].iter().step_by(CHANNELS).copied().collect();
let level = common::rms(&channel);
let at_440 = common::goertzel(&channel, sr, FREQ);
let at_1000 = common::goertzel(&channel, sr, 1000.0);
let at_220 = common::goertzel(&channel, sr, 220.0);
assert!(level > 0.1, "channel {ch} is ~silent (rms = {level})");
assert!(
at_440 > 10.0 * at_1000 && at_440 > 10.0 * at_220,
"channel {ch}: expected a dominant 440 Hz tone (440={at_440}, 1000={at_1000}, 220={at_220})"
);
}
}