1use 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 self.level = 0.0;
45 }
46 0x90 => {
47 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}