a simple (oscillo|vector|spectro)-scope for your terminal
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101use std::{num::ParseIntError, str::FromStr};
#[rustfmt::skip]#[derive(Debug, PartialEq, Clone)]pub enum Tone { C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B,}
#[derive(Debug, thiserror::Error, derive_more::Display)]pub struct ToneError();
#[derive(Debug, PartialEq, Clone)]pub struct Note { tone: Tone, octave: u32,}
#[derive(Debug, thiserror::Error, derive_more::From, derive_more::Display)]pub enum NoteError { InvalidOctave(ParseIntError), InalidNote(ToneError),}
impl FromStr for Note { type Err = NoteError;
fn from_str(txt: &str) -> Result<Self, Self::Err> { let trimmed = txt.trim(); let mut split = 0; for c in trimmed.chars() { if !c.is_ascii_digit() { split += 1; } else { break; } } Ok(Note { tone: trimmed[..split].parse::<Tone>()?, octave: trimmed[split..].parse::<u32>().unwrap_or(0), }) }}
impl FromStr for Tone { type Err = ToneError;
fn from_str(txt: &str) -> Result<Self, Self::Err> { match txt { "C" => Ok(Tone::C), "C#" | "Db" => Ok(Tone::Db), "D" => Ok(Tone::D), "D#" | "Eb" => Ok(Tone::Eb), "E" => Ok(Tone::E), "F" => Ok(Tone::F), "F#" | "Gb" => Ok(Tone::Gb), "G" => Ok(Tone::G), "G#" | "Ab" => Ok(Tone::Ab), "A" => Ok(Tone::A), "A#" | "Bb" => Ok(Tone::Bb), "B" => Ok(Tone::B), _ => Err(ToneError()), } }}
impl Note { pub fn tune_buffer_size(&self, sample_rate: u32) -> u32 { let t = 1.0 / self.tone.freq(self.octave); // periodo ? let buf = (sample_rate as f32) * t; buf.round() as u32 }}
impl Tone { pub fn freq(&self, octave: u32) -> f32 { match octave { 0 => match self { Tone::C => 16.35, Tone::Db => 17.32, Tone::D => 18.35, Tone::Eb => 19.45, Tone::E => 20.60, Tone::F => 21.83, Tone::Gb => 23.12, Tone::G => 24.50, Tone::Ab => 25.96, Tone::A => 27.50, Tone::Bb => 29.14, Tone::B => 30.87, }, _ => { let mut freq = self.freq(0); for _ in 0..octave { freq *= 2.0; } freq } } }}