#![doc = r#"
Extensions for `rustysynth` interop
"#]
use crate::prelude::*;
use rustysynth::*;
impl MidiTarget for Synthesizer {
type Error = ();
fn handle_event(&mut self, event: MidiMessage) -> Result<(), Self::Error> {
match event {
MidiMessage::SysCommon(_s) => {
Ok(())
}
MidiMessage::SysRealTime(_s) => {
Ok(())
}
MidiMessage::SysExclusive(_s) => {
Ok(())
}
MidiMessage::ChannelVoice(cvm) => {
Ok(())
}
MidiMessage::ChannelMode(cm) => {
Ok(())
}
}
}
}
#[test]
fn test_synth() {
use std::fs::File;
use std::sync::Arc;
let mut sf2 = include_bytes!("../../essential.sf2").as_slice();
let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap());
let mut mid = File::open("flourish.mid").unwrap();
let midi_file = Arc::new(MidiFile::new(&mut mid).unwrap());
let settings = SynthesizerSettings::new(44100);
let synthesizer = Synthesizer::new(&sound_font, &settings).unwrap();
let mut sequencer = MidiFileSequencer::new(synthesizer);
sequencer.play(&midi_file, false);
let sample_count = (settings.sample_rate as f64 * midi_file.get_length()) as usize;
let mut left: Vec<f32> = vec![0_f32; sample_count];
let mut right: Vec<f32> = vec![0_f32; sample_count];
sequencer.render(&mut left[..], &mut right[..]);
}
#[test]
fn audio_synth() {
use itertools::Itertools as _;
use std::sync::Arc;
use tinyaudio::prelude::*;
let params = OutputDeviceParameters {
channels_count: 2,
sample_rate: 44100,
channel_sample_count: 4410,
};
let params = OutputDeviceParameters {
channels_count: 2,
sample_rate: 44100,
channel_sample_count: 441,
};
let mut left: Vec<f32> = vec![0_f32; params.channel_sample_count];
let mut right: Vec<f32> = vec![0_f32; params.channel_sample_count];
let mut sf2 = include_bytes!("../../essential.sf2").as_slice();
let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap());
let mut mid = include_bytes!("../../test-asset/Clementi.mid").as_slice();
let midi_file = Arc::new(MidiFile::new(&mut mid).unwrap());
println!("midi file loaded");
let settings = SynthesizerSettings::new(params.sample_rate as i32);
let synthesizer = Synthesizer::new(&sound_font, &settings).unwrap();
println!("synth loaded");
let mut sequencer = MidiFileSequencer::new(synthesizer);
println!("sequencer loaded");
sequencer.play(&midi_file, false);
println!("sequencer playing");
let mut count = 0;
let _device = run_output_device(params, {
move |data| {
println!("closure call: {}", count);
count += 1;
sequencer.render(&mut left[..], &mut right[..]);
for (i, value) in left.iter().interleave(right.iter()).enumerate() {
data[i] = *value;
}
}
})
.unwrap();
std::thread::sleep(std::time::Duration::from_secs(180));
}
#[test]
fn stream_synth() {
use itertools::Itertools as _;
use std::sync::{Arc, Mutex};
use tinyaudio::prelude::*;
let params = OutputDeviceParameters {
channels_count: 2,
sample_rate: 44100,
channel_sample_count: 4410,
};
let params = OutputDeviceParameters {
channels_count: 2,
sample_rate: 44100,
channel_sample_count: 441,
};
let mut left: Vec<f32> = vec![0_f32; params.channel_sample_count];
let mut right: Vec<f32> = vec![0_f32; params.channel_sample_count];
let mut sf2 = include_bytes!("../../essential.sf2").as_slice();
let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap());
println!("midi file loaded");
let settings = SynthesizerSettings::new(params.sample_rate as i32);
let synthesizer = Arc::new(Mutex::new(
Synthesizer::new(&sound_font, &settings).unwrap(),
));
println!("synth loaded");
let s_c = synthesizer.clone();
std::thread::spawn(move || {
for i in 0..10 {
let key = 40 + i;
let mut synth = s_c.lock().unwrap();
synth.note_on(1, key, 127);
drop(synth);
std::thread::sleep(std::time::Duration::from_secs(4));
}
});
println!("sequencer playing");
let mut count = 0;
let _device = run_output_device(params, {
move |data| {
println!("closure call: {}", count);
count += 1;
let mut synth = synthesizer.lock().unwrap();
synth.render(&mut left[..], &mut right[..]);
for (i, value) in left.iter().interleave(right.iter()).enumerate() {
data[i] = *value;
}
}
})
.unwrap();
std::thread::sleep(std::time::Duration::from_secs(180));
}