midi_msg/
channel_voice.rs

1use crate::ReceiverContext;
2
3use super::parse_error::*;
4use super::util::*;
5use alloc::vec;
6use alloc::vec::Vec;
7
8/// Channel-level messages that act on a voice. For instance, turning notes on off,
9/// or modifying sounding notes. Used in [`MidiMsg`](crate::MidiMsg).
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ChannelVoiceMsg {
12    /// Turn on a note
13    NoteOn {
14        /// A MIDI note number 0-127. Per GM1, 69 = A440
15        note: u8,
16        /// The velocity the note should be played at, 0-127
17        velocity: u8,
18    },
19    /// Turn off a note
20    NoteOff {
21        /// Stop playing the given MIDI note at this channel, 0-127
22        note: u8,
23        /// The velocity the note should stop being played at, 0-127
24        velocity: u8,
25    },
26    /// Generally used for modifying the tones being played. Frequently shortened to 'CC'
27    ControlChange { control: ControlChange },
28    /// A note on with a preceding HighResVelocity CC per CA-031
29    HighResNoteOn { note: u8, velocity: u16 },
30    /// A note off with a preceding HighResVelocity CC per CA-031
31    HighResNoteOff { note: u8, velocity: u16 },
32    /// The amount of pressure being applied to a given note, which is a signal some controllers
33    /// after an initial `NoteOn`.
34    /// Can act on multiple notes at a time, thus it is "polyphonic".
35    PolyPressure {
36        /// The note to apply this pressure signal to, 0-127
37        note: u8,
38        /// The amount of pressure to apply, 0-127
39        pressure: u8,
40    },
41    /// Similar to `PolyPressure`, but only applies at the channel-level.
42    ChannelPressure { pressure: u8 },
43    /// Which "program", "patch" or "sound" to use when playing any preceding notes, 0-127.
44    /// Use [`GMSoundSet`](crate::GMSoundSet) when targeting General MIDI
45    ProgramChange { program: u8 },
46    /// Apply a pitch bend to all sounding notes. 0-8191 represent negative bends,
47    /// 8192 is no bend and8193-16383 are positive bends, with the standard bend rang
48    /// being +/-2 semitones per GM2. See [`Parameter::PitchBendSensitivity`]
49    PitchBend { bend: u16 },
50}
51
52impl ChannelVoiceMsg {
53    pub(crate) fn extend_midi(&self, v: &mut Vec<u8>) {
54        match self {
55            ChannelVoiceMsg::NoteOff { .. } => v.push(0x80),
56            ChannelVoiceMsg::NoteOn { .. } => v.push(0x90),
57            ChannelVoiceMsg::HighResNoteOff { .. } => v.push(0x80),
58            ChannelVoiceMsg::HighResNoteOn { .. } => v.push(0x90),
59            ChannelVoiceMsg::PolyPressure { .. } => v.push(0xA0),
60            ChannelVoiceMsg::ControlChange { .. } => v.push(0xB0),
61            ChannelVoiceMsg::ProgramChange { .. } => v.push(0xC0),
62            ChannelVoiceMsg::ChannelPressure { .. } => v.push(0xD0),
63            ChannelVoiceMsg::PitchBend { .. } => v.push(0xE0),
64        }
65        self.extend_midi_running(v);
66    }
67
68    // Can this message be extended by another?
69    pub(crate) fn is_extensible(&self) -> bool {
70        match self {
71            Self::NoteOff { .. }
72            | Self::NoteOn { .. }
73            | Self::HighResNoteOff { .. }
74            | Self::HighResNoteOn { .. } => true,
75            Self::ControlChange {
76                control: ControlChange::Parameter(_),
77            } => true,
78            Self::ControlChange { control } => control.is_lsb() || control.is_msb(),
79            _ => false,
80        }
81    }
82
83    // Can this message function as an extension to another?
84    pub(crate) fn is_extension(&self) -> bool {
85        match self {
86            Self::ControlChange { control } => match control {
87                ControlChange::HighResVelocity(_) => true,
88                control => control.is_lsb() || control.is_msb(),
89            },
90            _ => false,
91        }
92    }
93
94    pub(crate) fn maybe_extend(&self, other: &Self) -> Result<Self, ()> {
95        match (self, other) {
96            (
97                Self::NoteOff { note, velocity },
98                Self::ControlChange {
99                    control: ControlChange::HighResVelocity(v),
100                },
101            ) => Ok(Self::HighResNoteOff {
102                note: *note,
103                velocity: u14_from_u7s(*velocity, *v),
104            }),
105            (
106                Self::NoteOn { note, velocity },
107                Self::ControlChange {
108                    control: ControlChange::HighResVelocity(v),
109                },
110            ) => Ok(Self::HighResNoteOn {
111                note: *note,
112                velocity: u14_from_u7s(*velocity, *v),
113            }),
114            (
115                Self::HighResNoteOff { note, velocity },
116                Self::ControlChange {
117                    control: ControlChange::HighResVelocity(v),
118                },
119            ) => Ok(Self::HighResNoteOff {
120                note: *note,
121                velocity: replace_u14_lsb(*velocity, *v),
122            }),
123            (
124                Self::HighResNoteOn { note, velocity },
125                Self::ControlChange {
126                    control: ControlChange::HighResVelocity(v),
127                },
128            ) => Ok(Self::HighResNoteOn {
129                note: *note,
130                velocity: replace_u14_lsb(*velocity, *v),
131            }),
132            (Self::ControlChange { control: ctrl1 }, Self::ControlChange { control: ctrl2 }) => {
133                match ctrl1.maybe_extend(ctrl2) {
134                    Ok(control) => Ok(Self::ControlChange { control }),
135                    Err(()) => Err(()),
136                }
137            }
138            _ => Err(()),
139        }
140    }
141
142    /// Out of necessity, pushes a Channel message after the note message for `HighResNoteOn/Off`
143    pub(crate) fn extend_midi_running(&self, v: &mut Vec<u8>) {
144        match *self {
145            ChannelVoiceMsg::NoteOff { note, velocity } => {
146                v.push(to_u7(note));
147                v.push(to_u7(velocity));
148            }
149            ChannelVoiceMsg::NoteOn { note, velocity } => {
150                v.push(to_u7(note));
151                v.push(to_u7(velocity));
152            }
153            ChannelVoiceMsg::HighResNoteOff { note, velocity } => {
154                let [msb, lsb] = to_u14(velocity);
155                push_u7(note, v);
156                v.push(msb);
157                v.push(0xB0);
158                v.push(0x58);
159                v.push(lsb);
160            }
161            ChannelVoiceMsg::HighResNoteOn { note, velocity } => {
162                let [msb, lsb] = to_u14(velocity);
163                push_u7(note, v);
164                v.push(msb);
165                v.push(0xB0);
166                v.push(0x58);
167                v.push(lsb);
168            }
169            ChannelVoiceMsg::PolyPressure { note, pressure } => {
170                v.push(to_u7(note));
171                v.push(to_u7(pressure));
172            }
173            ChannelVoiceMsg::ControlChange { control } => control.extend_midi_running(v),
174            ChannelVoiceMsg::ProgramChange { program } => v.push(to_u7(program)),
175            ChannelVoiceMsg::ChannelPressure { pressure } => v.push(to_u7(pressure)),
176            ChannelVoiceMsg::PitchBend { bend } => {
177                push_u14(bend, v);
178            }
179        }
180    }
181
182    pub(crate) fn from_midi(m: &[u8], ctx: &ReceiverContext) -> Result<(Self, usize), ParseError> {
183        let status = match m.first() {
184            Some(b) => match b >> 4 {
185                0x8 => Self::NoteOff {
186                    note: 0,
187                    velocity: 0,
188                },
189                0x9 => Self::NoteOn {
190                    note: 0,
191                    velocity: 0,
192                },
193                0xA => Self::PolyPressure {
194                    note: 0,
195                    pressure: 0,
196                },
197                0xB => Self::ControlChange {
198                    control: ControlChange::BankSelect(0),
199                },
200                0xC => Self::ProgramChange { program: 0 },
201                0xD => Self::ChannelPressure { pressure: 0 },
202                0xE => Self::PitchBend { bend: 0 },
203                _ => return Err(ParseError::Invalid("This shouldn't be possible")),
204            },
205            None => return Err(ParseError::UnexpectedEnd),
206        };
207        let (msg, len) = Self::from_midi_running(&m[1..], &status, ctx)?;
208        Ok((msg, len + 1))
209    }
210
211    pub(crate) fn from_midi_running(
212        m: &[u8],
213        msg: &Self,
214        ctx: &ReceiverContext,
215    ) -> Result<(Self, usize), ParseError> {
216        match msg {
217            Self::NoteOff { .. } => Ok((
218                Self::NoteOff {
219                    note: u7_from_midi(m)?,
220                    velocity: u7_from_midi(&m[1..])?,
221                },
222                2,
223            )),
224            Self::NoteOn { .. } => Ok((
225                Self::NoteOn {
226                    note: u7_from_midi(m)?,
227                    velocity: u7_from_midi(&m[1..])?,
228                },
229                2,
230            )),
231            Self::PolyPressure { .. } => Ok((
232                Self::PolyPressure {
233                    note: u7_from_midi(m)?,
234                    pressure: u7_from_midi(&m[1..])?,
235                },
236                2,
237            )),
238            Self::ControlChange { .. } => Ok((
239                Self::ControlChange {
240                    control: ControlChange::from_midi(m, ctx)?,
241                },
242                2,
243            )),
244            Self::ProgramChange { .. } => Ok((
245                Self::ProgramChange {
246                    program: u7_from_midi(m)?,
247                },
248                1,
249            )),
250            Self::ChannelPressure { .. } => Ok((
251                Self::ChannelPressure {
252                    pressure: u7_from_midi(m)?,
253                },
254                1,
255            )),
256            Self::PitchBend { .. } => Ok((
257                Self::PitchBend {
258                    bend: u14_from_midi(m)?,
259                },
260                2,
261            )),
262            Self::HighResNoteOn { .. } | Self::HighResNoteOff { .. } => {
263                // This shouldn't really be used as a running message, but if it is, the last
264                // midi msg sent would have been a CC.
265                Ok((
266                    Self::ControlChange {
267                        control: ControlChange::from_midi(m, ctx)?,
268                    },
269                    2,
270                ))
271            }
272        }
273    }
274}
275
276/// An enum that defines the MIDI numbers associated with Control Changes.
277#[derive(Debug, Clone, Copy, PartialEq, Eq)]
278pub enum ControlNumber {
279    BankSelect = 0,
280    BankSelectLSB = 32,
281    ModWheel = 1,
282    ModWheelLSB = 33,
283    Breath = 2,
284    BreathLSB = 34,
285    Foot = 4,
286    FootLSB = 36,
287    Portamento = 5,
288    PortamentoLSB = 37,
289    DataEntry = 6,
290    DataEntryLSB = 38,
291    Volume = 7,
292    VolumeLSB = 39,
293    Balance = 8,
294    BalanceLSB = 40,
295    Pan = 10,
296    PanLSB = 42,
297    Expression = 11,
298    ExpressionLSB = 43,
299    Effect1 = 12,
300    Effect1LSB = 44,
301    Effect2 = 13,
302    Effect2LSB = 45,
303    GeneralPurpose1 = 16,
304    GeneralPurpose1LSB = 48,
305    GeneralPurpose2 = 17,
306    GeneralPurpose2LSB = 49,
307    GeneralPurpose3 = 18,
308    GeneralPurpose3LSB = 50,
309    GeneralPurpose4 = 19,
310    GeneralPurpose4LSB = 51,
311    /// AKA Sustain
312    Hold = 64,
313    TogglePortamento = 65,
314    Sostenuto = 66,
315    SoftPedal = 67,
316    ToggleLegato = 68,
317    Hold2 = 69,
318    /// AKA SoundVariation
319    SoundControl1 = 70,
320    /// AKA Timbre
321    SoundControl2 = 71,
322    /// AKA ReleaseTime
323    SoundControl3 = 72,
324    /// AKA AttackTime
325    SoundControl4 = 73,
326    /// AKA Brightness
327    SoundControl5 = 74,
328    /// AKA DecayTime
329    SoundControl6 = 75,
330    /// AKA VibratoRate
331    SoundControl7 = 76,
332    /// AKA VibratoDepth
333    SoundControl8 = 77,
334    /// AKA VibratoDelay
335    SoundControl9 = 78,
336    SoundControl10 = 79,
337    GeneralPurpose5 = 80,
338    GeneralPurpose6 = 81,
339    GeneralPurpose7 = 82,
340    GeneralPurpose8 = 83,
341    PortamentoControl = 84,
342    HighResVelocity = 88,
343    /// AKA ReverbSendLevel
344    Effects1Depth = 91,
345    /// AKA TremoloDepth
346    Effects2Depth = 92,
347    /// AKA ChorusSendLevel
348    Effects3Depth = 93,
349    /// AKA CelesteDepth
350    Effects4Depth = 94,
351    /// AKA PhaserDepth
352    Effects5Depth = 95,
353    DataIncrement = 96,
354    DataDecrement = 97,
355    NonRegisteredParameterLSB = 98,
356    NonRegisteredParameter = 99,
357    RegisteredParameterLSB = 100,
358    RegisteredParameter = 101,
359}
360
361/// Used by [`ChannelVoiceMsg::ControlChange`] to modify sounds.
362/// Each control targets a particular [`ControlNumber`], the meaning of which is given by convention.
363///
364/// When deserializing and [`complex_cc`](crate::ReceiverContext) is false (the default), only [ControlChange::CC] values are returned. "Simple" CC values represent the control parameter with a number, while "complex" variants capture the semantics of the spec. Simple can be turned into their complex counterparts using the [`to_complex`](ControlChange::to_complex) method, or vis-versa using the [`to_simple`](ControlChange::to_simple) and [`to_simple_high_res`](ControlChange::to_simple_high_res) methods.
365#[derive(Debug, Clone, Copy, PartialEq, Eq)]
366pub enum ControlChange {
367    /// "Simple" Control Change message.
368    ///
369    /// Control number may be any valid Midi CC Control number. May not be > 119.
370    CC {
371        control: u8,
372        /// 0-127
373        value: u8,
374    },
375    /// "Simple" high-resolution Control Change message.
376    ///
377    /// `control1` is associated with the MSB of the value, `control2` with the LSB. Neither `controls` may be > 119.
378    CCHighRes {
379        control1: u8,
380        control2: u8,
381        /// 0-16383
382        value: u16,
383    },
384
385    /// 0-16383
386    BankSelect(u16),
387    /// 0-16383
388    ModWheel(u16),
389    /// 0-16383
390    Breath(u16),
391    /// 0-16383
392    Foot(u16),
393    /// 0-16383
394    Portamento(u16),
395    /// 0-16383
396    Volume(u16),
397    /// 0-16383
398    Balance(u16),
399    /// 0-16383
400    Pan(u16),
401    /// 0-16383
402    Expression(u16),
403    /// 0-16383
404    Effect1(u16),
405    /// 0-16383
406    Effect2(u16),
407    /// 0-16383
408    GeneralPurpose1(u16),
409    /// 0-16383
410    GeneralPurpose2(u16),
411    /// 0-16383
412    GeneralPurpose3(u16),
413    /// 0-16383
414    GeneralPurpose4(u16),
415    /// 0-127
416    GeneralPurpose5(u8),
417    /// 0-127
418    GeneralPurpose6(u8),
419    /// 0-127
420    GeneralPurpose7(u8),
421    /// 0-127
422    GeneralPurpose8(u8),
423    /// 0-127
424    Hold(u8),
425    /// 0-127
426    Hold2(u8),
427    /// Turn portamento on or off
428    TogglePortamento(bool),
429    /// 0-127
430    Sostenuto(u8),
431    /// 0-127
432    SoftPedal(u8),
433    /// Turn legato on or off
434    ToggleLegato(bool),
435    /// Same as SoundControl1
436    SoundVariation(u8),
437    /// Same as SoundControl2
438    Timbre(u8),
439    /// Same as SoundControl3
440    ReleaseTime(u8),
441    /// Same as SoundControl4
442    AttackTime(u8),
443    /// Same as SoundControl5, and used as the MPE "third dimension" (usually Timbre) control
444    /// (RP-021, RP-053)
445    Brightness(u8),
446    /// Same as SoundControl6 (RP-021)
447    DecayTime(u8),
448    /// Same as SoundControl7 (RP-021)
449    VibratoRate(u8),
450    /// Same as SoundControl8 (RP-021)
451    VibratoDepth(u8),
452    /// Same as SoundControl9 (RP-021)
453    VibratoDelay(u8),
454    /// 0-127
455    SoundControl1(u8),
456    /// 0-127
457    SoundControl2(u8),
458    /// 0-127
459    SoundControl3(u8),
460    /// 0-127
461    SoundControl4(u8),
462    /// 0-127
463    SoundControl5(u8),
464    /// 0-127
465    SoundControl6(u8),
466    /// 0-127
467    SoundControl7(u8),
468    /// 0-127
469    SoundControl8(u8),
470    /// 0-127
471    SoundControl9(u8),
472    /// 0-127
473    SoundControl10(u8),
474    /// Used as the LSB of the velocity for the next note on/off message, 0-127.
475    /// Defined in CA-031
476    HighResVelocity(u8),
477    /// 0-127
478    PortamentoControl(u8),
479    /// 0-127
480    Effects1Depth(u8),
481    /// 0-127
482    Effects2Depth(u8),
483    /// 0-127
484    Effects3Depth(u8),
485    /// 0-127
486    Effects4Depth(u8),
487    /// 0-127
488    Effects5Depth(u8),
489    /// Same as Effects1Depth (RP-023)
490    ReverbSendLevel(u8),
491    /// Same as Effects2Depth
492    TremoloDepth(u8),
493    /// Same as Effects3Depth (RP-023)
494    ChorusSendLevel(u8),
495    /// Same as Effects4Depth
496    CelesteDepth(u8),
497    /// Same as Effects5Depth
498    PhaserDepth(u8),
499    /// Registered and Unregistered Parameters
500    Parameter(Parameter),
501    /// Set the value of the last-set Parameter. 0-16383
502    DataEntry(u16),
503    /// Set the MSB and LSB of the last-set parameter separately.
504    DataEntry2(u8, u8),
505    /// Increment the value of the last-set Parameter. 0-127
506    DataIncrement(u8),
507    /// Decrement the value of the last-set Parameter. 0-127
508    DataDecrement(u8),
509}
510
511impl ControlChange {
512    pub fn to_complex(&self) -> Self {
513        match *self {
514            Self::CC { control, value } => {
515                match control {
516                    // 14 bit controls
517                    0 => Self::BankSelect((value as u16) << 7),
518                    1 => Self::ModWheel((value as u16) << 7),
519                    2 => Self::Breath((value as u16) << 7),
520                    4 => Self::Foot((value as u16) << 7),
521                    5 => Self::Portamento((value as u16) << 7),
522                    6 => Self::DataEntry((value as u16) << 7),
523                    7 => Self::Volume((value as u16) << 7),
524                    8 => Self::Balance((value as u16) << 7),
525                    10 => Self::Pan((value as u16) << 7),
526                    11 => Self::Expression((value as u16) << 7),
527                    12 => Self::Effect1((value as u16) << 7),
528                    13 => Self::Effect2((value as u16) << 7),
529                    16 => Self::GeneralPurpose1((value as u16) << 7),
530                    17 => Self::GeneralPurpose2((value as u16) << 7),
531                    18 => Self::GeneralPurpose3((value as u16) << 7),
532                    19 => Self::GeneralPurpose4((value as u16) << 7),
533                    // 7 bit controls
534                    64 => Self::Hold(value),
535                    65 => Self::TogglePortamento(value >= 0x40),
536                    66 => Self::Sostenuto(value),
537                    67 => Self::SoftPedal(value),
538                    68 => Self::ToggleLegato(value >= 0x40),
539                    69 => Self::Hold2(value),
540                    70 => Self::SoundControl1(value),
541                    71 => Self::SoundControl2(value),
542                    72 => Self::SoundControl3(value),
543                    73 => Self::SoundControl4(value),
544                    74 => Self::SoundControl5(value),
545                    75 => Self::SoundControl6(value),
546                    76 => Self::SoundControl7(value),
547                    77 => Self::SoundControl8(value),
548                    78 => Self::SoundControl9(value),
549                    79 => Self::SoundControl10(value),
550                    80 => Self::GeneralPurpose5(value),
551                    81 => Self::GeneralPurpose6(value),
552                    82 => Self::GeneralPurpose7(value),
553                    83 => Self::GeneralPurpose8(value),
554                    84 => Self::PortamentoControl(value),
555                    88 => Self::HighResVelocity(value),
556                    91 => Self::Effects1Depth(value),
557                    92 => Self::Effects2Depth(value),
558                    93 => Self::Effects3Depth(value),
559                    94 => Self::Effects4Depth(value),
560                    95 => Self::Effects5Depth(value),
561                    96 => Self::DataIncrement(value),
562                    97 => Self::DataDecrement(value),
563                    // Undefined controls
564                    3 | 9 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 => {
565                        Self::CCHighRes {
566                            control1: control,
567                            control2: control + 32,
568                            value: (value as u16) << 7,
569                        }
570                    }
571                    control => Self::CC { control, value },
572                }
573            }
574            Self::CCHighRes {
575                control1, value, ..
576            } => {
577                match control1 {
578                    // 14 bit controls
579                    0 => Self::BankSelect(value),
580                    1 => Self::ModWheel(value),
581                    2 => Self::Breath(value),
582                    4 => Self::Foot(value),
583                    5 => Self::Portamento(value),
584                    6 => Self::DataEntry(value),
585                    7 => Self::Volume(value),
586                    8 => Self::Balance(value),
587                    10 => Self::Pan(value),
588                    11 => Self::Expression(value),
589                    12 => Self::Effect1(value),
590                    13 => Self::Effect2(value),
591                    16 => Self::GeneralPurpose1(value),
592                    17 => Self::GeneralPurpose2(value),
593                    18 => Self::GeneralPurpose3(value),
594                    19 => Self::GeneralPurpose4(value),
595                    _ => Self::CC {
596                        control: control1,
597                        value: (value >> 7) as u8,
598                    }
599                    .to_complex(),
600                }
601            }
602            // Everything else is already complex
603            rest => rest,
604        }
605    }
606
607    pub fn to_simple(&self) -> Self {
608        Self::CC {
609            control: self.control(),
610            value: self.value(),
611        }
612    }
613
614    pub fn to_simple_high_res(&self) -> Self {
615        match self {
616            Self::CCHighRes { .. } => *self,
617            _ => {
618                let cc = self.control();
619                Self::CCHighRes {
620                    control1: cc,
621                    control2: cc + 32,
622                    value: self.value_high_res(),
623                }
624            }
625        }
626    }
627
628    pub fn control(&self) -> u8 {
629        match self {
630            Self::CC { control, .. } => *control,
631            Self::CCHighRes { control1, .. } => *control1,
632            Self::BankSelect(_) => ControlNumber::BankSelect as u8,
633            Self::ModWheel(_) => ControlNumber::ModWheel as u8,
634            Self::Breath(_) => ControlNumber::Breath as u8,
635            Self::Foot(_) => ControlNumber::Foot as u8,
636            Self::Portamento(_) => ControlNumber::Portamento as u8,
637            Self::Volume(_) => ControlNumber::Volume as u8,
638            Self::Balance(_) => ControlNumber::Balance as u8,
639            Self::Pan(_) => ControlNumber::Pan as u8,
640            Self::Expression(_) => ControlNumber::Expression as u8,
641            Self::Effect1(_) => ControlNumber::Effect1 as u8,
642            Self::Effect2(_) => ControlNumber::Effect2 as u8,
643            Self::GeneralPurpose1(_) => ControlNumber::GeneralPurpose1 as u8,
644            Self::GeneralPurpose2(_) => ControlNumber::GeneralPurpose2 as u8,
645            Self::GeneralPurpose3(_) => ControlNumber::GeneralPurpose3 as u8,
646            Self::GeneralPurpose4(_) => ControlNumber::GeneralPurpose4 as u8,
647            Self::GeneralPurpose5(_) => ControlNumber::GeneralPurpose5 as u8,
648            Self::GeneralPurpose6(_) => ControlNumber::GeneralPurpose6 as u8,
649            Self::GeneralPurpose7(_) => ControlNumber::GeneralPurpose7 as u8,
650            Self::GeneralPurpose8(_) => ControlNumber::GeneralPurpose8 as u8,
651            Self::Hold(_) => ControlNumber::Hold as u8,
652            Self::Hold2(_) => ControlNumber::Hold2 as u8,
653            Self::TogglePortamento(_) => ControlNumber::TogglePortamento as u8,
654            Self::Sostenuto(_) => ControlNumber::Sostenuto as u8,
655            Self::SoftPedal(_) => ControlNumber::SoftPedal as u8,
656            Self::ToggleLegato(_) => ControlNumber::ToggleLegato as u8,
657            Self::SoundVariation(_) => ControlNumber::SoundControl1 as u8,
658            Self::Timbre(_) => ControlNumber::SoundControl2 as u8,
659            Self::ReleaseTime(_) => ControlNumber::SoundControl3 as u8,
660            Self::AttackTime(_) => ControlNumber::SoundControl4 as u8,
661            Self::Brightness(_) => ControlNumber::SoundControl5 as u8,
662            Self::DecayTime(_) => ControlNumber::SoundControl6 as u8,
663            Self::VibratoRate(_) => ControlNumber::SoundControl7 as u8,
664            Self::VibratoDepth(_) => ControlNumber::SoundControl8 as u8,
665            Self::VibratoDelay(_) => ControlNumber::SoundControl9 as u8,
666            Self::SoundControl1(_) => ControlNumber::SoundControl1 as u8,
667            Self::SoundControl2(_) => ControlNumber::SoundControl2 as u8,
668            Self::SoundControl3(_) => ControlNumber::SoundControl3 as u8,
669            Self::SoundControl4(_) => ControlNumber::SoundControl4 as u8,
670            Self::SoundControl5(_) => ControlNumber::SoundControl5 as u8,
671            Self::SoundControl6(_) => ControlNumber::SoundControl6 as u8,
672            Self::SoundControl7(_) => ControlNumber::SoundControl7 as u8,
673            Self::SoundControl8(_) => ControlNumber::SoundControl8 as u8,
674            Self::SoundControl9(_) => ControlNumber::SoundControl9 as u8,
675            Self::SoundControl10(_) => ControlNumber::SoundControl10 as u8,
676            Self::HighResVelocity(_) => ControlNumber::HighResVelocity as u8,
677            Self::PortamentoControl(_) => ControlNumber::PortamentoControl as u8,
678            Self::Effects1Depth(_) => ControlNumber::Effects1Depth as u8,
679            Self::Effects2Depth(_) => ControlNumber::Effects2Depth as u8,
680            Self::Effects3Depth(_) => ControlNumber::Effects3Depth as u8,
681            Self::Effects4Depth(_) => ControlNumber::Effects4Depth as u8,
682            Self::Effects5Depth(_) => ControlNumber::Effects5Depth as u8,
683            Self::ReverbSendLevel(_) => ControlNumber::Effects1Depth as u8,
684            Self::TremoloDepth(_) => ControlNumber::Effects2Depth as u8,
685            Self::ChorusSendLevel(_) => ControlNumber::Effects3Depth as u8,
686            Self::CelesteDepth(_) => ControlNumber::Effects4Depth as u8,
687            Self::PhaserDepth(_) => ControlNumber::Effects5Depth as u8,
688            Self::Parameter(Parameter::Unregistered(..)) => {
689                ControlNumber::NonRegisteredParameter as u8
690            }
691            Self::Parameter(_) => ControlNumber::RegisteredParameter as u8,
692            Self::DataEntry(_) => ControlNumber::DataEntry as u8,
693            Self::DataEntry2(_, _) => ControlNumber::DataEntry as u8,
694            Self::DataIncrement(_) => ControlNumber::DataIncrement as u8,
695            Self::DataDecrement(_) => ControlNumber::DataDecrement as u8,
696        }
697    }
698
699    /// The value of the control change, 0-127. Will be 0 for `ControlChange::Parameter`.
700    pub fn value(&self) -> u8 {
701        match self {
702            Self::CC { value, .. } => *value,
703            Self::CCHighRes { value, .. } => (*value >> 7) as u8,
704            Self::BankSelect(x)
705            | Self::ModWheel(x)
706            | Self::Breath(x)
707            | Self::Foot(x)
708            | Self::Portamento(x)
709            | Self::Volume(x)
710            | Self::Balance(x)
711            | Self::Pan(x)
712            | Self::Expression(x)
713            | Self::Effect1(x)
714            | Self::Effect2(x)
715            | Self::GeneralPurpose1(x)
716            | Self::GeneralPurpose2(x)
717            | Self::GeneralPurpose3(x)
718            | Self::GeneralPurpose4(x)
719            | Self::DataEntry(x) => (x >> 7) as u8,
720            Self::Hold(x)
721            | Self::Hold2(x)
722            | Self::Sostenuto(x)
723            | Self::SoftPedal(x)
724            | Self::SoundVariation(x)
725            | Self::Timbre(x)
726            | Self::ReleaseTime(x)
727            | Self::AttackTime(x)
728            | Self::Brightness(x)
729            | Self::DecayTime(x)
730            | Self::VibratoRate(x)
731            | Self::VibratoDepth(x)
732            | Self::VibratoDelay(x)
733            | Self::SoundControl1(x)
734            | Self::SoundControl2(x)
735            | Self::SoundControl3(x)
736            | Self::SoundControl4(x)
737            | Self::SoundControl5(x)
738            | Self::SoundControl6(x)
739            | Self::SoundControl7(x)
740            | Self::SoundControl8(x)
741            | Self::SoundControl9(x)
742            | Self::SoundControl10(x)
743            | Self::GeneralPurpose5(x)
744            | Self::GeneralPurpose6(x)
745            | Self::GeneralPurpose7(x)
746            | Self::GeneralPurpose8(x)
747            | Self::PortamentoControl(x)
748            | Self::Effects1Depth(x)
749            | Self::Effects2Depth(x)
750            | Self::Effects3Depth(x)
751            | Self::Effects4Depth(x)
752            | Self::Effects5Depth(x)
753            | Self::ReverbSendLevel(x)
754            | Self::TremoloDepth(x)
755            | Self::ChorusSendLevel(x)
756            | Self::CelesteDepth(x)
757            | Self::PhaserDepth(x)
758            | Self::HighResVelocity(x)
759            | Self::DataDecrement(x)
760            | Self::DataIncrement(x) => *x,
761            Self::DataEntry2(msb, _) => *msb,
762            Self::ToggleLegato(x) | Self::TogglePortamento(x) => {
763                if *x {
764                    127
765                } else {
766                    0
767                }
768            }
769            Self::Parameter(_) => 0,
770        }
771    }
772
773    /// The 14-bit value of the control change. Non-high-res parameters are scaled to 14 bits. Will be 0 for `ControlChange::Parameter`.
774    pub fn value_high_res(&self) -> u16 {
775        match self {
776            Self::CC { value, .. } => (*value as u16) << 7,
777            Self::CCHighRes { value, .. } => *value,
778            Self::BankSelect(x)
779            | Self::ModWheel(x)
780            | Self::Breath(x)
781            | Self::Foot(x)
782            | Self::Portamento(x)
783            | Self::Volume(x)
784            | Self::Balance(x)
785            | Self::Pan(x)
786            | Self::Expression(x)
787            | Self::Effect1(x)
788            | Self::Effect2(x)
789            | Self::GeneralPurpose1(x)
790            | Self::GeneralPurpose2(x)
791            | Self::GeneralPurpose3(x)
792            | Self::GeneralPurpose4(x)
793            | Self::DataEntry(x) => *x,
794            Self::Hold(x)
795            | Self::Hold2(x)
796            | Self::Sostenuto(x)
797            | Self::SoftPedal(x)
798            | Self::SoundVariation(x)
799            | Self::Timbre(x)
800            | Self::ReleaseTime(x)
801            | Self::AttackTime(x)
802            | Self::Brightness(x)
803            | Self::DecayTime(x)
804            | Self::VibratoRate(x)
805            | Self::VibratoDepth(x)
806            | Self::VibratoDelay(x)
807            | Self::SoundControl1(x)
808            | Self::SoundControl2(x)
809            | Self::SoundControl3(x)
810            | Self::SoundControl4(x)
811            | Self::SoundControl5(x)
812            | Self::SoundControl6(x)
813            | Self::SoundControl7(x)
814            | Self::SoundControl8(x)
815            | Self::SoundControl9(x)
816            | Self::SoundControl10(x)
817            | Self::GeneralPurpose5(x)
818            | Self::GeneralPurpose6(x)
819            | Self::GeneralPurpose7(x)
820            | Self::GeneralPurpose8(x)
821            | Self::PortamentoControl(x)
822            | Self::Effects1Depth(x)
823            | Self::Effects2Depth(x)
824            | Self::Effects3Depth(x)
825            | Self::Effects4Depth(x)
826            | Self::Effects5Depth(x)
827            | Self::ReverbSendLevel(x)
828            | Self::TremoloDepth(x)
829            | Self::ChorusSendLevel(x)
830            | Self::CelesteDepth(x)
831            | Self::PhaserDepth(x)
832            | Self::HighResVelocity(x)
833            | Self::DataDecrement(x)
834            | Self::DataIncrement(x) => (*x as u16) << 7,
835            Self::DataEntry2(msb, lsb) => (*msb as u16) << 7 | *lsb as u16,
836            Self::ToggleLegato(x) | Self::TogglePortamento(x) => {
837                if *x {
838                    127 << 7
839                } else {
840                    0
841                }
842            }
843            Self::Parameter(_) => 0,
844        }
845    }
846
847    fn high_res_cc(v: &mut Vec<u8>, control: u8, value: u16) {
848        let [msb, lsb] = to_u14(value);
849        v.push(control);
850        v.push(msb);
851        v.push(control + 32);
852        v.push(lsb);
853    }
854
855    fn undefined(v: &mut Vec<u8>, control: u8, value: u8) {
856        v.push(control.min(119));
857        v.push(to_u7(value));
858    }
859
860    fn undefined_high_res(v: &mut Vec<u8>, control1: u8, control2: u8, value: u16) {
861        let [msb, lsb] = to_u14(value);
862        v.push(control1.min(119));
863        v.push(msb);
864        v.push(control2.min(119));
865        v.push(lsb);
866    }
867
868    fn is_msb(&self) -> bool {
869        match self {
870            Self::BankSelect(_)
871            | Self::ModWheel(_)
872            | Self::Breath(_)
873            | Self::DataEntry(_)
874            | Self::CCHighRes { .. }
875            | Self::Foot(_)
876            | Self::Portamento(_)
877            | Self::Volume(_)
878            | Self::Balance(_)
879            | Self::Pan(_)
880            | Self::Expression(_)
881            | Self::Effect1(_)
882            | Self::Effect2(_)
883            | Self::GeneralPurpose1(_)
884            | Self::GeneralPurpose2(_)
885            | Self::GeneralPurpose3(_)
886            | Self::GeneralPurpose4(_) => true,
887            Self::CC { control, .. } if control < &32 || control == &99 || control == &101 => true,
888            _ => false,
889        }
890    }
891
892    fn is_lsb(&self) -> bool {
893        matches!(self, Self::CC { control, .. } if (&32..&64).contains(&control) || control == &98 || control == &100)
894    }
895
896    pub fn to_midi_running(&self) -> Vec<u8> {
897        let mut r: Vec<u8> = vec![];
898        self.extend_midi_running(&mut r);
899        r
900    }
901
902    pub fn extend_midi_running(&self, v: &mut Vec<u8>) {
903        match *self {
904            ControlChange::BankSelect(x) => ControlChange::high_res_cc(v, 0, x),
905            ControlChange::ModWheel(x) => ControlChange::high_res_cc(v, 1, x),
906            ControlChange::Breath(x) => ControlChange::high_res_cc(v, 2, x),
907            ControlChange::CC { control, value } => ControlChange::undefined(v, control, value),
908            ControlChange::CCHighRes {
909                control1,
910                control2,
911                value,
912            } => ControlChange::undefined_high_res(v, control1, control2, value),
913            ControlChange::Foot(x) => ControlChange::high_res_cc(v, 4, x),
914            ControlChange::Portamento(x) => ControlChange::high_res_cc(v, 5, x),
915            ControlChange::Volume(x) => ControlChange::high_res_cc(v, 7, x),
916            ControlChange::Balance(x) => ControlChange::high_res_cc(v, 8, x),
917            ControlChange::Pan(x) => ControlChange::high_res_cc(v, 10, x),
918            ControlChange::Expression(x) => ControlChange::high_res_cc(v, 11, x),
919            ControlChange::Effect1(x) => ControlChange::high_res_cc(v, 12, x),
920            ControlChange::Effect2(x) => ControlChange::high_res_cc(v, 13, x),
921            ControlChange::GeneralPurpose1(x) => ControlChange::high_res_cc(v, 16, x),
922            ControlChange::GeneralPurpose2(x) => ControlChange::high_res_cc(v, 17, x),
923            ControlChange::GeneralPurpose3(x) => ControlChange::high_res_cc(v, 18, x),
924            ControlChange::GeneralPurpose4(x) => ControlChange::high_res_cc(v, 19, x),
925            ControlChange::GeneralPurpose5(x) => {
926                v.push(80);
927                v.push(to_u7(x));
928            }
929            ControlChange::GeneralPurpose6(x) => {
930                v.push(82);
931                v.push(to_u7(x));
932            }
933            ControlChange::GeneralPurpose7(x) => {
934                v.push(83);
935                v.push(to_u7(x));
936            }
937            ControlChange::GeneralPurpose8(x) => {
938                v.push(84);
939                v.push(to_u7(x));
940            }
941            ControlChange::Hold(x) => {
942                v.push(64);
943                v.push(to_u7(x));
944            }
945            ControlChange::Hold2(x) => {
946                v.push(69);
947                v.push(to_u7(x));
948            }
949            ControlChange::TogglePortamento(on) => {
950                v.push(65);
951                v.push(if on { 127 } else { 0 });
952            }
953            ControlChange::Sostenuto(x) => {
954                v.push(66);
955                v.push(to_u7(x));
956            }
957            ControlChange::SoftPedal(x) => {
958                v.push(67);
959                v.push(to_u7(x));
960            }
961            ControlChange::ToggleLegato(on) => {
962                v.push(68);
963                v.push(if on { 127 } else { 0 });
964            }
965            ControlChange::SoundVariation(x) | ControlChange::SoundControl1(x) => {
966                v.push(70);
967                v.push(to_u7(x));
968            }
969            ControlChange::Timbre(x) | ControlChange::SoundControl2(x) => {
970                v.push(71);
971                v.push(to_u7(x));
972            }
973            ControlChange::ReleaseTime(x) | ControlChange::SoundControl3(x) => {
974                v.push(72);
975                v.push(to_u7(x));
976            }
977            ControlChange::AttackTime(x) | ControlChange::SoundControl4(x) => {
978                v.push(73);
979                v.push(to_u7(x));
980            }
981            ControlChange::Brightness(x) | ControlChange::SoundControl5(x) => {
982                v.push(74);
983                v.push(to_u7(x));
984            }
985            ControlChange::DecayTime(x) | ControlChange::SoundControl6(x) => {
986                v.push(75);
987                v.push(to_u7(x));
988            }
989            ControlChange::VibratoRate(x) | ControlChange::SoundControl7(x) => {
990                v.push(76);
991                v.push(to_u7(x));
992            }
993            ControlChange::VibratoDepth(x) | ControlChange::SoundControl8(x) => {
994                v.push(77);
995                v.push(to_u7(x));
996            }
997            ControlChange::VibratoDelay(x) | ControlChange::SoundControl9(x) => {
998                v.push(78);
999                v.push(to_u7(x));
1000            }
1001            ControlChange::SoundControl10(x) => {
1002                v.push(79);
1003                v.push(to_u7(x));
1004            }
1005            ControlChange::PortamentoControl(x) => {
1006                v.push(84);
1007                v.push(to_u7(x));
1008            }
1009            ControlChange::HighResVelocity(x) => {
1010                v.push(88);
1011                v.push(to_u7(x));
1012            }
1013            ControlChange::Effects1Depth(x) | ControlChange::ReverbSendLevel(x) => {
1014                v.push(91);
1015                v.push(to_u7(x));
1016            }
1017            ControlChange::Effects2Depth(x) | ControlChange::TremoloDepth(x) => {
1018                v.push(92);
1019                v.push(to_u7(x));
1020            }
1021            ControlChange::Effects3Depth(x) | ControlChange::ChorusSendLevel(x) => {
1022                v.push(93);
1023                v.push(to_u7(x));
1024            }
1025            ControlChange::Effects4Depth(x) | ControlChange::CelesteDepth(x) => {
1026                v.push(94);
1027                v.push(to_u7(x));
1028            }
1029            ControlChange::Effects5Depth(x) | ControlChange::PhaserDepth(x) => {
1030                v.push(95);
1031                v.push(to_u7(x));
1032            }
1033
1034            // Parameters
1035            ControlChange::Parameter(p) => p.extend_midi_running(v),
1036            ControlChange::DataEntry(x) => ControlChange::high_res_cc(v, 6, x),
1037            ControlChange::DataEntry2(msb, lsb) => {
1038                v.push(6);
1039                v.push(msb);
1040                v.push(6 + 32);
1041                v.push(lsb);
1042            }
1043            ControlChange::DataIncrement(x) => {
1044                v.push(96);
1045                v.push(to_u7(x));
1046            }
1047            ControlChange::DataDecrement(x) => {
1048                v.push(97);
1049                v.push(to_u7(x));
1050            }
1051        }
1052    }
1053
1054    pub(crate) fn from_midi(m: &[u8], ctx: &ReceiverContext) -> Result<Self, ParseError> {
1055        if m.len() < 2 {
1056            return Err(crate::ParseError::UnexpectedEnd);
1057        }
1058
1059        if m[0] > 119 {
1060            return Err(ParseError::Invalid(
1061                "Tried to parse a control change message, but it looks like a channel mode message",
1062            ));
1063        }
1064
1065        let value = u8_from_u7(m[1])?;
1066        if !ctx.complex_cc {
1067            return Ok(ControlChange::CC {
1068                control: m[0],
1069                value,
1070            });
1071        }
1072        Ok(match m[0] {
1073            // 14 bit controls
1074            0 => Self::BankSelect((value as u16) << 7),
1075            1 => Self::ModWheel((value as u16) << 7),
1076            2 => Self::Breath((value as u16) << 7),
1077            4 => Self::Foot((value as u16) << 7),
1078            5 => Self::Portamento((value as u16) << 7),
1079            6 => Self::DataEntry((value as u16) << 7),
1080            7 => Self::Volume((value as u16) << 7),
1081            8 => Self::Balance((value as u16) << 7),
1082            10 => Self::Pan((value as u16) << 7),
1083            11 => Self::Expression((value as u16) << 7),
1084            12 => Self::Effect1((value as u16) << 7),
1085            13 => Self::Effect2((value as u16) << 7),
1086            16 => Self::GeneralPurpose1((value as u16) << 7),
1087            17 => Self::GeneralPurpose2((value as u16) << 7),
1088            18 => Self::GeneralPurpose3((value as u16) << 7),
1089            19 => Self::GeneralPurpose4((value as u16) << 7),
1090            // 7 bit controls
1091            64 => Self::Hold(value),
1092            65 => Self::TogglePortamento(bool_from_u7(m[1])?),
1093            66 => Self::Sostenuto(value),
1094            67 => Self::SoftPedal(value),
1095            68 => Self::ToggleLegato(bool_from_u7(m[1])?),
1096            69 => Self::Hold2(value),
1097            70 => Self::SoundControl1(value),
1098            71 => Self::SoundControl2(value),
1099            72 => Self::SoundControl3(value),
1100            73 => Self::SoundControl4(value),
1101            74 => Self::SoundControl5(value),
1102            75 => Self::SoundControl6(value),
1103            76 => Self::SoundControl7(value),
1104            77 => Self::SoundControl8(value),
1105            78 => Self::SoundControl9(value),
1106            79 => Self::SoundControl10(value),
1107            80 => Self::GeneralPurpose5(value),
1108            81 => Self::GeneralPurpose6(value),
1109            82 => Self::GeneralPurpose7(value),
1110            83 => Self::GeneralPurpose8(value),
1111            84 => Self::PortamentoControl(value),
1112            88 => Self::HighResVelocity(value),
1113            91 => Self::Effects1Depth(value),
1114            92 => Self::Effects2Depth(value),
1115            93 => Self::Effects3Depth(value),
1116            94 => Self::Effects4Depth(value),
1117            95 => Self::Effects5Depth(value),
1118            96 => Self::DataIncrement(value),
1119            97 => Self::DataDecrement(value),
1120            // Undefined controls (including parameters)
1121            3 | 9 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 => {
1122                Self::CCHighRes {
1123                    control1: m[0],
1124                    control2: m[0] + 32,
1125                    value: (value as u16) << 7,
1126                }
1127            }
1128            control => Self::CC { control, value },
1129        })
1130    }
1131
1132    fn maybe_extend(&self, other: &Self) -> Result<Self, ()> {
1133        match (self, other) {
1134            (Self::BankSelect(msb), Self::CC { control, value })
1135            | (Self::CC { control, value }, Self::BankSelect(msb))
1136                if *control == ControlNumber::BankSelectLSB as u8 =>
1137            {
1138                Ok(Self::BankSelect(replace_u14_lsb(*msb, *value)))
1139            }
1140            (Self::ModWheel(msb), Self::CC { control, value })
1141            | (Self::CC { control, value }, Self::ModWheel(msb))
1142                if *control == ControlNumber::ModWheelLSB as u8 =>
1143            {
1144                Ok(Self::ModWheel(replace_u14_lsb(*msb, *value)))
1145            }
1146            (Self::Breath(msb), Self::CC { control, value })
1147            | (Self::CC { control, value }, Self::Breath(msb))
1148                if *control == ControlNumber::BreathLSB as u8 =>
1149            {
1150                Ok(Self::Breath(replace_u14_lsb(*msb, *value)))
1151            }
1152            (Self::Foot(msb), Self::CC { control, value })
1153            | (Self::CC { control, value }, Self::Foot(msb))
1154                if *control == ControlNumber::FootLSB as u8 =>
1155            {
1156                Ok(Self::Foot(replace_u14_lsb(*msb, *value)))
1157            }
1158            (Self::Portamento(msb), Self::CC { control, value })
1159            | (Self::CC { control, value }, Self::Portamento(msb))
1160                if *control == ControlNumber::PortamentoLSB as u8 =>
1161            {
1162                Ok(Self::Portamento(replace_u14_lsb(*msb, *value)))
1163            }
1164            (Self::DataEntry(msb), Self::CC { control, value })
1165            | (Self::CC { control, value }, Self::DataEntry(msb))
1166                if *control == ControlNumber::DataEntryLSB as u8 =>
1167            {
1168                Ok(Self::DataEntry(replace_u14_lsb(*msb, *value)))
1169            }
1170            (Self::Volume(msb), Self::CC { control, value })
1171            | (Self::CC { control, value }, Self::Volume(msb))
1172                if *control == ControlNumber::VolumeLSB as u8 =>
1173            {
1174                Ok(Self::Volume(replace_u14_lsb(*msb, *value)))
1175            }
1176            (Self::Balance(msb), Self::CC { control, value })
1177            | (Self::CC { control, value }, Self::Balance(msb))
1178                if *control == ControlNumber::BalanceLSB as u8 =>
1179            {
1180                Ok(Self::Balance(replace_u14_lsb(*msb, *value)))
1181            }
1182            (Self::Pan(msb), Self::CC { control, value })
1183            | (Self::CC { control, value }, Self::Pan(msb))
1184                if *control == ControlNumber::PanLSB as u8 =>
1185            {
1186                Ok(Self::Pan(replace_u14_lsb(*msb, *value)))
1187            }
1188            (Self::Expression(msb), Self::CC { control, value })
1189            | (Self::CC { control, value }, Self::Expression(msb))
1190                if *control == ControlNumber::ExpressionLSB as u8 =>
1191            {
1192                Ok(Self::Expression(replace_u14_lsb(*msb, *value)))
1193            }
1194            (Self::Effect1(msb), Self::CC { control, value })
1195            | (Self::CC { control, value }, Self::Effect1(msb))
1196                if *control == ControlNumber::Effect1LSB as u8 =>
1197            {
1198                Ok(Self::Effect1(replace_u14_lsb(*msb, *value)))
1199            }
1200            (Self::Effect2(msb), Self::CC { control, value })
1201            | (Self::CC { control, value }, Self::Effect2(msb))
1202                if *control == ControlNumber::Effect2LSB as u8 =>
1203            {
1204                Ok(Self::Effect2(replace_u14_lsb(*msb, *value)))
1205            }
1206            (Self::GeneralPurpose1(msb), Self::CC { control, value })
1207            | (Self::CC { control, value }, Self::GeneralPurpose1(msb))
1208                if *control == ControlNumber::GeneralPurpose1LSB as u8 =>
1209            {
1210                Ok(Self::GeneralPurpose1(replace_u14_lsb(*msb, *value)))
1211            }
1212            (Self::GeneralPurpose2(msb), Self::CC { control, value })
1213            | (Self::CC { control, value }, Self::GeneralPurpose2(msb))
1214                if *control == ControlNumber::GeneralPurpose2LSB as u8 =>
1215            {
1216                Ok(Self::GeneralPurpose2(replace_u14_lsb(*msb, *value)))
1217            }
1218            (Self::GeneralPurpose3(msb), Self::CC { control, value })
1219            | (Self::CC { control, value }, Self::GeneralPurpose3(msb))
1220                if *control == ControlNumber::GeneralPurpose3LSB as u8 =>
1221            {
1222                Ok(Self::GeneralPurpose3(replace_u14_lsb(*msb, *value)))
1223            }
1224            (Self::GeneralPurpose4(msb), Self::CC { control, value })
1225            | (Self::CC { control, value }, Self::GeneralPurpose4(msb))
1226                if *control == ControlNumber::GeneralPurpose4LSB as u8 =>
1227            {
1228                Ok(Self::GeneralPurpose4(replace_u14_lsb(*msb, *value)))
1229            }
1230            (
1231                Self::CCHighRes {
1232                    control1,
1233                    control2,
1234                    value: msb,
1235                },
1236                Self::CC { control, value },
1237            )
1238            | (
1239                Self::CC { control, value },
1240                Self::CCHighRes {
1241                    control1,
1242                    control2,
1243                    value: msb,
1244                },
1245            ) if control == control2 => Ok(Self::CCHighRes {
1246                control1: *control1,
1247                control2: *control2,
1248                value: replace_u14_lsb(*msb, *value),
1249            }),
1250            // Parameters
1251            (
1252                Self::CC {
1253                    control: ctrl1,
1254                    value: val1,
1255                },
1256                Self::CC {
1257                    control: ctrl2,
1258                    value: val2,
1259                },
1260            ) => {
1261                let ((ctrl_lsb, ctrl_msb), (val_lsb, val_msb)) = if ctrl1 < ctrl2 {
1262                    ((*ctrl1, *ctrl2), (*val1, *val2))
1263                } else {
1264                    ((*ctrl2, *ctrl1), (*val2, *val1))
1265                };
1266
1267                if ctrl_lsb == ControlNumber::NonRegisteredParameterLSB as u8
1268                    && ctrl_msb == ControlNumber::NonRegisteredParameter as u8
1269                {
1270                    Ok(Self::Parameter(Parameter::Unregistered(u14_from_u7s(
1271                        val_msb, val_lsb,
1272                    ))))
1273                } else if ctrl_lsb == ControlNumber::RegisteredParameterLSB as u8
1274                    && ctrl_msb == ControlNumber::RegisteredParameter as u8
1275                {
1276                    Ok(Self::Parameter(Parameter::maybe_extend_cc(
1277                        val_msb, val_lsb,
1278                    )?))
1279                } else {
1280                    Err(())
1281                }
1282            }
1283            (Self::Parameter(param), Self::CC { control, value })
1284            | (Self::CC { control, value }, Self::Parameter(param))
1285                if *control == ControlNumber::DataEntryLSB as u8 =>
1286            {
1287                Ok(Self::Parameter(param.maybe_extend(None, Some(*value))?))
1288            }
1289
1290            (Self::Parameter(param), Self::DataEntry(value))
1291            | (Self::DataEntry(value), Self::Parameter(param)) => {
1292                Ok(Self::Parameter(param.maybe_extend(Some(*value), None)?))
1293            }
1294            _ => Err(()),
1295        }
1296    }
1297}
1298
1299#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1300/// Used by [`ControlChange::Parameter`]. "Entry" Parameters can be used to set the given parameters:
1301/// they will first select that parameter, then send a [`ControlChange::DataEntry`] with the given value.
1302pub enum Parameter {
1303    /// A whole bunch of parameters defined by the given number 0-16383, that can be used for whatever.
1304    Unregistered(u16),
1305    /// A registered parameter that does nothing.
1306    /// Defined in GM2.
1307    Null,
1308    /// The pitch bend sensitivity in semitones (0-127) and the sensitivity in cents (0-100),
1309    /// respectively. For example, a value (1, 0) means +/- one semitone (a total range of two
1310    /// semitones)
1311    PitchBendSensitivity,
1312    PitchBendSensitivityEntry(u8, u8),
1313    /// A value from -8192-8191, representing the fractional cents to shift away from A440
1314    /// in 1/8192ths of a cent.
1315    FineTuning,
1316    FineTuningEntry(i16),
1317    /// A value from -64-63, the number of semitones to shift away from A44.
1318    CoarseTuning,
1319    CoarseTuningEntry(i8),
1320    /// Which "Tuning Program" to select from: 0-127.
1321    ///
1322    /// Defined in the MIDI Tuning Standard (Updated Specification)
1323    TuningProgramSelect,
1324    TuningProgramSelectEntry(u8),
1325    /// Which "Tuning Bank" to select from: 0-127.
1326    ///
1327    /// Defined in the MIDI Tuning Standard (Updated Specification)
1328    TuningBankSelect,
1329    TuningBankSelectEntry(u8),
1330    /// The amount of "modulation depth" your mod wheel should apply: 0-16383.
1331    ///
1332    /// Defined in CA 26. GM2 defines what this range might mean
1333    ModulationDepthRange,
1334    ModulationDepthRangeEntry(u16),
1335    /// Only valid when sent to channel 1 or channel 16, the former indicating that this
1336    /// is configuring the number of "lower zone" channels and the latter referring to the
1337    /// "upper zone". A value between 0 (zone is not configured to be MPE) and 16 (zone has
1338    /// 16 channels in it). There can be no more than lower zone channels + upper zone channels
1339    /// active at a given time.
1340    ///
1341    /// Defined in RP-053: MIDI Polyphonic Expression
1342    PolyphonicExpression,
1343    PolyphonicExpressionEntry(u8),
1344    /// A value 0-16383 representing -180.00-179.98 degrees.
1345    ///
1346    /// Defined in RP-049
1347    AzimuthAngle3DSound,
1348    AzimuthAngle3DSoundEntry(u16),
1349    /// A value 0-16383 representing -180.00-179.98 degrees.
1350    ///
1351    /// Defined in RP-049
1352    ElevationAngle3DSound,
1353    ElevationAngle3DSoundEntry(u16),
1354    /// A value 1-16383 representing -163.82-0 dB of gain.
1355    ///
1356    /// 0 indicates "negative infinity".
1357    ///
1358    /// Defined in RP-049
1359    Gain3DSound,
1360    Gain3DSoundEntry(u16),
1361    /// A value 0-16383 representing a ratio between -0.000061-1.0.
1362    ///
1363    /// Defined in RP-049
1364    DistanceRatio3DSound,
1365    DistanceRatio3DSoundEntry(u16),
1366    /// A value 0-16383 representing between 0 and 1000 distance units.
1367    /// Defined in RP-049
1368    MaxiumumDistance3DSound,
1369    MaxiumumDistance3DSoundEntry(u16),
1370    /// A value 0-16383 representing -163.83-0 dB of gain
1371    /// Defined in RP-049
1372    GainAtMaxiumumDistance3DSound,
1373    GainAtMaxiumumDistance3DSoundEntry(u16),
1374    /// A value 0-16383 representing a ratio between -0.000061-1.0
1375    /// Defined in RP-049
1376    ReferenceDistanceRatio3DSound,
1377    ReferenceDistanceRatio3DSoundEntry(u16),
1378    /// A value 0-16383 representing -180.00-179.98 degrees
1379    /// Defined in RP-049
1380    PanSpreadAngle3DSound,
1381    PanSpreadAngle3DSoundEntry(u16),
1382    /// A value 0-16383 representing -180.00-179.98 degrees
1383    /// Defined in RP-049
1384    RollAngle3DSound,
1385    RollAngle3DSoundEntry(u16),
1386}
1387
1388impl Parameter {
1389    fn extend_midi_running(&self, v: &mut Vec<u8>) {
1390        match self {
1391            Self::Null => {
1392                v.push(100);
1393                v.push(0x7F);
1394                v.push(101);
1395                v.push(0x7F);
1396            }
1397            Self::PitchBendSensitivity => {
1398                v.push(100);
1399                v.push(0);
1400                v.push(101);
1401                v.push(0);
1402            }
1403            Self::PitchBendSensitivityEntry(c, f) => {
1404                Self::PitchBendSensitivity.extend_midi_running(v);
1405                // Data entry:
1406                v.push(6);
1407                v.push(*c);
1408                v.push(6 + 32);
1409                v.push((*f).min(100));
1410            }
1411            Self::FineTuning => {
1412                v.push(100);
1413                v.push(1);
1414                v.push(101);
1415                v.push(0);
1416            }
1417            Self::FineTuningEntry(x) => {
1418                Self::FineTuning.extend_midi_running(v);
1419                // Data entry:
1420                let [msb, lsb] = i_to_u14(*x);
1421                v.push(6);
1422                v.push(msb);
1423                v.push(6 + 32);
1424                v.push(lsb);
1425            }
1426            Self::CoarseTuning => {
1427                v.push(100);
1428                v.push(2);
1429                v.push(101);
1430                v.push(0);
1431            }
1432            Self::CoarseTuningEntry(x) => {
1433                Self::CoarseTuning.extend_midi_running(v);
1434                // Data entry:
1435                let msb = i_to_u7(*x);
1436                v.push(6);
1437                v.push(msb);
1438                v.push(6 + 32);
1439                v.push(0);
1440            }
1441            Self::TuningProgramSelect => {
1442                v.push(100);
1443                v.push(3);
1444                v.push(101);
1445                v.push(0);
1446            }
1447            Self::TuningProgramSelectEntry(x) => {
1448                Self::TuningProgramSelect.extend_midi_running(v);
1449                // Data entry (MSB only)
1450                v.push(6);
1451                v.push(*x);
1452            }
1453            Self::TuningBankSelect => {
1454                v.push(100);
1455                v.push(4);
1456                v.push(101);
1457                v.push(0);
1458            }
1459            Self::TuningBankSelectEntry(x) => {
1460                Self::TuningBankSelect.extend_midi_running(v);
1461                // Data entry (MSB only)
1462                v.push(6);
1463                v.push(*x);
1464            }
1465            Self::ModulationDepthRange => {
1466                v.push(100);
1467                v.push(5);
1468                v.push(101);
1469                v.push(0);
1470            }
1471            Self::ModulationDepthRangeEntry(x) => {
1472                Self::ModulationDepthRange.extend_midi_running(v);
1473                // Data entry
1474                ControlChange::high_res_cc(v, 6, *x);
1475            }
1476            Self::PolyphonicExpression => {
1477                v.push(100);
1478                v.push(6);
1479                v.push(101);
1480                v.push(0);
1481            }
1482            Self::PolyphonicExpressionEntry(x) => {
1483                Self::PolyphonicExpression.extend_midi_running(v);
1484                // Data entry (MSB only)
1485                v.push(6);
1486                v.push((*x).min(16));
1487            }
1488            Self::AzimuthAngle3DSound => {
1489                v.push(100);
1490                v.push(0);
1491                v.push(101);
1492                v.push(61); // 3D Sound
1493            }
1494            Self::AzimuthAngle3DSoundEntry(x) => {
1495                Self::AzimuthAngle3DSound.extend_midi_running(v);
1496                // Data entry
1497                ControlChange::high_res_cc(v, 6, *x);
1498            }
1499            Self::ElevationAngle3DSound => {
1500                v.push(100);
1501                v.push(1);
1502                v.push(101);
1503                v.push(61); // 3D Sound
1504            }
1505            Self::ElevationAngle3DSoundEntry(x) => {
1506                Self::ElevationAngle3DSound.extend_midi_running(v);
1507                // Data entry
1508                ControlChange::high_res_cc(v, 6, *x);
1509            }
1510            Self::Gain3DSound => {
1511                v.push(100);
1512                v.push(2);
1513                v.push(101);
1514                v.push(61); // 3D Sound
1515            }
1516            Self::Gain3DSoundEntry(x) => {
1517                Self::Gain3DSound.extend_midi_running(v);
1518                // Data entry
1519                ControlChange::high_res_cc(v, 6, *x);
1520            }
1521            Self::DistanceRatio3DSound => {
1522                v.push(100);
1523                v.push(3);
1524                v.push(101);
1525                v.push(61); // 3D Sound
1526            }
1527            Self::DistanceRatio3DSoundEntry(x) => {
1528                Self::DistanceRatio3DSound.extend_midi_running(v);
1529                // Data entry
1530                ControlChange::high_res_cc(v, 6, *x);
1531            }
1532            Self::MaxiumumDistance3DSound => {
1533                v.push(100);
1534                v.push(4);
1535                v.push(101);
1536                v.push(61); // 3D Sound
1537            }
1538            Self::MaxiumumDistance3DSoundEntry(x) => {
1539                Self::MaxiumumDistance3DSound.extend_midi_running(v);
1540                // Data entry
1541                ControlChange::high_res_cc(v, 6, *x);
1542            }
1543            Self::GainAtMaxiumumDistance3DSound => {
1544                v.push(100);
1545                v.push(5);
1546                v.push(101);
1547                v.push(61); // 3D Sound
1548            }
1549            Self::GainAtMaxiumumDistance3DSoundEntry(x) => {
1550                Self::GainAtMaxiumumDistance3DSound.extend_midi_running(v);
1551                // Data entry
1552                ControlChange::high_res_cc(v, 6, *x);
1553            }
1554            Self::ReferenceDistanceRatio3DSound => {
1555                v.push(100);
1556                v.push(6);
1557                v.push(101);
1558                v.push(61); // 3D Sound
1559            }
1560            Self::ReferenceDistanceRatio3DSoundEntry(x) => {
1561                Self::ReferenceDistanceRatio3DSound.extend_midi_running(v);
1562                // Data entry
1563                ControlChange::high_res_cc(v, 6, *x);
1564            }
1565            Self::PanSpreadAngle3DSound => {
1566                v.push(100);
1567                v.push(7);
1568                v.push(101);
1569                v.push(61); // 3D Sound
1570            }
1571            Self::PanSpreadAngle3DSoundEntry(x) => {
1572                Self::PanSpreadAngle3DSound.extend_midi_running(v);
1573                // Data entry
1574                ControlChange::high_res_cc(v, 6, *x);
1575            }
1576            Self::RollAngle3DSound => {
1577                v.push(100);
1578                v.push(8);
1579                v.push(101);
1580                v.push(61); // 3D Sound
1581            }
1582            Self::RollAngle3DSoundEntry(x) => {
1583                Self::RollAngle3DSound.extend_midi_running(v);
1584                // Data entry
1585                ControlChange::high_res_cc(v, 6, *x);
1586            }
1587            Self::Unregistered(x) => {
1588                let [msb, lsb] = to_u14(*x);
1589                v.push(98);
1590                v.push(lsb);
1591                v.push(99);
1592                v.push(msb);
1593            }
1594        }
1595    }
1596
1597    fn maybe_extend_cc(msb: u8, lsb: u8) -> Result<Self, ()> {
1598        match (msb, lsb) {
1599            (0x7F, 0x7F) => Ok(Self::Null),
1600            (0, 0) => Ok(Self::PitchBendSensitivity),
1601            (0, 1) => Ok(Self::FineTuning),
1602            (0, 2) => Ok(Self::CoarseTuning),
1603            (0, 3) => Ok(Self::TuningProgramSelect),
1604            (0, 4) => Ok(Self::TuningBankSelect),
1605            (0, 5) => Ok(Self::ModulationDepthRange),
1606            (0, 6) => Ok(Self::PolyphonicExpression),
1607            (61, 0) => Ok(Self::AzimuthAngle3DSound),
1608            (61, 1) => Ok(Self::ElevationAngle3DSound),
1609            (61, 2) => Ok(Self::Gain3DSound),
1610            (61, 3) => Ok(Self::DistanceRatio3DSound),
1611            (61, 4) => Ok(Self::MaxiumumDistance3DSound),
1612            (61, 5) => Ok(Self::GainAtMaxiumumDistance3DSound),
1613            (61, 6) => Ok(Self::ReferenceDistanceRatio3DSound),
1614            (61, 7) => Ok(Self::PanSpreadAngle3DSound),
1615            (61, 8) => Ok(Self::RollAngle3DSound),
1616            _ => Err(()),
1617        }
1618    }
1619
1620    fn maybe_extend(&self, msb: Option<u16>, lsb: Option<u8>) -> Result<Self, ()> {
1621        match self {
1622            Self::PitchBendSensitivity => Ok(Self::PitchBendSensitivityEntry(
1623                msb.map_or(0, |v| (v >> 7) as u8),
1624                lsb.unwrap_or(0),
1625            )),
1626            Self::PitchBendSensitivityEntry(v1, v2) => Ok(Self::PitchBendSensitivityEntry(
1627                msb.map_or(*v1, |v| v as u8),
1628                lsb.unwrap_or(*v2),
1629            )),
1630            Self::FineTuning => Ok(Self::FineTuningEntry(i14_from_u7s(
1631                msb.map_or(0, |v| (v >> 7) as u8),
1632                lsb.unwrap_or(0),
1633            ))),
1634            Self::FineTuningEntry(v) => Ok(Self::FineTuningEntry(i14_from_u7s(
1635                msb.map_or(i_to_u14(*v)[0], |v| v as u8),
1636                lsb.unwrap_or(i_to_u14(*v)[1]),
1637            ))),
1638            Self::CoarseTuning => Ok(Self::CoarseTuningEntry(msb.map_or(0, |v| u7_to_i(v as u8)))),
1639            Self::CoarseTuningEntry(v) => Ok(Self::CoarseTuningEntry(
1640                msb.map_or(*v, |v| u7_to_i(v as u8)),
1641            )),
1642            Self::TuningProgramSelect => {
1643                Ok(Self::TuningProgramSelectEntry(msb.map_or(0, |v| v as u8)))
1644            }
1645            Self::TuningProgramSelectEntry(v) => {
1646                Ok(Self::TuningProgramSelectEntry(msb.map_or(*v, |v| v as u8)))
1647            }
1648            Self::TuningBankSelect => Ok(Self::TuningBankSelectEntry(msb.map_or(0, |v| v as u8))),
1649            Self::TuningBankSelectEntry(v) => {
1650                Ok(Self::TuningBankSelectEntry(msb.map_or(*v, |v| v as u8)))
1651            }
1652            Self::ModulationDepthRange => Ok(Self::ModulationDepthRangeEntry(replace_u14_lsb(
1653                msb.unwrap_or(0),
1654                lsb.unwrap_or(0),
1655            ))),
1656            Self::ModulationDepthRangeEntry(v) => Ok(Self::ModulationDepthRangeEntry(
1657                replace_u14_lsb(msb.unwrap_or(*v), lsb.unwrap_or((*v as u8) & 0b01111111)),
1658            )),
1659            Self::PolyphonicExpression => {
1660                Ok(Self::PolyphonicExpressionEntry(msb.map_or(0, |v| v as u8)))
1661            }
1662            Self::PolyphonicExpressionEntry(v) => {
1663                Ok(Self::PolyphonicExpressionEntry(msb.map_or(*v, |v| v as u8)))
1664            }
1665            Self::AzimuthAngle3DSound => Ok(Self::AzimuthAngle3DSoundEntry(replace_u14_lsb(
1666                msb.unwrap_or(0),
1667                lsb.unwrap_or(0),
1668            ))),
1669            Self::AzimuthAngle3DSoundEntry(v) => Ok(Self::AzimuthAngle3DSoundEntry(
1670                replace_u14_lsb(msb.unwrap_or(*v), lsb.unwrap_or((*v as u8) & 0b01111111)),
1671            )),
1672            Self::ElevationAngle3DSound => Ok(Self::ElevationAngle3DSoundEntry(replace_u14_lsb(
1673                msb.unwrap_or(0),
1674                lsb.unwrap_or(0),
1675            ))),
1676            Self::ElevationAngle3DSoundEntry(v) => Ok(Self::ElevationAngle3DSoundEntry(
1677                replace_u14_lsb(msb.unwrap_or(*v), lsb.unwrap_or((*v as u8) & 0b01111111)),
1678            )),
1679            Self::Gain3DSound => Ok(Self::Gain3DSoundEntry(replace_u14_lsb(
1680                msb.unwrap_or(0),
1681                lsb.unwrap_or(0),
1682            ))),
1683            Self::Gain3DSoundEntry(v) => Ok(Self::Gain3DSoundEntry(replace_u14_lsb(
1684                msb.unwrap_or(*v),
1685                lsb.unwrap_or((*v as u8) & 0b01111111),
1686            ))),
1687            Self::DistanceRatio3DSound => Ok(Self::DistanceRatio3DSoundEntry(replace_u14_lsb(
1688                msb.unwrap_or(0),
1689                lsb.unwrap_or(0),
1690            ))),
1691            Self::DistanceRatio3DSoundEntry(v) => Ok(Self::DistanceRatio3DSoundEntry(
1692                replace_u14_lsb(msb.unwrap_or(*v), lsb.unwrap_or((*v as u8) & 0b01111111)),
1693            )),
1694            Self::MaxiumumDistance3DSound => Ok(Self::MaxiumumDistance3DSoundEntry(
1695                replace_u14_lsb(msb.unwrap_or(0), lsb.unwrap_or(0)),
1696            )),
1697            Self::MaxiumumDistance3DSoundEntry(v) => Ok(Self::MaxiumumDistance3DSoundEntry(
1698                replace_u14_lsb(msb.unwrap_or(*v), lsb.unwrap_or((*v as u8) & 0b01111111)),
1699            )),
1700            Self::GainAtMaxiumumDistance3DSound => Ok(Self::GainAtMaxiumumDistance3DSoundEntry(
1701                replace_u14_lsb(msb.unwrap_or(0), lsb.unwrap_or(0)),
1702            )),
1703            Self::GainAtMaxiumumDistance3DSoundEntry(v) => {
1704                Ok(Self::GainAtMaxiumumDistance3DSoundEntry(replace_u14_lsb(
1705                    msb.unwrap_or(*v),
1706                    lsb.unwrap_or((*v as u8) & 0b01111111),
1707                )))
1708            }
1709            Self::ReferenceDistanceRatio3DSound => Ok(Self::ReferenceDistanceRatio3DSoundEntry(
1710                replace_u14_lsb(msb.unwrap_or(0), lsb.unwrap_or(0)),
1711            )),
1712            Self::ReferenceDistanceRatio3DSoundEntry(v) => {
1713                Ok(Self::ReferenceDistanceRatio3DSoundEntry(replace_u14_lsb(
1714                    msb.unwrap_or(*v),
1715                    lsb.unwrap_or((*v as u8) & 0b01111111),
1716                )))
1717            }
1718            Self::PanSpreadAngle3DSound => Ok(Self::PanSpreadAngle3DSoundEntry(replace_u14_lsb(
1719                msb.unwrap_or(0),
1720                lsb.unwrap_or(0),
1721            ))),
1722            Self::PanSpreadAngle3DSoundEntry(v) => Ok(Self::PanSpreadAngle3DSoundEntry(
1723                replace_u14_lsb(msb.unwrap_or(*v), lsb.unwrap_or((*v as u8) & 0b01111111)),
1724            )),
1725            Self::RollAngle3DSound => Ok(Self::RollAngle3DSoundEntry(replace_u14_lsb(
1726                msb.unwrap_or(0),
1727                lsb.unwrap_or(0),
1728            ))),
1729            Self::RollAngle3DSoundEntry(v) => Ok(Self::RollAngle3DSoundEntry(replace_u14_lsb(
1730                msb.unwrap_or(*v),
1731                lsb.unwrap_or((*v as u8) & 0b01111111),
1732            ))),
1733            _ => Err(()),
1734        }
1735    }
1736}
1737
1738#[cfg(test)]
1739mod tests {
1740    use crate::*;
1741    use alloc::vec;
1742
1743    #[test]
1744    fn serialize_channel_voice_msg() {
1745        assert_eq!(
1746            MidiMsg::ChannelVoice {
1747                channel: Channel::Ch1,
1748                msg: ChannelVoiceMsg::NoteOn {
1749                    note: 0x88,
1750                    velocity: 0xff
1751                }
1752            }
1753            .to_midi(),
1754            vec![0x90, 0x7f, 127]
1755        );
1756
1757        assert_eq!(
1758            MidiMsg::RunningChannelVoice {
1759                channel: Channel::Ch10,
1760                msg: ChannelVoiceMsg::PitchBend { bend: 0xff44 }
1761            }
1762            .to_midi(),
1763            vec![0x7f, 0x7f]
1764        );
1765
1766        assert_eq!(
1767            MidiMsg::ChannelVoice {
1768                channel: Channel::Ch10,
1769                msg: ChannelVoiceMsg::PitchBend { bend: 1000 }
1770            }
1771            .to_midi(),
1772            vec![0xE9, 0x68, 0x07]
1773        );
1774
1775        assert_eq!(
1776            MidiMsg::ChannelVoice {
1777                channel: Channel::Ch2,
1778                msg: ChannelVoiceMsg::ControlChange {
1779                    control: ControlChange::Volume(1000)
1780                }
1781            }
1782            .to_midi(),
1783            vec![0xB1, 7, 0x07, 39, 0x68]
1784        );
1785
1786        assert_eq!(
1787            MidiMsg::ChannelVoice {
1788                channel: Channel::Ch4,
1789                msg: ChannelVoiceMsg::ControlChange {
1790                    control: ControlChange::CC {
1791                        control: 85,
1792                        value: 77
1793                    }
1794                }
1795            }
1796            .to_midi(),
1797            vec![0xB3, 85, 77]
1798        );
1799
1800        assert_eq!(
1801            MidiMsg::ChannelVoice {
1802                channel: Channel::Ch2,
1803                msg: ChannelVoiceMsg::ControlChange {
1804                    control: ControlChange::CCHighRes {
1805                        control1: 3,
1806                        control2: 35,
1807                        value: 1000
1808                    }
1809                }
1810            }
1811            .to_midi(),
1812            vec![0xB1, 3, 0x07, 35, 0x68]
1813        );
1814
1815        assert_eq!(
1816            MidiMsg::ChannelVoice {
1817                channel: Channel::Ch3,
1818                msg: ChannelVoiceMsg::ControlChange {
1819                    control: ControlChange::TogglePortamento(true)
1820                }
1821            }
1822            .to_midi(),
1823            vec![0xB2, 65, 0x7f]
1824        );
1825
1826        assert_eq!(
1827            MidiMsg::ChannelVoice {
1828                channel: Channel::Ch2,
1829                msg: ChannelVoiceMsg::ControlChange {
1830                    control: ControlChange::Parameter(Parameter::FineTuning)
1831                }
1832            }
1833            .to_midi(),
1834            vec![0xB1, 100, 0x01, 101, 0x00]
1835        );
1836
1837        assert_eq!(
1838            MidiMsg::ChannelVoice {
1839                channel: Channel::Ch2,
1840                msg: ChannelVoiceMsg::ControlChange {
1841                    control: ControlChange::Parameter(Parameter::Unregistered(1000))
1842                }
1843            }
1844            .to_midi(),
1845            vec![0xB1, 98, 0x68, 99, 0x07]
1846        );
1847    }
1848
1849    #[test]
1850    fn deserialize_channel_voice_msg() {
1851        let mut ctx = ReceiverContext::new().complex_cc();
1852
1853        test_serialization(
1854            MidiMsg::ChannelVoice {
1855                channel: Channel::Ch1,
1856                msg: ChannelVoiceMsg::NoteOn {
1857                    note: 0x7f,
1858                    velocity: 0x7f,
1859                },
1860            },
1861            &mut ctx,
1862        );
1863
1864        test_serialization(
1865            MidiMsg::ChannelVoice {
1866                channel: Channel::Ch10,
1867                msg: ChannelVoiceMsg::PitchBend { bend: 1000 },
1868            },
1869            &mut ctx,
1870        );
1871
1872        test_serialization(
1873            MidiMsg::ChannelVoice {
1874                channel: Channel::Ch2,
1875                msg: ChannelVoiceMsg::ControlChange {
1876                    control: ControlChange::Volume(1000),
1877                },
1878            },
1879            &mut ctx,
1880        );
1881
1882        test_serialization(
1883            MidiMsg::ChannelVoice {
1884                channel: Channel::Ch4,
1885                msg: ChannelVoiceMsg::ControlChange {
1886                    control: ControlChange::CC {
1887                        control: 85,
1888                        value: 77,
1889                    },
1890                },
1891            },
1892            &mut ctx,
1893        );
1894
1895        test_serialization(
1896            MidiMsg::ChannelVoice {
1897                channel: Channel::Ch2,
1898                msg: ChannelVoiceMsg::ControlChange {
1899                    control: ControlChange::CCHighRes {
1900                        control1: 3,
1901                        control2: 35,
1902                        value: 1000,
1903                    },
1904                },
1905            },
1906            &mut ctx,
1907        );
1908
1909        test_serialization(
1910            MidiMsg::ChannelVoice {
1911                channel: Channel::Ch3,
1912                msg: ChannelVoiceMsg::ControlChange {
1913                    control: ControlChange::TogglePortamento(true),
1914                },
1915            },
1916            &mut ctx,
1917        );
1918
1919        test_serialization(
1920            MidiMsg::ChannelVoice {
1921                channel: Channel::Ch2,
1922                msg: ChannelVoiceMsg::ControlChange {
1923                    control: ControlChange::Parameter(Parameter::FineTuning),
1924                },
1925            },
1926            &mut ctx,
1927        );
1928
1929        test_serialization(
1930            MidiMsg::ChannelVoice {
1931                channel: Channel::Ch2,
1932                msg: ChannelVoiceMsg::ControlChange {
1933                    control: ControlChange::Parameter(Parameter::Unregistered(1000)),
1934                },
1935            },
1936            &mut ctx,
1937        );
1938
1939        test_serialization(
1940            MidiMsg::ChannelVoice {
1941                channel: Channel::Ch3,
1942                msg: ChannelVoiceMsg::HighResNoteOn {
1943                    note: 77,
1944                    velocity: 1000,
1945                },
1946            },
1947            &mut ctx,
1948        );
1949
1950        test_serialization(
1951            MidiMsg::ChannelVoice {
1952                channel: Channel::Ch2,
1953                msg: ChannelVoiceMsg::ControlChange {
1954                    control: ControlChange::Parameter(Parameter::FineTuningEntry(-30)),
1955                },
1956            },
1957            &mut ctx,
1958        );
1959
1960        test_serialization(
1961            MidiMsg::ChannelVoice {
1962                channel: Channel::Ch2,
1963                msg: ChannelVoiceMsg::ControlChange {
1964                    control: ControlChange::Parameter(Parameter::Gain3DSoundEntry(1001)),
1965                },
1966            },
1967            &mut ctx,
1968        );
1969
1970        test_serialization(
1971            MidiMsg::ChannelVoice {
1972                channel: Channel::Ch2,
1973                msg: ChannelVoiceMsg::ControlChange {
1974                    control: ControlChange::Parameter(Parameter::PitchBendSensitivityEntry(4, 78)),
1975                },
1976            },
1977            &mut ctx,
1978        );
1979
1980        test_serialization(
1981            MidiMsg::ChannelVoice {
1982                channel: Channel::Ch2,
1983                msg: ChannelVoiceMsg::ControlChange {
1984                    control: ControlChange::GeneralPurpose1(50),
1985                },
1986            },
1987            &mut ctx,
1988        );
1989    }
1990
1991    #[test]
1992    fn test_cc_control_and_value() {
1993        assert_eq!(
1994            ControlChange::CC {
1995                control: 20,
1996                value: 40
1997            }
1998            .control(),
1999            20
2000        );
2001        assert_eq!(
2002            ControlChange::CC {
2003                control: 20,
2004                value: 40
2005            }
2006            .value(),
2007            40
2008        );
2009        assert_eq!(
2010            ControlChange::CC {
2011                control: 20,
2012                value: 40
2013            }
2014            .value_high_res(),
2015            40 << 7
2016        );
2017
2018        assert_eq!(ControlChange::Breath(40 << 7).control(), 2);
2019        assert_eq!(ControlChange::Breath(40 << 7).value(), 40);
2020        assert_eq!(ControlChange::Breath(40 << 7).value_high_res(), 40 << 7);
2021    }
2022
2023    #[test]
2024    fn test_cc_to_complex_and_to_simple() {
2025        assert_eq!(
2026            ControlChange::CC {
2027                control: 2,
2028                value: 40
2029            }
2030            .to_complex(),
2031            ControlChange::Breath(40 << 7)
2032        );
2033        assert_eq!(
2034            ControlChange::Breath(40 << 7).to_simple(),
2035            ControlChange::CC {
2036                control: 2,
2037                value: 40
2038            }
2039        );
2040        assert_eq!(
2041            ControlChange::Breath(40 << 7).to_simple_high_res(),
2042            ControlChange::CCHighRes {
2043                control1: 2,
2044                control2: 34,
2045                value: 40 << 7
2046            }
2047        );
2048
2049        assert_eq!(
2050            ControlChange::CC {
2051                control: 20,
2052                value: 40
2053            }
2054            .to_complex(),
2055            ControlChange::CCHighRes {
2056                control1: 20,
2057                control2: 52,
2058                value: 40 << 7,
2059            }
2060        );
2061        assert_eq!(
2062            ControlChange::CCHighRes {
2063                control1: 20,
2064                control2: 52,
2065                value: 40 << 7,
2066            }
2067            .to_simple(),
2068            ControlChange::CC {
2069                control: 20,
2070                value: 40,
2071            },
2072        );
2073        assert_eq!(
2074            ControlChange::CCHighRes {
2075                control1: 20,
2076                control2: 52,
2077                value: 40 << 7,
2078            }
2079            .to_simple_high_res(),
2080            ControlChange::CCHighRes {
2081                control1: 20,
2082                control2: 52,
2083                value: 40 << 7,
2084            }
2085        );
2086    }
2087}