Skip to content

Commit

Permalink
src: add functions to create sequences and chords from pitches
Browse files Browse the repository at this point in the history
  • Loading branch information
paveyry committed Sep 8, 2023
1 parent b6afefb commit 02e97ec
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 53 deletions.
8 changes: 5 additions & 3 deletions examples/praeludium_no1_multi_phrase.rs
Expand Up @@ -50,9 +50,11 @@ fn right_hand() -> Result<Phrase> {
for _ in 0..=1 {
right_hand.add_rest(QUAVER);
for _ in 0..=1 {
right_hand.add_note(Note::new(pitch1, SEMIQUAVER, MF)?);
right_hand.add_note(Note::new(pitch2, SEMIQUAVER, MF)?);
right_hand.add_note(Note::new(pitch3, SEMIQUAVER, MF)?);
right_hand.add_sequential_notes(Note::new_sequence(
SEMIQUAVER,
MF,
&[pitch1, pitch2, pitch3],
))?;
}
}
Ok(())
Expand Down
8 changes: 5 additions & 3 deletions examples/praeludium_no1_organ_piano.rs
Expand Up @@ -48,9 +48,11 @@ fn right_hand() -> Result<Phrase> {
for _ in 0..=1 {
right_hand.add_rest(QUAVER);
for _ in 0..=1 {
right_hand.add_note(Note::new(pitch1, SEMIQUAVER, MF)?);
right_hand.add_note(Note::new(pitch2, SEMIQUAVER, MF)?);
right_hand.add_note(Note::new(pitch3, SEMIQUAVER, MF)?);
right_hand.add_sequential_notes(Note::new_sequence(
SEMIQUAVER,
MF,
&[pitch1, pitch2, pitch3],
))?;
}
}
Ok(())
Expand Down
8 changes: 5 additions & 3 deletions examples/praeludium_no1_single_phrase.rs
Expand Up @@ -45,9 +45,11 @@ fn phrase() -> Result<Phrase> {
vec![Note::new(pitch2, DOTTED_QUAVER + CROTCHET, MF)?],
)?);
for _ in 0..=1 {
phrase.add_note(Note::new(pitch3, SEMIQUAVER, MF)?);
phrase.add_note(Note::new(pitch4, SEMIQUAVER, MF)?);
phrase.add_note(Note::new(pitch5, SEMIQUAVER, MF)?);
phrase.add_sequential_notes(Note::new_sequence(
SEMIQUAVER,
MF,
&[pitch3, pitch4, pitch5],
))?;
}
}
Ok(())
Expand Down
16 changes: 15 additions & 1 deletion src/chord.rs
@@ -1,4 +1,5 @@
use crate::errors::ChordError;
use crate::num::u7;
use crate::Note;
use crate::Result;

Expand Down Expand Up @@ -37,7 +38,7 @@ impl Chord {
///
/// * `ChordError::EmptyChord` if notes vec is empty
/// * `ChordError::RhythmTooLong` if `rhythm` is longer than the longest note
pub fn new(rhythm: f64, notes: Vec<Note>) -> Result<Chord> {
pub fn new(rhythm: f64, notes: Vec<Note>) -> Result<Self> {
if notes.is_empty() {
return Err(ChordError::EmptyChord.into());
}
Expand All @@ -52,6 +53,19 @@ impl Chord {
Ok(Chord { rhythm, notes })
}

/// Returns a new Chord based on the given rhythm value, note pitches, and dynamic.
///
/// # Arguments
///
/// * `rhythm`: duration in beats of the `Chord` and all the notes it contains
/// * `pitches`: list of the pitches of the notes of the `Chord`
/// * `dynamic`: dynamic that each note in the `Chord` will take
pub fn from_pitches(rhythm: f64, dynamic: u7, pitches: &[u7]) -> Result<Self> {
// let notes: Result<Vec<_>> = pitches.iter().map(|p| Note::new(*p, rhythm, dynamic)).collect();
let notes: Result<Vec<_>> = Note::new_sequence(rhythm, dynamic, pitches).collect();
Self::new(rhythm, notes?)
}

/// Returns the rhythm value of the `Chord`
pub fn rhythm(&self) -> f64 {
self.rhythm
Expand Down
41 changes: 0 additions & 41 deletions src/constants/mod.rs

This file was deleted.

13 changes: 13 additions & 0 deletions src/note.rs
Expand Up @@ -68,6 +68,19 @@ impl Note {
})
}

/// Creates an iterator of notes with idential rhythms and dynamic which can be added directly
/// to a phrase using `phrase.add_sequential_notes` to be played sequentially or collected as
/// a vector to use in a `Chord`.
pub fn new_sequence(
rhythm: f64,
dynamic: u7,
pitches: &[u7],
) -> impl std::iter::Iterator<Item = Result<Note>> + '_ {
pitches
.iter()
.map(move |p| Note::new(*p, rhythm, dynamic))
}

/// Returns the pitch of the note
pub fn pitch(&self) -> u7 {
self.pitch
Expand Down
9 changes: 7 additions & 2 deletions src/phrase.rs
@@ -1,5 +1,6 @@
use crate::Chord;
use crate::Note;
use crate::Result;

/// Describes the entries contains in a `Phrase`
#[derive(Clone)]
Expand Down Expand Up @@ -60,10 +61,14 @@ impl Phrase {
/// Adds multiple sequential notes to the phrase
/// Each note will be played after the previous one.
/// This function will clone the notes into the Phrase's entry Vec
pub fn add_sequential_notes<N: IntoIterator<Item = Note>>(&mut self, notes: N) {
pub fn add_sequential_notes<N: IntoIterator<Item = Result<Note>>>(
&mut self,
notes: N,
) -> Result<()> {
for n in notes.into_iter() {
self.add_note(n);
self.add_note(n?);
}
Ok(())
}

/// Adds a chord to the phrase.
Expand Down

0 comments on commit 02e97ec

Please sign in to comment.