old school music tracker audio backend
at dev 88 lines 2.0 kB view raw
1use core::fmt::{Display, Write}; 2 3use crate::project::event_command::NoteCommand; 4 5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] 6pub struct Note(u8); 7 8impl Note { 9 pub fn new(value: u8) -> Result<Note, u8> { 10 if value > 199 { 11 Err(value) 12 } else { 13 Ok(Note(value)) 14 } 15 } 16 17 pub const fn get_octave(self) -> u8 { 18 self.0 / 12 19 } 20 21 pub const fn get_note_name(self) -> &'static str { 22 match self.0 % 12 { 23 0 => "C", 24 1 => "C#", 25 2 => "D", 26 3 => "D#", 27 4 => "E", 28 5 => "F", 29 6 => "F#", 30 7 => "G", 31 8 => "G#", 32 9 => "A", 33 10 => "A#", 34 11 => "B", 35 _ => panic!(), 36 } 37 } 38 39 pub fn get_frequency(self) -> f32 { 40 // taken from https://en.wikipedia.org/wiki/MIDI_tuning_standard 41 440. * ((f32::from(self.0) - 69.) / 12.).exp2() 42 } 43 44 pub const fn get(self) -> u8 { 45 self.0 46 } 47} 48 49impl Display for Note { 50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 51 f.write_str(self.get_note_name())?; 52 f.write_char('-')?; 53 self.get_octave().fmt(f)?; 54 Ok(()) 55 } 56} 57 58impl Default for Note { 59 fn default() -> Self { 60 Self(60) // C-5 61 } 62} 63 64#[derive(Clone, Copy, Debug, Default)] 65pub struct NoteEvent { 66 pub note: Note, 67 pub sample_instr: u8, 68 pub vol: VolumeEffect, 69 pub command: NoteCommand, 70} 71 72#[derive(Debug, Clone, Copy, Default)] 73pub enum VolumeEffect { 74 FineVolSlideUp(u8), 75 FineVolSlideDown(u8), 76 VolSlideUp(u8), 77 VolSlideDown(u8), 78 PitchSlideUp(u8), 79 PitchSlideDown(u8), 80 SlideToNoteWithSpeed(u8), 81 VibratoWithSpeed(u8), 82 Volume(u8), 83 Panning(u8), 84 /// Uses Instr / Sample Default Volume 85 // TODO: figure out if i want to have that in here or if i want to use it with Option around it 86 #[default] 87 None, 88}