use approx::assert_relative_eq; use itertools::izip; use rawdio::{prelude::*, Mixer}; struct Fixture { channel_count: usize, sample_rate: usize, context: Box, audio_process: Box, mixer: Mixer, } impl Fixture { fn process(&mut self, input: &dyn AudioBuffer) -> OwnedAudioBuffer { let mut output_buffer = OwnedAudioBuffer::new(input.frame_count(), self.channel_count, self.sample_rate); self.audio_process.process(input, &mut output_buffer); output_buffer } fn new(channel_count: usize) -> Self { let sample_rate = 44100; let (mut context, process) = create_engine_with_options(EngineOptions::default().with_sample_rate(sample_rate)); let mixer = Mixer::new(context.as_ref(), channel_count, channel_count); connect_nodes!("input" => mixer => "output"); context.start(); Self { channel_count, sample_rate, context, audio_process: process, mixer, } } } impl Default for Fixture { fn default() -> Self { let channel_count = 2; Self::new(channel_count) } } impl Drop for Fixture { fn drop(&mut self) { self.context.stop(); } } #[test] fn test_phase_invert() { let channel_count = 1; let mut fixture = Fixture::new(channel_count); fixture.mixer.set_level(0, 0, Level::from_linear(-1.0)); let frame_count = 1_024; let sample_rate = 48_000; let input_signal = OwnedAudioBuffer::white_noise(frame_count, channel_count, sample_rate); let output_signal = fixture.process(&input_signal); let input_data = input_signal.get_channel_data(SampleLocation::channel(0)); let output_data = output_signal.get_channel_data(SampleLocation::channel(0)); for (input_sample, output_sample) in izip!(input_data.iter(), output_data.iter()) { assert_relative_eq!(*output_sample, -1.0 * *input_sample); } } #[test] fn test_channel_flip() { let channel_count = 2; let mut fixture = Fixture::new(channel_count); fixture.mixer.set_level(0, 0, Level::zero()); fixture.mixer.set_level(0, 1, Level::unity()); fixture.mixer.set_level(1, 0, Level::unity()); fixture.mixer.set_level(1, 1, Level::zero()); let frame_count = 1_024; let sample_rate = 48_000; let input_signal = OwnedAudioBuffer::white_noise(frame_count, channel_count, sample_rate); let output_signal = fixture.process(&input_signal); let input_0 = input_signal.get_channel_data(SampleLocation::channel(0)); let input_1 = input_signal.get_channel_data(SampleLocation::channel(1)); let output_0 = output_signal.get_channel_data(SampleLocation::channel(0)); let output_1 = output_signal.get_channel_data(SampleLocation::channel(1)); for (input_sample, output_sample) in izip!(input_0.iter(), output_1.iter()) { assert_relative_eq!(*output_sample, *input_sample); } for (input_sample, output_sample) in izip!(input_1.iter(), output_0.iter()) { assert_relative_eq!(*output_sample, *input_sample); } } #[test] fn test_stereo_to_mono() { let channel_count = 2; let mut fixture = Fixture::new(channel_count); fixture.mixer.set_level(0, 0, Level::from_linear(0.5)); fixture.mixer.set_level(1, 0, Level::from_linear(0.5)); let frame_count = 1_024; let sample_rate = 48_000; let input_signal = OwnedAudioBuffer::white_noise(frame_count, channel_count, sample_rate); let output_signal = fixture.process(&input_signal); let input_0 = input_signal.get_channel_data(SampleLocation::channel(0)); let input_1 = input_signal.get_channel_data(SampleLocation::channel(1)); let output_0 = output_signal.get_channel_data(SampleLocation::channel(0)); assert!(output_signal.channel_is_silent(1)); for (input_sample_0, input_sample_1, output_sample) in izip!(input_0.iter(), input_1.iter(), output_0.iter()) { let expected_sample = 0.5 * (*input_sample_0 + *input_sample_1); assert_relative_eq!(*output_sample, expected_sample); } }