sine_synth/
sine_synth.rs

1//! Simple monophonic synthesizer generating a sine wave for each received MIDI note.
2
3use audio_midi_shell::{AudioGenerator, AudioMidiShell};
4
5const SAMPLE_RATE: u32 = 44100;
6const BUFFER_SIZE: usize = 1024;
7const PROCESS_CHUNK_SIZE: usize = 16;
8
9fn main() -> ! {
10    AudioMidiShell::run_forever(
11        SAMPLE_RATE,
12        BUFFER_SIZE,
13        PROCESS_CHUNK_SIZE,
14        SineSynth::default(),
15    );
16}
17
18#[derive(Debug, Default)]
19struct SineSynth {
20    level: f32,
21    phase: f32,
22    phase_inc: f32,
23}
24
25impl AudioGenerator for SineSynth {
26    fn process(&mut self, frames: &mut [[f32; 2]]) {
27        for frame in frames {
28            let sample = f32::sin(self.phase) * self.level * 0.5;
29            frame[0] = sample;
30            frame[1] = sample;
31
32            self.phase += self.phase_inc;
33
34            if self.phase > core::f32::consts::TAU {
35                self.phase -= core::f32::consts::TAU;
36            }
37        }
38    }
39
40    fn process_midi(&mut self, message: &[u8], _timestamp: u64) {
41        match message[0] & 0xF0 {
42            0x80 => {
43                // Note off
44                self.level = 0.0;
45            }
46            0x90 => {
47                // Note on
48                self.level = message[2] as f32 / 127.0;
49                let frequency = 440.0 * f32::powf(2.0, (message[1] as i32 - 69) as f32 / 12.0);
50                self.phase_inc = frequency / SAMPLE_RATE as f32 * core::f32::consts::TAU;
51            }
52            _ => {}
53        };
54    }
55}