Skip to content

Commit

Permalink
Merge dee576d into 7cff5d6
Browse files Browse the repository at this point in the history
  • Loading branch information
henryksloan committed Aug 23, 2020
2 parents 7cff5d6 + dee576d commit a722e26
Show file tree
Hide file tree
Showing 17 changed files with 461 additions and 385 deletions.
24 changes: 12 additions & 12 deletions src/chord/chord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use crate::chord::errors::ChordError;
use crate::chord::number::Number::Triad;
use crate::chord::{Number, Quality};
use crate::interval::Interval;
use crate::note::{Note, NoteError, Notes, PitchClass};
use crate::note::{Note, NoteError, Notes, Pitch, NoteLetter};

/// A chord.
#[derive(Debug, Clone)]
pub struct Chord {
/// The root note of the chord.
pub root: PitchClass,
pub root: Pitch,
/// The octave of the root note of the chord.
pub octave: u8,
/// The intervals within the chord.
Expand All @@ -23,13 +23,13 @@ pub struct Chord {

impl Chord {
/// Create a new chord.
pub fn new(root: PitchClass, quality: Quality, number: Number) -> Self {
pub fn new(root: Pitch, quality: Quality, number: Number) -> Self {
Self::with_inversion(root, quality, number, 0)
}

/// Create a new chord with a given inversion.
pub fn with_inversion(
root: PitchClass,
root: Pitch,
quality: Quality,
number: Number,
inversion: u8,
Expand Down Expand Up @@ -79,11 +79,11 @@ impl Chord {

/// Parse a chord using a regex.
pub fn from_regex(string: &str) -> Result<Self, ChordError> {
let (pitch_class, pitch_match) = PitchClass::from_regex(&string)?;
let (pitch, pitch_match) = Pitch::from_regex(&string)?;

let slash_option = string.find('/');
let bass_note_result = if let Some(slash) = slash_option {
PitchClass::from_regex(&string[slash + 1..].trim())
Pitch::from_regex(&string[slash + 1..].trim())
} else {
Err(NoteError::InvalidPitch)
};
Expand All @@ -106,7 +106,7 @@ impl Chord {
};

let chord = Chord::with_inversion(
pitch_class,
pitch,
quality,
number,
inversion_num_option.unwrap_or(0),
Expand All @@ -116,12 +116,12 @@ impl Chord {
let inversion = chord
.notes()
.iter()
.position(|note| note.pitch_class == bass_note)
.position(|note| note.pitch == bass_note)
.unwrap_or(0);

if inversion != 0 {
return Ok(Chord::with_inversion(
pitch_class,
pitch,
quality,
number,
inversion as u8,
Expand All @@ -136,8 +136,8 @@ impl Chord {
impl Notes for Chord {
fn notes(&self) -> Vec<Note> {
let root_note = Note {
pitch: self.root,
octave: self.octave,
pitch_class: self.root,
};
let mut notes = Interval::to_notes(root_note, self.intervals.clone());
notes.rotate_left(self.inversion as usize);
Expand All @@ -150,7 +150,7 @@ impl Notes for Chord {

// Ensure that octave increments at the right notes
for i in 1..notes.len() {
if notes[i].pitch_class as u8 <= notes[i - 1].pitch_class as u8 {
if notes[i].pitch.into_u8() <= notes[i - 1].pitch.into_u8() {
notes[i].octave = notes[i - 1].octave + 1;
} else if notes[i].octave < notes[i - 1].octave {
notes[i].octave = notes[i - 1].octave;
Expand All @@ -163,7 +163,7 @@ impl Notes for Chord {
impl Default for Chord {
fn default() -> Self {
Chord {
root: PitchClass::C,
root: Pitch { letter: NoteLetter::C, accidental: 0 },
octave: 4,
intervals: vec![],
quality: Quality::Major,
Expand Down
18 changes: 9 additions & 9 deletions src/interval/interval.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::interval::errors::IntervalError;
use crate::note::{Note, PitchClass};
use crate::note::{Note, Pitch};
use strum_macros::Display;

/// The quality of an interval; major, minor, etc.
Expand Down Expand Up @@ -172,26 +172,26 @@ impl Interval {

/// Move the given note up by this interval.
pub fn second_note_from(self, first_note: Note) -> Note {
let pitch_class = PitchClass::from_interval(first_note.pitch_class, self);
let pitch = Pitch::from_interval(first_note.pitch, self);
let octave = first_note.octave;
let excess_octave = (first_note.pitch_class as u8 + self.semitone_count) / 12;
let excess_octave = (first_note.pitch.into_u8() + self.semitone_count) / 12;

Note {
octave: octave + excess_octave,
pitch_class,
pitch,
}
}

/// Move the given note down by this interval.
pub fn second_note_down_from(self, first_note: Note) -> Note {
let pitch_class = PitchClass::from_interval_down(first_note.pitch_class, self);
let pitch = Pitch::from_interval_down(first_note.pitch, self);
let octave = first_note.octave;
let raw_diff = first_note.pitch_class as i16 - self.semitone_count as i16;
let raw_diff = first_note.pitch.into_u8() as i16 - self.semitone_count as i16;
let excess_octave = (raw_diff / -12) + if raw_diff < 0 { 1 } else { 0 };

Note {
octave: octave - excess_octave as u8,
pitch_class,
pitch,
}
}

Expand All @@ -201,7 +201,7 @@ impl Interval {

for interval in intervals {
let last_note = notes.last().unwrap();
let interval_first_note = Note::new(last_note.pitch_class, last_note.octave);
let interval_first_note = Note::new(last_note.pitch, last_note.octave);
let interval_second_note = interval.second_note_from(interval_first_note);
notes.push(interval_second_note);
}
Expand All @@ -223,7 +223,7 @@ impl Interval {
.rev();
for interval in reversed {
let last_note = notes.last().unwrap();
let interval_first_note = Note::new(last_note.pitch_class, last_note.octave);
let interval_first_note = Note::new(last_note.pitch, last_note.octave);
let interval_second_note = interval.second_note_down_from(interval_first_note);
notes.push(interval_second_note);
}
Expand Down
10 changes: 5 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
//!
//! ```no_run
//! extern crate rust_music_theory as rustmt;
//! use rustmt::note::{Note, Notes, PitchClass};
//! use rustmt::note::{Note, Notes, Pitch, PitchSymbol::*};
//! use rustmt::scale::{Direction, Scale, ScaleType, Mode};
//! use rustmt::chord::{Chord, Number as ChordNumber, Quality as ChordQuality};
//!
//! // to create a Note, specify a pitch class and an octave;
//! let note = Note::new(PitchClass::As, 4);
//! // Note { pitch_class: A, octave: 4 }
//! let note = Note::new(Pitch::from(As), 4);
//! // Note { Pitch::new(NoteLetter::A, 1), octave: 4 }
//!
//! // Scale Example;
//! let scale = Scale::new(
//! ScaleType::Diatonic, // scale type
//! PitchClass::C, // tonic
//! Pitch::from(C), // tonic
//! 4, // octave
//! Some(Mode::Ionian), // scale mode
//! Direction::Ascending, // direction
Expand All @@ -35,7 +35,7 @@
//! let scale_notes = scale.notes();
//!
//! // Chord Example;
//! let chord = Chord::new(PitchClass::C, ChordQuality::Major, ChordNumber::Triad);
//! let chord = Chord::new(Pitch::from(C), ChordQuality::Major, ChordNumber::Triad);
//!
//! // returns a Vector of the Notes of the chord
//! let chord_notes = chord.notes();
Expand Down
6 changes: 4 additions & 2 deletions src/note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

mod errors;
mod note;
mod pitch_class;
mod pitch;
mod pitch_symbol;

pub use errors::NoteError;
pub use note::{Note, Notes};
pub use pitch_class::PitchClass;
pub use pitch::{Pitch, NoteLetter};
pub use pitch_symbol::PitchSymbol;
14 changes: 7 additions & 7 deletions src/note/note.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
use crate::note::PitchClass;
use crate::note::Pitch;
use std::fmt;
use std::fmt::Formatter;

/// A note.
#[derive(Debug, Clone)]
pub struct Note {
/// The pitch class of the note (A, B, C#, etc).
pub pitch_class: PitchClass,
/// The pitch of the note (A, B, C#, etc).
pub pitch: Pitch,
/// The octave of the note in standard notation.
pub octave: u8,
}

impl Note {
/// Create a new note.
pub fn new(pitch_class: PitchClass, octave: u8) -> Self {
pub fn new(pitch: Pitch, octave: u8) -> Self {
Note {
pitch_class,
pitch,
octave,
}
}
}

impl fmt::Display for Note {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.pitch_class)
write!(f, "{}", self.pitch)
}
}

Expand All @@ -47,7 +47,7 @@ pub trait Notes {

println!("Notes:");
for (i, note) in notes.iter().enumerate() {
println!(" {}: {}", i + 1, note.pitch_class)
println!(" {}: {}", i + 1, note.pitch)
}
}
}

0 comments on commit a722e26

Please sign in to comment.