use super::{Degree, Interval, Note, PerfectQuality, PitchClass, PitchGroup};
pub struct Matrix;
impl Matrix {
pub fn interval(pc: &PitchClass, pg: &PitchGroup) -> Option<Interval> {
use crate::types::{Interval::*, MajorQuality::*, PerfectQuality::*};
match (pc, pg) {
(PitchClass::Cn, PitchGroup::Cn) => Some(First(Perfect)),
(PitchClass::Cn, PitchGroup::Gn) => Some(Fourth(Perfect)),
(PitchClass::Cn, PitchGroup::Cs) => Some(Seventh(Major)),
(PitchClass::Cn, PitchGroup::Gs) => Some(Third(Major)),
(PitchClass::Cn, PitchGroup::Ds) => Some(Sixth(Major)),
(PitchClass::Cn, PitchGroup::As) => Some(Second(Major)),
(PitchClass::Cn, PitchGroup::Fn) => Some(Fifth(Perfect)),
(PitchClass::Cs, PitchGroup::Dn) => Some(Seventh(Major)),
(PitchClass::Cs, PitchGroup::An) => Some(Third(Major)),
(PitchClass::Cs, PitchGroup::En) => Some(Sixth(Major)),
(PitchClass::Cs, PitchGroup::Bn) => Some(Second(Major)),
(PitchClass::Cs, PitchGroup::Fs) => Some(Fifth(Perfect)),
(PitchClass::Cs, PitchGroup::Cs) => Some(First(Perfect)),
(PitchClass::Cs, PitchGroup::Gs) => Some(Fourth(Perfect)),
(PitchClass::Dn, PitchGroup::Cn) => Some(Second(Major)),
(PitchClass::Dn, PitchGroup::Gn) => Some(Fifth(Perfect)),
(PitchClass::Dn, PitchGroup::Dn) => Some(First(Perfect)),
(PitchClass::Dn, PitchGroup::An) => Some(Fourth(Perfect)),
(PitchClass::Dn, PitchGroup::Ds) => Some(Seventh(Major)),
(PitchClass::Dn, PitchGroup::As) => Some(Third(Major)),
(PitchClass::Dn, PitchGroup::Fn) => Some(Sixth(Major)),
(PitchClass::Ds, PitchGroup::En) => Some(Seventh(Major)),
(PitchClass::Ds, PitchGroup::Bn) => Some(Third(Major)),
(PitchClass::Ds, PitchGroup::Fs) => Some(Sixth(Major)),
(PitchClass::Ds, PitchGroup::Cs) => Some(Second(Major)),
(PitchClass::Ds, PitchGroup::Gs) => Some(Fifth(Perfect)),
(PitchClass::Ds, PitchGroup::Ds) => Some(First(Perfect)),
(PitchClass::Ds, PitchGroup::As) => Some(Fourth(Perfect)),
(PitchClass::En, PitchGroup::Cn) => Some(Third(Major)),
(PitchClass::En, PitchGroup::Gn) => Some(Sixth(Major)),
(PitchClass::En, PitchGroup::Dn) => Some(Second(Major)),
(PitchClass::En, PitchGroup::An) => Some(Fifth(Perfect)),
(PitchClass::En, PitchGroup::En) => Some(First(Perfect)),
(PitchClass::En, PitchGroup::Bn) => Some(Fourth(Perfect)),
(PitchClass::En, PitchGroup::Fn) => Some(Seventh(Major)),
(PitchClass::Fn, PitchGroup::Cn) => Some(Fourth(Perfect)),
(PitchClass::Fn, PitchGroup::Fs) => Some(Seventh(Major)),
(PitchClass::Fn, PitchGroup::Cs) => Some(Third(Major)),
(PitchClass::Fn, PitchGroup::Gs) => Some(Sixth(Major)),
(PitchClass::Fn, PitchGroup::Ds) => Some(Second(Major)),
(PitchClass::Fn, PitchGroup::As) => Some(Fifth(Perfect)),
(PitchClass::Fn, PitchGroup::Fn) => Some(First(Perfect)),
(PitchClass::Fs, PitchGroup::Gn) => Some(Seventh(Major)),
(PitchClass::Fs, PitchGroup::Dn) => Some(Third(Major)),
(PitchClass::Fs, PitchGroup::An) => Some(Sixth(Major)),
(PitchClass::Fs, PitchGroup::En) => Some(Second(Major)),
(PitchClass::Fs, PitchGroup::Bn) => Some(Fifth(Perfect)),
(PitchClass::Fs, PitchGroup::Fs) => Some(First(Perfect)),
(PitchClass::Fs, PitchGroup::Cs) => Some(Fourth(Perfect)),
(PitchClass::Gn, PitchGroup::Cn) => Some(Fifth(Perfect)),
(PitchClass::Gn, PitchGroup::Gn) => Some(First(Perfect)),
(PitchClass::Gn, PitchGroup::Dn) => Some(Fourth(Perfect)),
(PitchClass::Gn, PitchGroup::Gs) => Some(Seventh(Major)),
(PitchClass::Gn, PitchGroup::Ds) => Some(Third(Major)),
(PitchClass::Gn, PitchGroup::As) => Some(Sixth(Major)),
(PitchClass::Gn, PitchGroup::Fn) => Some(Second(Major)),
(PitchClass::Gs, PitchGroup::An) => Some(Seventh(Major)),
(PitchClass::Gs, PitchGroup::En) => Some(Third(Major)),
(PitchClass::Gs, PitchGroup::Bn) => Some(Sixth(Major)),
(PitchClass::Gs, PitchGroup::Fs) => Some(Second(Major)),
(PitchClass::Gs, PitchGroup::Cs) => Some(Fifth(Perfect)),
(PitchClass::Gs, PitchGroup::Gs) => Some(First(Perfect)),
(PitchClass::Gs, PitchGroup::Ds) => Some(Fourth(Perfect)),
(PitchClass::An, PitchGroup::Cn) => Some(Sixth(Major)),
(PitchClass::An, PitchGroup::Gn) => Some(Second(Major)),
(PitchClass::An, PitchGroup::Dn) => Some(Fifth(Perfect)),
(PitchClass::An, PitchGroup::An) => Some(First(Perfect)),
(PitchClass::An, PitchGroup::En) => Some(Fourth(Perfect)),
(PitchClass::An, PitchGroup::As) => Some(Seventh(Major)),
(PitchClass::An, PitchGroup::Fn) => Some(Third(Major)),
(PitchClass::As, PitchGroup::Bn) => Some(Seventh(Major)),
(PitchClass::As, PitchGroup::Fs) => Some(Third(Major)),
(PitchClass::As, PitchGroup::Cs) => Some(Sixth(Major)),
(PitchClass::As, PitchGroup::Gs) => Some(Second(Major)),
(PitchClass::As, PitchGroup::Ds) => Some(Fifth(Perfect)),
(PitchClass::As, PitchGroup::As) => Some(First(Perfect)),
(PitchClass::As, PitchGroup::Fn) => Some(Fourth(Perfect)),
(PitchClass::Bn, PitchGroup::Cn) => Some(Seventh(Major)),
(PitchClass::Bn, PitchGroup::Gn) => Some(Third(Major)),
(PitchClass::Bn, PitchGroup::Dn) => Some(Sixth(Major)),
(PitchClass::Bn, PitchGroup::An) => Some(Second(Major)),
(PitchClass::Bn, PitchGroup::En) => Some(Fifth(Perfect)),
(PitchClass::Bn, PitchGroup::Bn) => Some(First(Perfect)),
(PitchClass::Bn, PitchGroup::Fs) => Some(Fourth(Perfect)),
(_, _) => None,
}
}
pub fn degree(pc: &PitchClass, pg: &PitchGroup) -> Option<Degree> {
use crate::types::Degree::*;
match (pc, pg) {
(PitchClass::Cn, PitchGroup::Cn) => Some(Tonic),
(PitchClass::Cn, PitchGroup::Gn) => Some(Subdominant),
(PitchClass::Cn, PitchGroup::Cs) => Some(Subtonic),
(PitchClass::Cn, PitchGroup::Gs) => Some(Mediant),
(PitchClass::Cn, PitchGroup::Ds) => Some(Submediant),
(PitchClass::Cn, PitchGroup::As) => Some(Subtonic),
(PitchClass::Cn, PitchGroup::Fn) => Some(Dominant),
(PitchClass::Cs, PitchGroup::Dn) => Some(Subtonic),
(PitchClass::Cs, PitchGroup::An) => Some(Mediant),
(PitchClass::Cs, PitchGroup::En) => Some(Submediant),
(PitchClass::Cs, PitchGroup::Bn) => Some(Supertonic),
(PitchClass::Cs, PitchGroup::Fs) => Some(Dominant),
(PitchClass::Cs, PitchGroup::Cs) => Some(Tonic),
(PitchClass::Cs, PitchGroup::Gs) => Some(Subdominant),
(PitchClass::Dn, PitchGroup::Cn) => Some(Supertonic),
(PitchClass::Dn, PitchGroup::Gn) => Some(Dominant),
(PitchClass::Dn, PitchGroup::Dn) => Some(Tonic),
(PitchClass::Dn, PitchGroup::An) => Some(Subdominant),
(PitchClass::Dn, PitchGroup::Ds) => Some(Subtonic),
(PitchClass::Dn, PitchGroup::As) => Some(Mediant),
(PitchClass::Dn, PitchGroup::Fn) => Some(Submediant),
(PitchClass::Ds, PitchGroup::En) => Some(Subtonic),
(PitchClass::Ds, PitchGroup::Bn) => Some(Mediant),
(PitchClass::Ds, PitchGroup::Fs) => Some(Submediant),
(PitchClass::Ds, PitchGroup::Cs) => Some(Supertonic),
(PitchClass::Ds, PitchGroup::Gs) => Some(Dominant),
(PitchClass::Ds, PitchGroup::Ds) => Some(Tonic),
(PitchClass::Ds, PitchGroup::As) => Some(Subdominant),
(PitchClass::En, PitchGroup::Cn) => Some(Mediant),
(PitchClass::En, PitchGroup::Gn) => Some(Submediant),
(PitchClass::En, PitchGroup::Dn) => Some(Supertonic),
(PitchClass::En, PitchGroup::An) => Some(Dominant),
(PitchClass::En, PitchGroup::En) => Some(Tonic),
(PitchClass::En, PitchGroup::Bn) => Some(Subdominant),
(PitchClass::En, PitchGroup::Fn) => Some(Subtonic),
(PitchClass::Fn, PitchGroup::Cn) => Some(Subdominant),
(PitchClass::Fn, PitchGroup::Fs) => Some(Subtonic),
(PitchClass::Fn, PitchGroup::Cs) => Some(Mediant),
(PitchClass::Fn, PitchGroup::Gs) => Some(Submediant),
(PitchClass::Fn, PitchGroup::Ds) => Some(Supertonic),
(PitchClass::Fn, PitchGroup::As) => Some(Dominant),
(PitchClass::Fn, PitchGroup::Fn) => Some(Tonic),
(PitchClass::Fs, PitchGroup::Gn) => Some(Subtonic),
(PitchClass::Fs, PitchGroup::Dn) => Some(Mediant),
(PitchClass::Fs, PitchGroup::An) => Some(Submediant),
(PitchClass::Fs, PitchGroup::En) => Some(Supertonic),
(PitchClass::Fs, PitchGroup::Bn) => Some(Dominant),
(PitchClass::Fs, PitchGroup::Fs) => Some(Tonic),
(PitchClass::Fs, PitchGroup::Cs) => Some(Subdominant),
(PitchClass::Gn, PitchGroup::Cn) => Some(Dominant),
(PitchClass::Gn, PitchGroup::Gn) => Some(Tonic),
(PitchClass::Gn, PitchGroup::Dn) => Some(Subdominant),
(PitchClass::Gn, PitchGroup::Gs) => Some(Subtonic),
(PitchClass::Gn, PitchGroup::Ds) => Some(Mediant),
(PitchClass::Gn, PitchGroup::As) => Some(Submediant),
(PitchClass::Gn, PitchGroup::Fn) => Some(Supertonic),
(PitchClass::Gs, PitchGroup::An) => Some(Subtonic),
(PitchClass::Gs, PitchGroup::En) => Some(Mediant),
(PitchClass::Gs, PitchGroup::Bn) => Some(Submediant),
(PitchClass::Gs, PitchGroup::Fs) => Some(Supertonic),
(PitchClass::Gs, PitchGroup::Cs) => Some(Dominant),
(PitchClass::Gs, PitchGroup::Gs) => Some(Tonic),
(PitchClass::Gs, PitchGroup::Ds) => Some(Subdominant),
(PitchClass::An, PitchGroup::Cn) => Some(Submediant),
(PitchClass::An, PitchGroup::Gn) => Some(Supertonic),
(PitchClass::An, PitchGroup::Dn) => Some(Dominant),
(PitchClass::An, PitchGroup::An) => Some(Tonic),
(PitchClass::An, PitchGroup::En) => Some(Subdominant),
(PitchClass::An, PitchGroup::As) => Some(Subtonic),
(PitchClass::An, PitchGroup::Fn) => Some(Mediant),
(PitchClass::As, PitchGroup::Bn) => Some(Subtonic),
(PitchClass::As, PitchGroup::Fs) => Some(Mediant),
(PitchClass::As, PitchGroup::Cs) => Some(Submediant),
(PitchClass::As, PitchGroup::Gs) => Some(Supertonic),
(PitchClass::As, PitchGroup::Ds) => Some(Dominant),
(PitchClass::As, PitchGroup::As) => Some(Tonic),
(PitchClass::As, PitchGroup::Fn) => Some(Subdominant),
(PitchClass::Bn, PitchGroup::Cn) => Some(Subtonic),
(PitchClass::Bn, PitchGroup::Gn) => Some(Mediant),
(PitchClass::Bn, PitchGroup::Dn) => Some(Submediant),
(PitchClass::Bn, PitchGroup::An) => Some(Supertonic),
(PitchClass::Bn, PitchGroup::En) => Some(Dominant),
(PitchClass::Bn, PitchGroup::Bn) => Some(Tonic),
(PitchClass::Bn, PitchGroup::Fs) => Some(Subdominant),
(_, _) => None,
}
}
pub fn natural(pc: &PitchClass, pg: &PitchGroup) -> Option<Note> {
use crate::types::{Accidental::*, Note::*};
match (pc, pg) {
(PitchClass::Cn, PitchGroup::Cn) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Gn) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Cs) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Gs) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Ds) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::As) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Fn) => Some(C(Natural)),
(PitchClass::Cs, PitchGroup::Dn) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::An) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::En) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::Bn) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::Fs) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::Cs) => Some(D(Flat)),
(PitchClass::Cs, PitchGroup::Gs) => Some(D(Flat)),
(PitchClass::Dn, PitchGroup::Cn) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::Gn) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::Dn) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::An) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::Ds) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::As) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::Fn) => Some(D(Natural)),
(PitchClass::Ds, PitchGroup::En) => Some(D(Sharp)),
(PitchClass::Ds, PitchGroup::Bn) => Some(D(Sharp)),
(PitchClass::Ds, PitchGroup::Fs) => Some(D(Sharp)),
(PitchClass::Ds, PitchGroup::Cs) => Some(E(Flat)),
(PitchClass::Ds, PitchGroup::Gs) => Some(E(Flat)),
(PitchClass::Ds, PitchGroup::Ds) => Some(E(Flat)),
(PitchClass::Ds, PitchGroup::As) => Some(E(Flat)),
(PitchClass::En, PitchGroup::Cn) => Some(E(Natural)),
(PitchClass::En, PitchGroup::Gn) => Some(E(Natural)),
(PitchClass::En, PitchGroup::Dn) => Some(E(Natural)),
(PitchClass::En, PitchGroup::An) => Some(E(Natural)),
(PitchClass::En, PitchGroup::En) => Some(E(Natural)),
(PitchClass::En, PitchGroup::Bn) => Some(E(Natural)),
(PitchClass::En, PitchGroup::Fn) => Some(E(Natural)),
(PitchClass::Fn, PitchGroup::Cn) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::Fs) => Some(E(Sharp)),
(PitchClass::Fn, PitchGroup::Cs) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::Gs) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::Ds) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::As) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::Fn) => Some(F(Natural)),
(PitchClass::Fs, PitchGroup::Gn) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::Dn) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::An) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::En) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::Bn) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::Fs) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::Cs) => Some(G(Flat)),
(PitchClass::Gn, PitchGroup::Cn) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Gn) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Dn) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Gs) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Ds) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::As) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Fn) => Some(G(Natural)),
(PitchClass::Gs, PitchGroup::An) => Some(G(Sharp)),
(PitchClass::Gs, PitchGroup::En) => Some(G(Sharp)),
(PitchClass::Gs, PitchGroup::Bn) => Some(G(Sharp)),
(PitchClass::Gs, PitchGroup::Fs) => Some(G(Sharp)),
(PitchClass::Gs, PitchGroup::Cs) => Some(A(Flat)),
(PitchClass::Gs, PitchGroup::Gs) => Some(A(Flat)),
(PitchClass::Gs, PitchGroup::Ds) => Some(A(Flat)),
(PitchClass::An, PitchGroup::Cn) => Some(A(Natural)),
(PitchClass::An, PitchGroup::Gn) => Some(A(Natural)),
(PitchClass::An, PitchGroup::Dn) => Some(A(Natural)),
(PitchClass::An, PitchGroup::An) => Some(A(Natural)),
(PitchClass::An, PitchGroup::En) => Some(A(Natural)),
(PitchClass::An, PitchGroup::As) => Some(A(Natural)),
(PitchClass::An, PitchGroup::Fn) => Some(A(Natural)),
(PitchClass::As, PitchGroup::Bn) => Some(A(Sharp)),
(PitchClass::As, PitchGroup::Fs) => Some(A(Sharp)),
(PitchClass::As, PitchGroup::Cs) => Some(B(Flat)),
(PitchClass::As, PitchGroup::Gs) => Some(B(Flat)),
(PitchClass::As, PitchGroup::Ds) => Some(B(Flat)),
(PitchClass::As, PitchGroup::As) => Some(B(Flat)),
(PitchClass::As, PitchGroup::Fn) => Some(B(Flat)),
(PitchClass::Bn, PitchGroup::Cn) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::Gn) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::Dn) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::An) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::En) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::Bn) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::Fs) => Some(B(Natural)),
(_, _) => None,
}
}
pub fn sharp(pc: &PitchClass, pg: &PitchGroup) -> Option<Note> {
use crate::types::{Accidental::*, Note::*};
match (pc, pg) {
(PitchClass::Cn, PitchGroup::Cn) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Gn) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Cs) => Some(B(Sharp)),
(PitchClass::Cn, PitchGroup::Gs) => Some(B(Sharp)),
(PitchClass::Cn, PitchGroup::Ds) => Some(B(Sharp)),
(PitchClass::Cn, PitchGroup::As) => Some(B(Sharp)),
(PitchClass::Cn, PitchGroup::Fn) => Some(B(Sharp)),
(PitchClass::Cs, PitchGroup::Dn) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::An) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::En) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::Bn) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::Fs) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::Cs) => Some(C(Sharp)),
(PitchClass::Cs, PitchGroup::Gs) => Some(C(Sharp)),
(PitchClass::Dn, PitchGroup::Cn) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::Gn) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::Dn) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::An) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::Ds) => Some(C(DoubleSharp)),
(PitchClass::Dn, PitchGroup::As) => Some(C(DoubleSharp)),
(PitchClass::Dn, PitchGroup::Fn) => Some(C(DoubleSharp)),
(PitchClass::Ds, PitchGroup::En) => Some(D(Sharp)),
(PitchClass::Ds, PitchGroup::Bn) => Some(D(Sharp)),
(PitchClass::Ds, PitchGroup::Fs) => Some(D(Sharp)),
(PitchClass::Ds, PitchGroup::Cs) => Some(D(Sharp)),
(PitchClass::Ds, PitchGroup::Gs) => Some(D(Sharp)),
(PitchClass::Ds, PitchGroup::Ds) => Some(D(Sharp)),
(PitchClass::Ds, PitchGroup::As) => Some(D(Sharp)),
(PitchClass::En, PitchGroup::Cn) => Some(E(Natural)),
(PitchClass::En, PitchGroup::Gn) => Some(E(Natural)),
(PitchClass::En, PitchGroup::Dn) => Some(E(Natural)),
(PitchClass::En, PitchGroup::An) => Some(E(Natural)),
(PitchClass::En, PitchGroup::En) => Some(E(Natural)),
(PitchClass::En, PitchGroup::Bn) => Some(E(Natural)),
(PitchClass::En, PitchGroup::Fn) => Some(D(DoubleSharp)),
(PitchClass::Fn, PitchGroup::Cn) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::Fs) => Some(E(Sharp)),
(PitchClass::Fn, PitchGroup::Cs) => Some(E(Sharp)),
(PitchClass::Fn, PitchGroup::Gs) => Some(E(Sharp)),
(PitchClass::Fn, PitchGroup::Ds) => Some(E(Sharp)),
(PitchClass::Fn, PitchGroup::As) => Some(E(Sharp)),
(PitchClass::Fn, PitchGroup::Fn) => Some(E(Sharp)),
(PitchClass::Fs, PitchGroup::Gn) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::Dn) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::An) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::En) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::Bn) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::Fs) => Some(F(Sharp)),
(PitchClass::Fs, PitchGroup::Cs) => Some(F(Sharp)),
(PitchClass::Gn, PitchGroup::Cn) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Gn) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Dn) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Gs) => Some(F(DoubleSharp)),
(PitchClass::Gn, PitchGroup::Ds) => Some(F(DoubleSharp)),
(PitchClass::Gn, PitchGroup::As) => Some(F(DoubleSharp)),
(PitchClass::Gn, PitchGroup::Fn) => Some(F(DoubleSharp)),
(PitchClass::Gs, PitchGroup::An) => Some(G(Sharp)),
(PitchClass::Gs, PitchGroup::En) => Some(G(Sharp)),
(PitchClass::Gs, PitchGroup::Bn) => Some(G(Sharp)),
(PitchClass::Gs, PitchGroup::Fs) => Some(G(Sharp)),
(PitchClass::Gs, PitchGroup::Cs) => Some(G(Sharp)),
(PitchClass::Gs, PitchGroup::Gs) => Some(G(Sharp)),
(PitchClass::Gs, PitchGroup::Ds) => Some(G(Sharp)),
(PitchClass::An, PitchGroup::Cn) => Some(A(Natural)),
(PitchClass::An, PitchGroup::Gn) => Some(A(Natural)),
(PitchClass::An, PitchGroup::Dn) => Some(A(Natural)),
(PitchClass::An, PitchGroup::An) => Some(A(Natural)),
(PitchClass::An, PitchGroup::En) => Some(A(Natural)),
(PitchClass::An, PitchGroup::As) => Some(G(DoubleSharp)),
(PitchClass::An, PitchGroup::Fn) => Some(G(DoubleSharp)),
(PitchClass::As, PitchGroup::Bn) => Some(A(Sharp)),
(PitchClass::As, PitchGroup::Fs) => Some(A(Sharp)),
(PitchClass::As, PitchGroup::Cs) => Some(A(Sharp)),
(PitchClass::As, PitchGroup::Gs) => Some(A(Sharp)),
(PitchClass::As, PitchGroup::Ds) => Some(A(Sharp)),
(PitchClass::As, PitchGroup::As) => Some(A(Sharp)),
(PitchClass::As, PitchGroup::Fn) => Some(A(Sharp)),
(PitchClass::Bn, PitchGroup::Cn) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::Gn) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::Dn) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::An) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::En) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::Bn) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::Fs) => Some(B(Natural)),
(_, _) => None,
}
}
pub fn flat(pc: &PitchClass, pg: &PitchGroup) -> Option<Note> {
use crate::types::{Accidental::*, Note::*};
match (pc, pg) {
(PitchClass::Cn, PitchGroup::Cn) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Gn) => Some(D(DoubleFlat)),
(PitchClass::Cn, PitchGroup::Cs) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Gs) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Ds) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::As) => Some(C(Natural)),
(PitchClass::Cn, PitchGroup::Fn) => Some(C(Natural)),
(PitchClass::Cs, PitchGroup::Dn) => Some(D(Flat)),
(PitchClass::Cs, PitchGroup::An) => Some(D(Flat)),
(PitchClass::Cs, PitchGroup::En) => Some(D(Flat)),
(PitchClass::Cs, PitchGroup::Bn) => Some(D(Flat)),
(PitchClass::Cs, PitchGroup::Fs) => Some(D(Flat)),
(PitchClass::Cs, PitchGroup::Cs) => Some(D(Flat)),
(PitchClass::Cs, PitchGroup::Gs) => Some(D(Flat)),
(PitchClass::Dn, PitchGroup::Cn) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::Gn) => Some(E(DoubleFlat)),
(PitchClass::Dn, PitchGroup::Dn) => Some(E(DoubleFlat)),
(PitchClass::Dn, PitchGroup::An) => Some(E(DoubleFlat)),
(PitchClass::Dn, PitchGroup::Ds) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::As) => Some(D(Natural)),
(PitchClass::Dn, PitchGroup::Fn) => Some(D(Natural)),
(PitchClass::Ds, PitchGroup::En) => Some(E(Flat)),
(PitchClass::Ds, PitchGroup::Bn) => Some(E(Flat)),
(PitchClass::Ds, PitchGroup::Fs) => Some(E(Flat)),
(PitchClass::Ds, PitchGroup::Cs) => Some(E(Flat)),
(PitchClass::Ds, PitchGroup::Gs) => Some(E(Flat)),
(PitchClass::Ds, PitchGroup::Ds) => Some(E(Flat)),
(PitchClass::Ds, PitchGroup::As) => Some(E(Flat)),
(PitchClass::En, PitchGroup::Cn) => Some(E(Natural)),
(PitchClass::En, PitchGroup::Gn) => Some(F(Flat)),
(PitchClass::En, PitchGroup::Dn) => Some(F(Flat)),
(PitchClass::En, PitchGroup::An) => Some(F(Flat)),
(PitchClass::En, PitchGroup::En) => Some(F(Flat)),
(PitchClass::En, PitchGroup::Bn) => Some(F(Flat)),
(PitchClass::En, PitchGroup::Fn) => Some(E(Natural)),
(PitchClass::Fn, PitchGroup::Cn) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::Fs) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::Cs) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::Gs) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::Ds) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::As) => Some(F(Natural)),
(PitchClass::Fn, PitchGroup::Fn) => Some(F(Natural)),
(PitchClass::Fs, PitchGroup::Gn) => Some(G(Flat)),
(PitchClass::Fs, PitchGroup::Dn) => Some(G(Flat)),
(PitchClass::Fs, PitchGroup::An) => Some(G(Flat)),
(PitchClass::Fs, PitchGroup::En) => Some(G(Flat)),
(PitchClass::Fs, PitchGroup::Bn) => Some(G(Flat)),
(PitchClass::Fs, PitchGroup::Fs) => Some(G(Flat)),
(PitchClass::Fs, PitchGroup::Cs) => Some(G(Flat)),
(PitchClass::Gn, PitchGroup::Cn) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Gn) => Some(A(DoubleFlat)),
(PitchClass::Gn, PitchGroup::Dn) => Some(A(DoubleFlat)),
(PitchClass::Gn, PitchGroup::Gs) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Ds) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::As) => Some(G(Natural)),
(PitchClass::Gn, PitchGroup::Fn) => Some(G(Natural)),
(PitchClass::Gs, PitchGroup::An) => Some(A(Flat)),
(PitchClass::Gs, PitchGroup::En) => Some(A(Flat)),
(PitchClass::Gs, PitchGroup::Bn) => Some(A(Flat)),
(PitchClass::Gs, PitchGroup::Fs) => Some(A(Flat)),
(PitchClass::Gs, PitchGroup::Cs) => Some(A(Flat)),
(PitchClass::Gs, PitchGroup::Gs) => Some(A(Flat)),
(PitchClass::Gs, PitchGroup::Ds) => Some(A(Flat)),
(PitchClass::An, PitchGroup::Cn) => Some(A(Natural)),
(PitchClass::An, PitchGroup::Gn) => Some(B(DoubleFlat)),
(PitchClass::An, PitchGroup::Dn) => Some(B(DoubleFlat)),
(PitchClass::An, PitchGroup::An) => Some(B(DoubleFlat)),
(PitchClass::An, PitchGroup::En) => Some(B(DoubleFlat)),
(PitchClass::An, PitchGroup::As) => Some(A(Natural)),
(PitchClass::An, PitchGroup::Fn) => Some(A(Natural)),
(PitchClass::As, PitchGroup::Bn) => Some(B(Flat)),
(PitchClass::As, PitchGroup::Fs) => Some(B(Flat)),
(PitchClass::As, PitchGroup::Cs) => Some(B(Flat)),
(PitchClass::As, PitchGroup::Gs) => Some(B(Flat)),
(PitchClass::As, PitchGroup::Ds) => Some(B(Flat)),
(PitchClass::As, PitchGroup::As) => Some(B(Flat)),
(PitchClass::As, PitchGroup::Fn) => Some(B(Flat)),
(PitchClass::Bn, PitchGroup::Cn) => Some(B(Natural)),
(PitchClass::Bn, PitchGroup::Gn) => Some(C(Flat)),
(PitchClass::Bn, PitchGroup::Dn) => Some(C(Flat)),
(PitchClass::Bn, PitchGroup::An) => Some(C(Flat)),
(PitchClass::Bn, PitchGroup::En) => Some(C(Flat)),
(PitchClass::Bn, PitchGroup::Bn) => Some(C(Flat)),
(PitchClass::Bn, PitchGroup::Fs) => Some(C(Flat)),
(_, _) => None,
}
}
}
#[cfg(test)]
mod tests {
use super::{Matrix, PitchClass, PitchGroup};
#[test]
fn print_natural_matrix() {
println!("Natural Key Matrix");
print!(" ");
for x in 0u8..12 {
print!(" {:<2}", x)
}
println!();
print!(" ");
for x in 0u8..12 {
let pc = PitchClass::from_index(x);
print!(" {:>2}", pc)
}
println!();
for y in 0..12 {
let pg = PitchGroup::from_index(y);
print!(" {:>3} {:>3}", y, pg);
for x in 0..12 {
let pc = PitchClass::from_index(x);
if let Some(note) = Matrix::natural(&pc, &pg) {
print!(" {:<3}", note.to_string());
} else {
print!(" ");
}
}
println!();
}
println!();
}
#[test]
fn print_sharps_matrix() {
println!("Sharp Key Matrix");
print!(" ");
for x in 0u8..12 {
print!(" {:<2}", x)
}
println!();
print!(" ");
for x in 0u8..12 {
let pc = PitchClass::from_index(x);
print!(" {:>2}", pc)
}
println!();
for y in 0..12 {
let pg = PitchGroup::from_index(y);
print!(" {:>3} {:>3}", y, pg);
for x in 0..12 {
let pc = PitchClass::from_index(x);
if let Some(note) = Matrix::sharp(&pc, &pg) {
print!(" {:<3}", note.to_string());
} else {
print!(" ");
}
}
println!();
}
println!();
}
#[test]
fn print_flats_matrix() {
println!("Flat Key Matrix");
print!(" ");
for x in 0u8..12 {
print!(" {:<2}", x)
}
println!();
print!(" ");
for x in 0u8..12 {
let pc = PitchClass::from_index(x);
print!(" {:>2}", pc)
}
println!();
for y in 0..12 {
let pg = PitchGroup::from_index(y);
print!(" {:>3} {:>3}", y, pg);
for x in 0..12 {
let pc = PitchClass::from_index(x);
if let Some(note) = Matrix::flat(&pc, &pg) {
print!(" {:<3}", note.to_string());
} else {
print!(" ");
}
}
println!();
}
println!();
}
#[test]
fn print_intervals_scale() {
println!("Interval Key Matrix");
print!(" ");
for x in 0u8..12 {
print!(" {:<2}", x)
}
println!();
print!(" ");
for x in 0u8..12 {
let pc = PitchClass::from_index(x);
print!(" {:>2}", pc)
}
println!();
for y in 0..12 {
let pg = PitchGroup::from_index(y);
print!(" {:>3} {:>3}", y, pg);
for x in 0..12 {
let pc = PitchClass::from_index(x);
if let Some(note) = Matrix::interval(&pc, &pg) {
print!(" {:<3}", note.to_string());
} else {
print!(" ");
}
}
println!();
}
println!();
}
}