Browse and listen to thousands of radio stations across the globe right from your terminal ๐ŸŒŽ ๐Ÿ“ป ๐ŸŽตโœจ
radio rust tokio web-radio command-line-tool tui
at main 2.6 kB view raw
1use std::{num::ParseIntError, str::FromStr}; 2 3#[derive(Debug, PartialEq, Clone)] 4pub enum Tone { 5 C, 6 Db, 7 D, 8 Eb, 9 E, 10 F, 11 Gb, 12 G, 13 Ab, 14 A, 15 Bb, 16 B, 17} 18 19#[derive(Debug, thiserror::Error, derive_more::Display)] 20pub struct ToneError(); 21 22#[derive(Debug, PartialEq, Clone)] 23pub struct Note { 24 tone: Tone, 25 octave: u32, 26} 27 28#[derive(Debug, thiserror::Error, derive_more::From, derive_more::Display)] 29pub enum NoteError { 30 InvalidOctave(ParseIntError), 31 InalidNote(ToneError), 32} 33 34impl FromStr for Note { 35 type Err = NoteError; 36 37 fn from_str(txt: &str) -> Result<Self, Self::Err> { 38 let trimmed = txt.trim(); 39 let mut split = 0; 40 for c in trimmed.chars() { 41 if !c.is_ascii_digit() { 42 split += 1; 43 } else { 44 break; 45 } 46 } 47 Ok(Note { 48 tone: trimmed[..split].parse::<Tone>()?, 49 octave: trimmed[split..].parse::<u32>().unwrap_or(0), 50 }) 51 } 52} 53 54impl FromStr for Tone { 55 type Err = ToneError; 56 57 fn from_str(txt: &str) -> Result<Self, Self::Err> { 58 match txt { 59 "C" => Ok(Tone::C), 60 "C#" | "Db" => Ok(Tone::Db), 61 "D" => Ok(Tone::D), 62 "D#" | "Eb" => Ok(Tone::Eb), 63 "E" => Ok(Tone::E), 64 "F" => Ok(Tone::F), 65 "F#" | "Gb" => Ok(Tone::Gb), 66 "G" => Ok(Tone::G), 67 "G#" | "Ab" => Ok(Tone::Ab), 68 "A" => Ok(Tone::A), 69 "A#" | "Bb" => Ok(Tone::Bb), 70 "B" => Ok(Tone::B), 71 _ => Err(ToneError()), 72 } 73 } 74} 75 76impl Note { 77 pub fn tune_buffer_size(&self, sample_rate: u32) -> u32 { 78 let t = 1.0 / self.tone.freq(self.octave); // periodo ? 79 let buf = (sample_rate as f32) * t; 80 buf.round() as u32 81 } 82} 83 84impl Tone { 85 pub fn freq(&self, octave: u32) -> f32 { 86 match octave { 87 0 => match self { 88 Tone::C => 16.35, 89 Tone::Db => 17.32, 90 Tone::D => 18.35, 91 Tone::Eb => 19.45, 92 Tone::E => 20.60, 93 Tone::F => 21.83, 94 Tone::Gb => 23.12, 95 Tone::G => 24.50, 96 Tone::Ab => 25.96, 97 Tone::A => 27.50, 98 Tone::Bb => 29.14, 99 Tone::B => 30.87, 100 }, 101 _ => { 102 let mut freq = self.freq(0); 103 for _ in 0..octave { 104 freq *= 2.0; 105 } 106 freq 107 } 108 } 109 } 110}