midix/
velocity.rs

1use crate::prelude::*;
2use core::fmt;
3
4/// Identifies the velocity of a key press, or a key unpress, or an aftertouch.
5#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
6pub struct Velocity(DataByte);
7
8impl Velocity {
9    /// Creates a new velocity from the provided byte
10    ///
11    /// Checks for correctness (leading 0 bit)
12    pub fn new<B, E>(rep: B) -> Result<Self, std::io::Error>
13    where
14        B: TryInto<DataByte, Error = E>,
15        E: Into<io::Error>,
16    {
17        rep.try_into().map(Self).map_err(Into::into)
18    }
19
20    /// Returns a max velocity
21    pub fn max() -> Self {
22        Self(DataByte::new_unchecked(127))
23    }
24
25    /// Returns a velocity of zero.
26    pub fn zero() -> Self {
27        Self(DataByte::new_unchecked(0))
28    }
29
30    /// Get a reference to the underlying byte
31    pub fn byte(&self) -> u8 {
32        self.0.0
33    }
34
35    /// Get the dynamic of the velocity...fortississississimo
36    pub fn dynamic(&self) -> Dynamic {
37        match self.byte() {
38            0 => Dynamic::off(),
39            1..16 => Dynamic::ppp(),
40            16..32 => Dynamic::pp(),
41            32..48 => Dynamic::p(),
42            48..64 => Dynamic::mp(),
43            64..80 => Dynamic::mf(),
44            80..96 => Dynamic::f(),
45            96..112 => Dynamic::ff(),
46            _ => Dynamic::fff(),
47        }
48    }
49}
50
51impl fmt::Display for Velocity {
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        self.0.fmt(f)
54    }
55}
56
57/// The musical analog of the digital velocity
58#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
59pub enum Dynamic {
60    /// no sound
61    Off,
62    /// very quiet
63    Pianississimo,
64    /// pretty quiet
65    Pianissimo,
66    /// quiet
67    Piano,
68    /// kinda quiet
69    MezzoPiano,
70    /// kinda loud
71    MezzoForte,
72    /// loud
73    Forte,
74    /// pretty loud
75    Fortissimo,
76    /// very loud
77    Fortississimo,
78}
79
80impl Dynamic {
81    /// No sound
82    pub fn off() -> Self {
83        Self::Off
84    }
85
86    /// very quiet
87    pub fn ppp() -> Self {
88        Self::Pianississimo
89    }
90
91    /// pretty quiet
92    pub fn pp() -> Self {
93        Self::Pianissimo
94    }
95
96    /// quiet
97    pub fn p() -> Self {
98        Self::Piano
99    }
100
101    /// kinda quiet
102    pub fn mp() -> Self {
103        Self::MezzoPiano
104    }
105
106    /// kinda loud
107    pub fn mf() -> Self {
108        Self::MezzoForte
109    }
110
111    /// loud
112    pub fn f() -> Self {
113        Self::Forte
114    }
115
116    /// pretty loud
117    pub fn ff() -> Self {
118        Self::Fortissimo
119    }
120
121    /// very loud
122    pub fn fff() -> Self {
123        Self::Fortississimo
124    }
125}