-
Notifications
You must be signed in to change notification settings - Fork 24
/
main.rs
96 lines (78 loc) · 2.89 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use rustysynth::MidiFile;
use rustysynth::MidiFileSequencer;
use rustysynth::SoundFont;
use rustysynth::Synthesizer;
use rustysynth::SynthesizerSettings;
use std::fs::File;
use std::io::Write;
use std::sync::Arc;
fn main() {
simple_chord();
flourish();
}
fn simple_chord() {
// Load the SoundFont.
let mut sf2 = File::open("TimGM6mb.sf2").unwrap();
let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap());
// Create the synthesizer.
let settings = SynthesizerSettings::new(44100);
let mut synthesizer = Synthesizer::new(&sound_font, &settings).unwrap();
// Play some notes (middle C, E, G).
synthesizer.note_on(0, 60, 100);
synthesizer.note_on(0, 64, 100);
synthesizer.note_on(0, 67, 100);
// The output buffer (3 seconds).
let sample_count = (3 * settings.sample_rate) as usize;
let mut left: Vec<f32> = vec![0_f32; sample_count];
let mut right: Vec<f32> = vec![0_f32; sample_count];
// Render the waveform.
synthesizer.render(&mut left[..], &mut right[..]);
// Write the waveform to the file.
write_pcm(&left[..], &right[..], "simple_chord.pcm");
}
fn flourish() {
// Load the SoundFont.
let mut sf2 = File::open("TimGM6mb.sf2").unwrap();
let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap());
// Load the MIDI file.
let mut mid = File::open("flourish.mid").unwrap();
let midi_file = Arc::new(MidiFile::new(&mut mid).unwrap());
// Create the MIDI file sequencer.
let settings = SynthesizerSettings::new(44100);
let synthesizer = Synthesizer::new(&sound_font, &settings).unwrap();
let mut sequencer = MidiFileSequencer::new(synthesizer);
// Play the MIDI file.
sequencer.play(&midi_file, false);
// The output buffer.
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];
// Render the waveform.
sequencer.render(&mut left[..], &mut right[..]);
// Write the waveform to the file.
write_pcm(&left[..], &right[..], "flourish.pcm");
}
fn write_pcm(left: &[f32], right: &[f32], path: &str) {
let mut max: f32 = 0_f32;
for t in 0..left.len() {
if left[t].abs() > max {
max = left[t].abs();
}
if right[t].abs() > max {
max = right[t].abs();
}
}
let a = 0.99_f32 / max;
let mut buf: Vec<u8> = vec![0; 4 * left.len()];
for t in 0..left.len() {
let left_i16 = (a * left[t] * 32768_f32) as i16;
let right_i16 = (a * right[t] * 32768_f32) as i16;
let offset = 4 * t;
buf[offset] = left_i16 as u8;
buf[offset + 1] = (left_i16 >> 8) as u8;
buf[offset + 2] = right_i16 as u8;
buf[offset + 3] = (right_i16 >> 8) as u8;
}
let mut pcm = File::create(path).unwrap();
pcm.write_all(&buf[..]).unwrap();
}