note_pen/
pitch.rs

1use crate::Interval;
2use derive_more::with_trait::{Add, Neg, Sub};
3
4#[derive(Copy, Clone, Debug, PartialEq, Eq, Add, Sub)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub struct RelativePitch(pub u8);
7
8impl RelativePitch {
9    pub const fn new(pitch: u8) -> Self {
10        Self(pitch % 12)
11    }
12}
13
14// derive!(RelativePitch, From, from, Self, Self(pitch),
15#[derive(Copy, Clone, Debug, PartialEq, Eq, Add, Neg)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct Pitch(pub i16);
18
19impl Pitch {
20    pub const fn new(pitch: i16) -> Self {
21        Self(pitch)
22    }
23
24    pub const fn increment(&self) -> Self {
25        Self(self.0 + 1)
26    }
27
28    pub const fn decrement(&self) -> Self {
29        Self(self.0 - 1)
30    }
31
32    pub const fn octave_up(&self) -> Self {
33        Self(self.0 + 12)
34    }
35
36    pub const fn octave_down(&self) -> Self {
37        Self(self.0 - 12)
38    }
39
40    pub const fn simple(&self) -> RelativePitch {
41        RelativePitch((self.0 % 12) as u8)
42    }
43}
44
45impl Sub for Pitch {
46    type Output = Interval;
47    fn sub(self, other: Self) -> Interval {
48        Interval(self.0 - other.0)
49    }
50}