1
0
Fork 0

Clean up i32 note formatters

This commit is contained in:
Robbert van der Helm 2022-03-21 14:40:17 +01:00
parent e90bfecc0b
commit 0f60ce9609
2 changed files with 21 additions and 21 deletions

View file

@ -110,32 +110,29 @@ pub fn from_i32_power_of_two() -> Arc<dyn Fn(&str) -> Option<i32> + Send + Sync>
Arc::new(|string| string.parse().ok().map(|n: i32| (n as f32).log2() as i32)) Arc::new(|string| string.parse().ok().map(|n: i32| (n as f32).log2() as i32))
} }
const NOTES: [&str; 12] = [ /// Turns an integer MIDI note number (usually in the range [0, 127]) into a note name, where 60 is
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", /// C4 and 69 is A4 (nice).
];
/// Turns an integer midi number (range 0-127 usually) into a note name, e.g. 69 -> A4
pub fn i32_note_formatter() -> Arc<dyn Fn(i32) -> String + Send + Sync> { pub fn i32_note_formatter() -> Arc<dyn Fn(i32) -> String + Send + Sync> {
Arc::new(move |x| { Arc::new(move |value| {
let note = x as usize; let note_name = util::NOTES[value as usize % 12];
let note_name = NOTES[note % 12].to_string(); let octave = (value / 12) - 1;
let octave = (note / 12) as i32 - 1;
format!("{note_name}{octave}") format!("{note_name}{octave}")
}) })
} }
/// parses a note name into a midi number (range 0-127 usually), e.g. A#4 -> 70
/// Parse a note name to a MIDI number using the inverse mapping from [`i32_note_formatter`].
pub fn from_i32_note_formatter() -> Arc<dyn Fn(&str) -> Option<i32> + Send + Sync> { pub fn from_i32_note_formatter() -> Arc<dyn Fn(&str) -> Option<i32> + Send + Sync> {
Arc::new(|string| { Arc::new(|string| {
// string is too short to be a note name let (note_name, octave) = string
if string.len() < 2 { .trim()
return None; .split_once(|c: char| c.is_whitespace() || c.is_digit(10))?;
}
let (note_name, octave) = if string.contains("#") { let note_id = util::NOTES
string.split_at(2) .iter()
} else { .position(|&candidate| note_name.eq_ignore_ascii_case(candidate))?
string.split_at(1) as i32;
}; let octave: i32 = octave.trim().parse().ok()?;
// using unwrap_or here, or else trying to parse "##" breaks it
let note = NOTES.iter().position(|&r| r == note_name).unwrap_or(0) as i32; Some((octave + 1) + (12 * note_id))
octave.parse().ok().map(|n: i32| (n + 1) * 12 + note)
}) })
} }

View file

@ -6,6 +6,9 @@ pub mod window;
pub use stft::StftHelper; pub use stft::StftHelper;
pub const MINUS_INFINITY_DB: f32 = -100.0; pub const MINUS_INFINITY_DB: f32 = -100.0;
pub const NOTES: [&str; 12] = [
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
];
/// Temporarily allow allocations within `func` if NIH-plug was configured with the /// Temporarily allow allocations within `func` if NIH-plug was configured with the
/// `assert_process_allocs` feature. /// `assert_process_allocs` feature.