use web_audio_api::context::AsBaseAudioContext;
use web_audio_api::context::OfflineAudioContext;
use web_audio_api::node::{
AudioNode, AudioScheduledSourceNode, OscillatorNode, OscillatorOptions, OscillatorType,
};
use web_audio_api::{SampleRate, BUFFER_SIZE};
#[test]
fn test_offline_render() {
const LENGTH: usize = 555;
assert!(LENGTH % BUFFER_SIZE as usize != 0);
let mut context = OfflineAudioContext::new(2, LENGTH, SampleRate(44_100));
assert_eq!(context.length(), LENGTH);
{
let constant1 = context.create_constant_source();
constant1.offset().set_value(2.);
constant1.connect(&context.destination());
let constant2 = context.create_constant_source();
constant2.offset().set_value(-4.);
constant2.connect(&context.destination());
}
let output = context.start_rendering();
assert_eq!(output.number_of_channels(), 2);
assert_eq!(output.sample_len(), LENGTH);
assert_eq!(output.channel_data(0).as_slice(), &[-2.; LENGTH]);
assert_eq!(output.channel_data(1).as_slice(), &[-2.; LENGTH]);
}
#[test]
fn test_start_stop() {
let len = (BUFFER_SIZE * 4) as usize;
let mut context = OfflineAudioContext::new(1, len, SampleRate(BUFFER_SIZE));
assert_eq!(context.length(), len);
{
let opts = OscillatorOptions {
type_: OscillatorType::Square,
frequency: 0., ..Default::default()
};
let osc = OscillatorNode::new(&context, opts);
osc.connect(&context.destination());
osc.start_at(1.);
osc.stop_at(3.);
}
let output = context.start_rendering();
assert_eq!(output.number_of_channels(), 1);
assert_eq!(output.sample_len(), BUFFER_SIZE as usize * 4);
let channel_data = output.channel_data(0).as_slice();
let mut expected = vec![0.; BUFFER_SIZE as usize];
expected.append(&mut vec![1.; 2 * BUFFER_SIZE as usize]);
expected.append(&mut vec![0.; BUFFER_SIZE as usize]);
assert_eq!(channel_data, expected.as_slice());
}
#[test]
fn test_delayed_constant_source() {
let len = (BUFFER_SIZE * 4) as usize;
let mut context = OfflineAudioContext::new(1, len, SampleRate(BUFFER_SIZE));
assert_eq!(context.length(), len);
{
let delay = context.create_delay(10.);
delay.delay_time().set_value(2.);
delay.connect(&context.destination());
let source = context.create_constant_source();
source.connect(&delay);
}
let output = context.start_rendering();
assert_eq!(output.number_of_channels(), 1);
assert_eq!(output.sample_len(), BUFFER_SIZE as usize * 4);
let channel_data = output.channel_data(0).as_slice();
let mut expected = vec![0.; 2 * BUFFER_SIZE as usize];
expected.append(&mut vec![1.; 2 * BUFFER_SIZE as usize]);
assert_eq!(channel_data, expected.as_slice());
}
#[test]
fn test_audio_param_graph() {
let len = BUFFER_SIZE as usize;
let mut context = OfflineAudioContext::new(1, len, SampleRate(BUFFER_SIZE));
{
let gain = context.create_gain();
gain.gain().set_value(0.5); gain.connect(&context.destination());
let source = context.create_constant_source();
source.offset().set_value(0.8);
source.connect(&gain);
let param_input1 = context.create_constant_source();
param_input1.offset().set_value(0.1);
param_input1.connect(gain.gain());
let param_input2 = context.create_constant_source();
param_input2.offset().set_value(0.3);
param_input2.connect(gain.gain());
}
let output = context.start_rendering();
assert_eq!(output.number_of_channels(), 1);
assert_eq!(output.sample_len(), BUFFER_SIZE as usize);
let channel_data = output.channel_data(0).as_slice();
let expected = vec![0.8 * 0.9; BUFFER_SIZE as usize];
assert_eq!(channel_data, expected.as_slice());
}
#[test]
fn test_listener() {
let len = BUFFER_SIZE as usize;
let mut context = OfflineAudioContext::new(1, len, SampleRate(BUFFER_SIZE));
{
let listener1 = context.listener();
let listener2 = context.listener();
listener1.position_x().set_value(1.);
listener2.position_y().set_value(2.);
}
let _ = context.start_rendering();
let listener = context.listener();
assert_eq!(listener.position_y().value(), 2.);
assert_eq!(listener.position_x().value(), 1.);
}
#[test]
fn test_cycle() {
let len = BUFFER_SIZE as usize;
let mut context = OfflineAudioContext::new(1, len, SampleRate(44_100));
{
let cycle1 = context.create_gain();
cycle1.connect(&context.destination());
let cycle2 = context.create_gain();
cycle2.connect(&cycle1);
cycle1.connect(&cycle2);
let source_cycle = context.create_constant_source();
source_cycle.offset().set_value(1.);
source_cycle.connect(&cycle1);
let other = context.create_constant_source();
other.offset().set_value(2.);
other.connect(&context.destination());
}
let output = context.start_rendering();
assert_eq!(
output.channel_data(0).as_slice(),
&[2.; BUFFER_SIZE as usize]
);
}