redact_composer_musical/
lib.rs

1#![deny(missing_docs, missing_debug_implementations)]
2//! Musical domain library.
3
4/// Utilities for building or generating rhythms.
5pub mod rhythm;
6
7mod timing;
8pub use timing::*;
9
10mod chord;
11pub use chord::*;
12
13mod pitch_class;
14pub use pitch_class::*;
15
16mod note;
17pub use note::*;
18
19mod interval;
20pub use interval::*;
21
22mod key;
23pub use key::*;
24
25mod scale;
26pub use scale::*;
27
28/// Types implementing [`Element`](redact_composer_core::Element).
29#[cfg(feature = "redact-composer")]
30pub mod elements {
31    pub use super::{
32        rhythm::Rhythm, Chord, ChordShape, Degree, Interval, Key, Mode, Note, NoteName, PitchClass,
33        Scale, TimeSignature,
34    };
35}
36
37/// Provides a sequence of intervals, representing the interval *deltas* from one note to the next.
38pub trait IntervalStepSequence {
39    /// Provides a sequence of intervals, representing the interval *deltas* from one to the next.
40    fn interval_steps(&self) -> Vec<Interval>;
41}
42
43/// Provides a collection of intervals, each as an absolute interval from a relative pitch.
44pub trait IntervalCollection {
45    /// Provides a collection of intervals, each as an absolute interval from a relative pitch.
46    fn intervals(&self) -> Vec<Interval>;
47}
48
49impl<T> IntervalCollection for T
50where
51    T: IntervalStepSequence,
52{
53    fn intervals(&self) -> Vec<Interval> {
54        let mut intervals = self
55            .interval_steps()
56            .into_iter()
57            .fold(
58                (vec![Interval::P1], Interval::P1),
59                |(mut intervals, mut last), step| {
60                    last += step;
61                    intervals.push(last);
62
63                    (intervals, last)
64                },
65            )
66            .0;
67
68        if intervals.len() > 1 && (intervals[intervals.len() - 1].0 - intervals[0].0) % 12 == 0 {
69            intervals.pop();
70        }
71
72        intervals
73    }
74}
75
76/// Trait implemented for types which represent or provide a collection of pitch classes.
77pub trait PitchClassCollection {
78    /// Returns this type's pitches.
79    fn pitch_classes(&self) -> Vec<PitchClass>;
80}
81
82impl<P: Into<PitchClass> + Copy, I: IntoIterator<Item = P> + Clone> PitchClassCollection for I {
83    fn pitch_classes(&self) -> Vec<PitchClass> {
84        self.clone().into_iter().map(|p| p.into()).collect()
85    }
86}