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(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}