Expand description
Represents general musical note and allow to convert it, currently only to MIDI byte and back.
Basically, this crate just makes very good work on alteration and resolving enharmonical representation of midi notes, based on given key and scale.
At least, it works better, that built-in Reaper and MuseScore algorithms.
It uses Nederlanden language as string representation, as it is the most consistent and easy to use (and hard to mistake) note representation.
Basically:
- B is always B (there is no H)
- is — Sharp
- isis — DoubleSharp
- es (for E and A — Es and As respectively) — Flat
- eses — DoubleFlat
#Examples
use musical_note::{midi_to_note, Accidental, Key, NoteName, Octave, ResolvedNote, Scale};
let as3 = ResolvedNote::new(NoteName::A, Accidental::Flat, Octave::new(5), 68);
assert_eq!(ResolvedNote::from_str("as3").unwrap(), as3);
assert_eq!(ResolvedNote::from_str("Aes3").unwrap(), as3);
let a_moll = Key::new(NoteName::A, Accidental::White, Scale::Minor);
// automatically unwraps
let a_dur = Key::from((&"a".to_string(), Scale::Major));
let d_moll = Key::from_str("d", Scale::Minor).unwrap();
let d_dur = Key::from_str("d", Scale::Major).unwrap();
let fis_moll = Key::from_str("fis", Scale::Minor).unwrap();
let fis_dur = Key::from_str("fis", Scale::Major).unwrap();
let ais_dur = Key::from_str("ais", Scale::Major).unwrap();
let des_moll = Key::from_str("des", Scale::Minor).unwrap();
// first test against idiot mistake:
assert_eq!(
midi_to_note(60, Key::from_str("c", Scale::Major).unwrap(), None),
ResolvedNote::new(NoteName::C, Accidental::White, Octave::new(60 / 12), 60)
);
// // test on Bb2
let midi = 58u8;
assert_eq!(
midi_to_note(midi, d_moll, None),
ResolvedNote::from_str("bes2").unwrap()
);
// // test against major alteration (VI♭)
assert_eq!(
midi_to_note(midi, d_dur, None),
ResolvedNote::from_str("bes2").unwrap()
);
// // test against minor alteration (II♭)
assert_eq!(
midi_to_note(midi, a_moll, None),
ResolvedNote::from_str("bes2").unwrap()
);
assert_eq!(
midi_to_note(midi, a_dur, None),
ResolvedNote::from_str("ais2").unwrap()
);
assert_eq!(
midi_to_note(midi, a_dur, Some(Accidental::Flat)),
ResolvedNote::from_str("bes2").unwrap()
);
assert_eq!(
midi_to_note(midi, fis_moll, None),
ResolvedNote::from_str("ais2").unwrap()
);
assert_eq!(
midi_to_note(midi, fis_dur, None),
ResolvedNote::from_str("ais2").unwrap()
);
// // test against tonality doublesharps and doubleflats
assert_eq!(
midi_to_note(62, ais_dur, None),
ResolvedNote::from_str("cisis3").unwrap()
);
assert_eq!(
midi_to_note(57, des_moll, None),
ResolvedNote::from_str("beses2").unwrap()
);
// // some church scales
let c_phrygian = Key::from_str("c", Scale::Phrygian).unwrap();
assert_eq!(
midi_to_note(61, c_phrygian, None),
ResolvedNote::from_str("des3").unwrap()
);
assert_eq!(
midi_to_note(63, c_phrygian, None),
ResolvedNote::from_str("es3").unwrap()
);
let es3 = midi_to_note(63,
Key::new(
NoteName::C,
Accidental::Sharp,
Scale::Major,
),
Some(Accidental::Flat));
assert_eq!(
format!(
"{}{}{}",
es3.note.to_string(),
es3.accidental.to_string_by_note(es3.note),
es3.octave.as_midi()
),
"es3".to_string()
);
assert_eq!(
midi_to_note(65, c_phrygian, None),
ResolvedNote::from_str("f3").unwrap()
);
let fis_dorian = Key::from_str("fis", Scale::Dorian).unwrap();
assert_eq!(
midi_to_note(60, fis_dorian, None),
ResolvedNote::from_str("bis2").unwrap()
);
// // test against known bugs
assert_eq!(
midi_to_note(64, fis_dur, None),
ResolvedNote::from_str("e3").unwrap()
);
assert_eq!(
midi_to_note(62, fis_dur, None),
ResolvedNote::from_str("d3").unwrap()
);
Structs§
- Key
- Note
- Not yet resolved Note, constructed by MIDI.
- Notes
Map - Effectively maps notes to midi and backwards.
- Octave
- Resolved
Note - Represents note, that can be written in score.
- Resolved
Scale - Concrete Scale representation, based on the given root note.
Enums§
Functions§
- midi_
to_ note - Main function to convert midi to ResolvedNote.