use crate::error::{PulseError, PulseResult};
pub fn frequency_to_midi_note(frequency: f32) -> PulseResult<u8> {
if !frequency.is_finite() || frequency <= 0.0 {
return Err(PulseError::InvalidFrequency { frequency });
}
Ok(tunes::midi::frequency_to_midi_note(frequency))
}
pub fn midi_note_to_frequency(note: i64) -> PulseResult<f32> {
if !(0..=127).contains(¬e) {
return Err(PulseError::InvalidMidiNote { note });
}
let note = u8::try_from(note).map_err(|_| PulseError::InvalidMidiNote { note })?;
Ok(tunes::midi::midi_note_to_frequency(note))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn converts_between_frequency_and_midi_notes() {
assert_eq!(frequency_to_midi_note(440.0).unwrap(), 69);
assert!((midi_note_to_frequency(69).unwrap() - 440.0).abs() < 0.01);
}
#[test]
fn rejects_invalid_midi_inputs() {
assert_eq!(
midi_note_to_frequency(200).unwrap_err().to_string(),
"invalid midi note: 200"
);
assert_eq!(
frequency_to_midi_note(f32::NAN).unwrap_err().to_string(),
"invalid frequency: NaN"
);
assert_eq!(
frequency_to_midi_note(0.0).unwrap_err().to_string(),
"invalid frequency: 0"
);
assert_eq!(
frequency_to_midi_note(-440.0).unwrap_err().to_string(),
"invalid frequency: -440"
);
}
}