1use crate::ReceiverContext;
2
3use super::parse_error::*;
4use super::util::*;
5use alloc::vec;
6use alloc::vec::Vec;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ChannelVoiceMsg {
12 NoteOn {
14 note: u8,
16 velocity: u8,
18 },
19 NoteOff {
21 note: u8,
23 velocity: u8,
25 },
26 ControlChange { control: ControlChange },
28 HighResNoteOn { note: u8, velocity: u16 },
30 HighResNoteOff { note: u8, velocity: u16 },
32 PolyPressure {
36 note: u8,
38 pressure: u8,
40 },
41 ChannelPressure { pressure: u8 },
43 ProgramChange { program: u8 },
46 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 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 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 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 Ok((
266 Self::ControlChange {
267 control: ControlChange::from_midi(m, ctx)?,
268 },
269 2,
270 ))
271 }
272 }
273 }
274}
275
276#[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 Hold = 64,
313 TogglePortamento = 65,
314 Sostenuto = 66,
315 SoftPedal = 67,
316 ToggleLegato = 68,
317 Hold2 = 69,
318 SoundControl1 = 70,
320 SoundControl2 = 71,
322 SoundControl3 = 72,
324 SoundControl4 = 73,
326 SoundControl5 = 74,
328 SoundControl6 = 75,
330 SoundControl7 = 76,
332 SoundControl8 = 77,
334 SoundControl9 = 78,
336 SoundControl10 = 79,
337 GeneralPurpose5 = 80,
338 GeneralPurpose6 = 81,
339 GeneralPurpose7 = 82,
340 GeneralPurpose8 = 83,
341 PortamentoControl = 84,
342 HighResVelocity = 88,
343 Effects1Depth = 91,
345 Effects2Depth = 92,
347 Effects3Depth = 93,
349 Effects4Depth = 94,
351 Effects5Depth = 95,
353 DataIncrement = 96,
354 DataDecrement = 97,
355 NonRegisteredParameterLSB = 98,
356 NonRegisteredParameter = 99,
357 RegisteredParameterLSB = 100,
358 RegisteredParameter = 101,
359}
360
361#[derive(Debug, Clone, Copy, PartialEq, Eq)]
366pub enum ControlChange {
367 CC {
371 control: u8,
372 value: u8,
374 },
375 CCHighRes {
379 control1: u8,
380 control2: u8,
381 value: u16,
383 },
384
385 BankSelect(u16),
387 ModWheel(u16),
389 Breath(u16),
391 Foot(u16),
393 Portamento(u16),
395 Volume(u16),
397 Balance(u16),
399 Pan(u16),
401 Expression(u16),
403 Effect1(u16),
405 Effect2(u16),
407 GeneralPurpose1(u16),
409 GeneralPurpose2(u16),
411 GeneralPurpose3(u16),
413 GeneralPurpose4(u16),
415 GeneralPurpose5(u8),
417 GeneralPurpose6(u8),
419 GeneralPurpose7(u8),
421 GeneralPurpose8(u8),
423 Hold(u8),
425 Hold2(u8),
427 TogglePortamento(bool),
429 Sostenuto(u8),
431 SoftPedal(u8),
433 ToggleLegato(bool),
435 SoundVariation(u8),
437 Timbre(u8),
439 ReleaseTime(u8),
441 AttackTime(u8),
443 Brightness(u8),
446 DecayTime(u8),
448 VibratoRate(u8),
450 VibratoDepth(u8),
452 VibratoDelay(u8),
454 SoundControl1(u8),
456 SoundControl2(u8),
458 SoundControl3(u8),
460 SoundControl4(u8),
462 SoundControl5(u8),
464 SoundControl6(u8),
466 SoundControl7(u8),
468 SoundControl8(u8),
470 SoundControl9(u8),
472 SoundControl10(u8),
474 HighResVelocity(u8),
477 PortamentoControl(u8),
479 Effects1Depth(u8),
481 Effects2Depth(u8),
483 Effects3Depth(u8),
485 Effects4Depth(u8),
487 Effects5Depth(u8),
489 ReverbSendLevel(u8),
491 TremoloDepth(u8),
493 ChorusSendLevel(u8),
495 CelesteDepth(u8),
497 PhaserDepth(u8),
499 Parameter(Parameter),
501 DataEntry(u16),
503 DataEntry2(u8, u8),
505 DataIncrement(u8),
507 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 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 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 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 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 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 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 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 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 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 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 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 (
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)]
1300pub enum Parameter {
1303 Unregistered(u16),
1305 Null,
1308 PitchBendSensitivity,
1312 PitchBendSensitivityEntry(u8, u8),
1313 FineTuning,
1316 FineTuningEntry(i16),
1317 CoarseTuning,
1319 CoarseTuningEntry(i8),
1320 TuningProgramSelect,
1324 TuningProgramSelectEntry(u8),
1325 TuningBankSelect,
1329 TuningBankSelectEntry(u8),
1330 ModulationDepthRange,
1334 ModulationDepthRangeEntry(u16),
1335 PolyphonicExpression,
1343 PolyphonicExpressionEntry(u8),
1344 AzimuthAngle3DSound,
1348 AzimuthAngle3DSoundEntry(u16),
1349 ElevationAngle3DSound,
1353 ElevationAngle3DSoundEntry(u16),
1354 Gain3DSound,
1360 Gain3DSoundEntry(u16),
1361 DistanceRatio3DSound,
1365 DistanceRatio3DSoundEntry(u16),
1366 MaxiumumDistance3DSound,
1369 MaxiumumDistance3DSoundEntry(u16),
1370 GainAtMaxiumumDistance3DSound,
1373 GainAtMaxiumumDistance3DSoundEntry(u16),
1374 ReferenceDistanceRatio3DSound,
1377 ReferenceDistanceRatio3DSoundEntry(u16),
1378 PanSpreadAngle3DSound,
1381 PanSpreadAngle3DSoundEntry(u16),
1382 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 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 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 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 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 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 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 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); }
1494 Self::AzimuthAngle3DSoundEntry(x) => {
1495 Self::AzimuthAngle3DSound.extend_midi_running(v);
1496 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); }
1505 Self::ElevationAngle3DSoundEntry(x) => {
1506 Self::ElevationAngle3DSound.extend_midi_running(v);
1507 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); }
1516 Self::Gain3DSoundEntry(x) => {
1517 Self::Gain3DSound.extend_midi_running(v);
1518 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); }
1527 Self::DistanceRatio3DSoundEntry(x) => {
1528 Self::DistanceRatio3DSound.extend_midi_running(v);
1529 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); }
1538 Self::MaxiumumDistance3DSoundEntry(x) => {
1539 Self::MaxiumumDistance3DSound.extend_midi_running(v);
1540 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); }
1549 Self::GainAtMaxiumumDistance3DSoundEntry(x) => {
1550 Self::GainAtMaxiumumDistance3DSound.extend_midi_running(v);
1551 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); }
1560 Self::ReferenceDistanceRatio3DSoundEntry(x) => {
1561 Self::ReferenceDistanceRatio3DSound.extend_midi_running(v);
1562 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); }
1571 Self::PanSpreadAngle3DSoundEntry(x) => {
1572 Self::PanSpreadAngle3DSound.extend_midi_running(v);
1573 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); }
1582 Self::RollAngle3DSoundEntry(x) => {
1583 Self::RollAngle3DSound.extend_midi_running(v);
1584 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}