use itertools::Itertools; use rustysynth::SoundFont; use rustysynth::Synthesizer; use rustysynth::SynthesizerSettings; use std::fs::File; use std::sync::Arc; use tinyaudio::prelude::*; fn main() { // Load the SoundFont. let mut sf2 = File::open("FatBoy.sf2").unwrap(); let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap()); // Setup the audio output. let params = OutputDeviceParameters { channels_count: 2, sample_rate: 44100, channel_sample_count: 4410, }; // Create the synthesizer. let settings = SynthesizerSettings::new(params.sample_rate as i32); let mut synthesizer = Synthesizer::new(&sound_font, &settings).unwrap(); // Play some notes (middle C, E, G). // 16 channels actually // 60=c 64=e 67=g //up to 128velocity though dont go below 50 tbh synthesizer.note_on(0, 64, 100); //synthesizer.render(&mut left[..], &mut right[..]); // puts in a state of rendering the first loop of these notes // The recycled output buffer per-loop, could be in lamba but that'd be wasteful let sample_count = (params.channel_sample_count) as usize; let mut left: Vec = vec![0_f32; sample_count]; let mut right: Vec = vec![0_f32; sample_count]; // Start the audio output. Executes channel_sample_count per loop, sample_rate/channel_sample_count per second forever. let _device = run_output_device(params, { move |data| { synthesizer.render(&mut left[..], &mut right[..]); // put in a state of rendering the next loop of these notes for (i, value) in left.iter().interleave(right.iter()).enumerate() { data[i] = *value; } } }) .unwrap(); // Let it ride std::thread::sleep(std::time::Duration::from_secs(1)); }