rstmt_core/notes/
note.rs

1/*
2    Appellation: note <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use crate::{IntoPitch, Octave, Pitch, Pitches};
6
7#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
8#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
9pub struct Note {
10    pub(crate) octave: Octave,
11    pub(crate) pitch: Pitch,
12}
13
14impl Note {
15    pub fn new(octave: Octave, pitch: impl IntoPitch) -> Self {
16        Self {
17            octave,
18            pitch: pitch.into_pitch(),
19        }
20    }
21    /// Returns a new instance of the note with the given pitch;
22    /// the note's octave is set to the default octave (4).
23    pub fn from_pitch(pitch: impl IntoPitch) -> Self {
24        Self {
25            octave: Octave::default(),
26            pitch: pitch.into_pitch(),
27        }
28    }
29    /// Returns an instance of the note's [PitchClass](crate::pitch::PitchCalss).
30    /// Each pitch class is a synmoblic representation of a group of frequencies,
31    /// which are separated by a factor of 2^(1/12).
32    ///
33    pub fn class(&self) -> Pitches {
34        self.pitch.class()
35    }
36
37    /// Returns an owned instance of the note's octave
38    pub const fn octave(&self) -> &Octave {
39        &self.octave
40    }
41    /// Returns a mutable reference to the note's octave
42    pub fn octave_mut(&mut self) -> &mut Octave {
43        &mut self.octave
44    }
45    /// Returns an owned instance of the note's pitch
46    pub const fn pitch(&self) -> &Pitch {
47        &self.pitch
48    }
49    /// Returns a mutable reference to the note's pitch
50    pub fn pitch_mut(&mut self) -> &mut Pitch {
51        &mut self.pitch
52    }
53    /// Sets the note's octave
54    pub fn set_octave(&mut self, octave: Octave) {
55        self.octave = octave;
56    }
57    /// Sets the note's pitch
58    pub fn set_pitch(&mut self, Pitch(pitch): Pitch) {
59        self.pitch.set(pitch);
60    }
61    /// Returns a new instance of the note with the given octave
62    pub fn with_octave(self, octave: Octave) -> Self {
63        Self { octave, ..self }
64    }
65    /// Returns a new instance of the note with the given pitch
66    pub fn with_pitch(self, Pitch(pitch): Pitch) -> Note {
67        Note {
68            octave: self.octave,
69            pitch: Pitch(pitch),
70        }
71    }
72}
73
74/*
75 ************* Implementations *************
76*/
77
78impl core::fmt::Display for Note {
79    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
80        write!(f, "{}.{}", self.class(), self.octave)
81    }
82}
83
84unsafe impl Send for Note {}
85
86unsafe impl Sync for Note {}
87
88impl From<(Octave, Pitch)> for Note {
89    fn from((octave, pitch): (Octave, Pitch)) -> Self {
90        Self { octave, pitch }
91    }
92}
93
94impl From<Note> for (Octave, Pitch) {
95    fn from(note: Note) -> Self {
96        (note.octave, note.pitch)
97    }
98}
99
100impl From<Note> for Pitch {
101    fn from(note: Note) -> Self {
102        note.pitch
103    }
104}
105
106impl From<Pitch> for Note {
107    fn from(pitch: Pitch) -> Self {
108        Self {
109            octave: Octave::default(),
110            pitch,
111        }
112    }
113}