Skip to main content

maolan_widgets/
midi.rs

1use std::fmt;
2
3pub const MIDI_CHANNELS: usize = 16;
4pub const KEYS_SCROLL_ID: &str = "piano.keys.scroll";
5pub const NOTES_SCROLL_ID: &str = "piano.notes.scroll";
6pub const CTRL_SCROLL_ID: &str = "piano.ctrl.scroll";
7pub const SYSEX_SCROLL_ID: &str = "piano.sysex.scroll";
8
9pub const KEYBOARD_WIDTH: f32 = 128.0;
10pub const RIGHT_SCROLL_GUTTER_WIDTH: f32 = 16.0;
11pub const TOOLS_STRIP_WIDTH: f32 = 248.0;
12pub const MAIN_SPLIT_SPACING: f32 = 3.0;
13pub const H_ZOOM_MIN: f32 = 1.0;
14pub const H_ZOOM_MAX: f32 = 127.0;
15pub const MIDI_NOTE_COUNT: usize = 128;
16pub const OCTAVES: usize = 11;
17pub const WHITE_KEYS_PER_OCTAVE: usize = 7;
18pub const NOTES_PER_OCTAVE: usize = 12;
19pub const PITCH_MAX: u8 = (MIDI_NOTE_COUNT as u8) - 1;
20pub const WHITE_KEY_HEIGHT: f32 = 14.0;
21pub const MAX_RPN_NRPN_POINTS: usize = 4096;
22pub const MIDI_DIN_BYTES_PER_SEC: f64 = 3125.0;
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub enum PianoControllerLane {
26    Controller,
27    Velocity,
28    Rpn,
29    Nrpn,
30    SysEx,
31    MpePitchBend,
32    MpePressure,
33    MpeTimbre,
34}
35
36impl fmt::Display for PianoControllerLane {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        match self {
39            Self::Controller => write!(f, "Controller"),
40            Self::Velocity => write!(f, "Velocity"),
41            Self::Rpn => write!(f, "RPN"),
42            Self::Nrpn => write!(f, "NRPN"),
43            Self::SysEx => write!(f, "SysEx"),
44            Self::MpePitchBend => write!(f, "MPE Pitch Bend"),
45            Self::MpePressure => write!(f, "MPE Pressure"),
46            Self::MpeTimbre => write!(f, "MPE Timbre"),
47        }
48    }
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub enum PianoRpnKind {
53    PitchBendSensitivity,
54    FineTuning,
55    CoarseTuning,
56}
57
58impl fmt::Display for PianoRpnKind {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        match self {
61            Self::PitchBendSensitivity => write!(f, "Pitch Bend Sensitivity"),
62            Self::FineTuning => write!(f, "Fine Tuning"),
63            Self::CoarseTuning => write!(f, "Coarse Tuning"),
64        }
65    }
66}
67
68pub const PIANO_RPN_KIND_ALL: [PianoRpnKind; 3] = [
69    PianoRpnKind::PitchBendSensitivity,
70    PianoRpnKind::FineTuning,
71    PianoRpnKind::CoarseTuning,
72];
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq)]
75pub enum PianoNrpnKind {
76    Brightness,
77    VibratoRate,
78    VibratoDepth,
79}
80
81impl fmt::Display for PianoNrpnKind {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        match self {
84            Self::Brightness => write!(f, "Brightness"),
85            Self::VibratoRate => write!(f, "Vibrato Rate"),
86            Self::VibratoDepth => write!(f, "Vibrato Depth"),
87        }
88    }
89}
90
91pub const PIANO_NRPN_KIND_ALL: [PianoNrpnKind; 3] = [
92    PianoNrpnKind::Brightness,
93    PianoNrpnKind::VibratoRate,
94    PianoNrpnKind::VibratoDepth,
95];
96
97/// A single point in a per-note MPE expression curve. `sample_offset` is
98/// relative to the note's start.
99#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
100pub struct MpeExpressionPoint {
101    pub sample_offset: usize,
102    /// For pitch bend this is 0..=16383 (8192 center); for pressure and
103    /// timbre this is 0..=127.
104    pub value: u16,
105}
106
107/// One per-note MPE expression curve.
108#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
109pub struct MpeExpressionCurve {
110    pub points: Vec<MpeExpressionPoint>,
111}
112
113/// Per-note MPE expression data attached to a [`PianoNote`].
114#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
115pub struct MpeNoteExpression {
116    pub pitch_bend: MpeExpressionCurve,
117    pub pressure: MpeExpressionCurve,
118    pub timbre: MpeExpressionCurve,
119}
120
121#[derive(Debug, Clone)]
122pub struct PianoNote {
123    pub start_sample: usize,
124    pub length_samples: usize,
125    pub pitch: u8,
126    pub velocity: u8,
127    pub channel: u8,
128    pub mpe: MpeNoteExpression,
129}
130
131#[derive(Debug, Clone)]
132pub struct PianoControllerPoint {
133    pub sample: usize,
134    pub controller: u8,
135    pub value: u8,
136    pub channel: u8,
137}
138
139#[derive(Debug, Clone)]
140pub struct PianoSysExPoint {
141    pub sample: usize,
142    pub data: Vec<u8>,
143}