diff --git a/src/music/mod.rs b/src/music/mod.rs index 292fdcf..3288ca8 100644 --- a/src/music/mod.rs +++ b/src/music/mod.rs @@ -40,9 +40,27 @@ impl
Primitive
{
pub type PlayerName = String;
#[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)]
-pub enum Mode {
- Major,
- Minor,
+pub enum KeySig {
+ Major(PitchClass),
+ Minor(PitchClass),
+}
+
+impl Default for KeySig {
+ fn default() -> Self {
+ // the white piano keys
+ Self::Major(PitchClass::C)
+ }
+}
+
+impl KeySig {
+ pub fn get_scale(self) -> impl Iterator Music {
self.with(Control::Player(name))
}
- pub fn with_key_sig(self, pitch_class: PitchClass, mode: Mode) -> Self {
- self.with(Control::KeySig(pitch_class, mode))
+ pub fn with_key_sig(self, key_signature: KeySig) -> Self {
+ self.with(Control::KeySig(key_signature))
}
pub fn duration(&self) -> Dur {
@@ -375,4 +393,40 @@ mod tests {
let pitch = Pitch::C(Octave(-4));
assert_is_close_freq(pitch.get_frequency(), 1.022);
}
+
+ #[test]
+ fn key_sig_c_major_scale() {
+ let scale: Vec<_> = KeySig::Major(PitchClass::C).get_scale().collect();
+ assert_eq!(
+ scale,
+ [
+ PitchClass::C,
+ PitchClass::D,
+ PitchClass::E,
+ PitchClass::F,
+ PitchClass::G,
+ PitchClass::A,
+ PitchClass::B,
+ PitchClass::C,
+ ]
+ );
+ }
+
+ #[test]
+ fn key_sig_g_major_scale() {
+ let scale: Vec<_> = KeySig::Major(PitchClass::G).get_scale().collect();
+ assert_eq!(
+ scale,
+ [
+ PitchClass::G,
+ PitchClass::A,
+ PitchClass::B,
+ PitchClass::C,
+ PitchClass::D,
+ PitchClass::E,
+ PitchClass::Fs,
+ PitchClass::G,
+ ]
+ );
+ }
}
diff --git a/src/music/performance.rs b/src/music/performance.rs
index 3eb9d15..3de4832 100644
--- a/src/music/performance.rs
+++ b/src/music/performance.rs
@@ -7,8 +7,8 @@ use ordered_float::OrderedFloat;
use crate::instruments::InstrumentName;
use super::{
- duration::Dur, interval::AbsPitch, phrases::PhraseAttribute, pitch::PitchClass, Control, Mode,
- Music, PlayerName, Primitive, Volume,
+ duration::Dur, interval::AbsPitch, phrases::PhraseAttribute, Control, KeySig, Music,
+ PlayerName, Primitive, Volume,
};
#[derive(Debug)]
@@ -84,8 +84,8 @@ where
ctx.player = player;
m.perf(players, ctx)
}
- Self::Modify(Control::KeySig(pc, mode), m) => {
- ctx.key = (*pc, *mode);
+ Self::Modify(Control::KeySig(ks), m) => {
+ ctx.key = *ks;
m.perf(players, ctx)
}
}
@@ -126,7 +126,7 @@ pub struct Context<'p, P> {
whole_note: Duration,
pitch: AbsPitch,
volume: Volume,
- key: (PitchClass, Mode),
+ key: KeySig,
}
impl<'p, P> Clone for Context<'p, P> {
@@ -495,7 +495,7 @@ mod defaults {
whole_note: metro(120, Dur::QN),
pitch: AbsPitch::from(0),
volume: Volume::loudest(),
- key: (PitchClass::C, Mode::Major),
+ key: KeySig::default(),
}
}
}