1use alloc::vec;
2use alloc::vec::Vec;
3use core::convert::TryFrom;
4
5use super::{
6 ChannelModeMsg, ChannelVoiceMsg, ParseError, ReceiverContext, SystemCommonMsg,
7 SystemRealTimeMsg,
8};
9
10#[cfg(feature = "sysex")]
11use super::SystemExclusiveMsg;
12
13#[cfg(feature = "file")]
14use super::Meta;
15
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18#[derive(Debug, Clone, PartialEq)]
19pub enum MidiMsg {
20 ChannelVoice {
22 channel: Channel,
23 msg: ChannelVoiceMsg,
24 },
25 RunningChannelVoice {
33 channel: Channel,
34 msg: ChannelVoiceMsg,
35 },
36 ChannelMode {
38 channel: Channel,
39 msg: ChannelModeMsg,
40 },
41 RunningChannelMode {
43 channel: Channel,
44 msg: ChannelModeMsg,
45 },
46 SystemCommon { msg: SystemCommonMsg },
48 SystemRealTime { msg: SystemRealTimeMsg },
50 #[cfg(feature = "sysex")]
53 SystemExclusive { msg: SystemExclusiveMsg },
54
55 #[cfg(feature = "file")]
57 Meta { msg: Meta },
58
59 #[cfg(feature = "file")]
64 #[cfg_attr(feature = "serde", serde(skip))]
65 Invalid { bytes: Vec<u8>, error: ParseError },
66}
67
68impl MidiMsg {
69 pub fn to_midi(&self) -> Vec<u8> {
71 let mut r: Vec<u8> = vec![];
72 self.extend_midi(&mut r);
73 r
74 }
75
76 pub fn from_midi(m: &[u8]) -> Result<(Self, usize), ParseError> {
80 Self::from_midi_with_context(m, &mut ReceiverContext::default())
81 }
82
83 pub fn from_midi_with_context(
98 m: &[u8],
99 ctx: &mut ReceiverContext,
100 ) -> Result<(Self, usize), ParseError> {
101 Self::_from_midi_with_context(m, ctx, true)
102 }
103
104 pub fn from_midi_with_context_no_extensions(
107 m: &[u8],
108 ctx: &mut ReceiverContext,
109 ) -> Result<(Self, usize), ParseError> {
110 Self::_from_midi_with_context(m, ctx, false)
111 }
112
113 fn _from_midi_with_context(
114 m: &[u8],
115 ctx: &mut ReceiverContext,
116 allow_extensions: bool,
117 ) -> Result<(Self, usize), ParseError> {
118 let (mut midi_msg, mut len) = match m.first() {
119 Some(b) => match b >> 4 {
120 0x8 | 0x9 | 0xA | 0xC | 0xD | 0xE => {
121 let (msg, len) = ChannelVoiceMsg::from_midi(m, ctx)?;
122 let channel = Channel::from_u8(b & 0x0F);
123 let midi_msg = Self::ChannelVoice { channel, msg };
124
125 ctx.previous_channel_message = Some(midi_msg.clone());
126 Ok((midi_msg, len))
127 }
128 0xB => {
129 let channel = Channel::from_u8(b & 0x0F);
131 let (midi_msg, len) = if let Some(b2) = m.get(1) {
132 if b2 >= &120 {
133 let (msg, len) = ChannelModeMsg::from_midi(m)?;
134 (Self::ChannelMode { channel, msg }, len)
135 } else {
136 let (mut msg, len) = ChannelVoiceMsg::from_midi(m, ctx)?;
137
138 if allow_extensions {
139 if let Some(Self::ChannelVoice {
142 channel: prev_channel,
143 msg: prev_msg,
144 }) = ctx.previous_channel_message
145 {
146 if channel == prev_channel
147 && prev_msg.is_extensible()
148 && msg.is_extension()
149 {
150 if let Ok(updated_msg) = prev_msg.maybe_extend(&msg) {
151 msg = updated_msg;
152 }
153 }
154 }
155 }
156 (Self::ChannelVoice { channel, msg }, len)
157 }
158 } else {
159 return Err(ParseError::UnexpectedEnd);
160 };
161
162 ctx.previous_channel_message = Some(midi_msg.clone());
163 Ok((midi_msg, len))
164 }
165 0xF => {
166 if b & 0b00001111 == 0 {
167 #[cfg(feature = "sysex")]
168 {
169 let (msg, len) = SystemExclusiveMsg::from_midi(m, ctx)?;
170 return Ok((Self::SystemExclusive { msg }, len));
171 }
172 #[cfg(not(feature = "sysex"))]
173 return Err(ParseError::SystemExclusiveDisabled);
174 } else if b & 0b00001111 == 0xF && ctx.parsing_smf {
175 #[cfg(feature = "file")]
176 {
177 let (msg, len) = Meta::from_midi(m)?;
178 return Ok((Self::Meta { msg }, len));
179 }
180 #[cfg(not(feature = "file"))]
181 return Err(ParseError::FileDisabled);
182 } else if b & 0b00001000 == 0 {
183 let (msg, len) = SystemCommonMsg::from_midi(m, ctx)?;
184 Ok((Self::SystemCommon { msg }, len))
185 } else {
186 let (msg, len) = SystemRealTimeMsg::from_midi(m)?;
187 Ok((Self::SystemRealTime { msg }, len))
188 }
189 }
190 _ => {
191 if let Some(p) = &ctx.previous_channel_message {
192 match p {
193 Self::ChannelVoice {
194 channel,
195 msg: prev_msg,
196 } => {
197 if m.len() < 2 {
198 return Err(ParseError::UnexpectedEnd);
199 }
200 match prev_msg {
201 ChannelVoiceMsg::ControlChange { .. } => {
203 if m[0] >= 120 {
204 let (msg, len) = ChannelModeMsg::from_midi_running(m)?;
205 return Ok((
206 Self::ChannelMode {
207 channel: *channel,
208 msg,
209 },
210 len,
211 ));
212 }
213 }
214 _ => (),
215 };
216 let (mut msg, len) =
217 ChannelVoiceMsg::from_midi_running(m, prev_msg, ctx)?;
218
219 if allow_extensions {
220 if prev_msg.is_extensible() && msg.is_extension() {
223 if let Ok(updated_msg) = prev_msg.maybe_extend(&msg) {
224 msg = updated_msg;
225 }
226 }
227 }
228 Ok((
229 Self::ChannelVoice {
230 channel: *channel,
231 msg,
232 },
233 len,
234 ))
235 }
236
237 Self::ChannelMode { channel, .. } => {
238 if m.len() < 2 {
239 return Err(ParseError::UnexpectedEnd);
240 }
241 if m[0] >= 120 {
243 let (msg, len) = ChannelModeMsg::from_midi_running(m)?;
244 Ok((
245 Self::ChannelMode {
246 channel: *channel,
247 msg,
248 },
249 len,
250 ))
251 } else {
252 let control = crate::ControlChange::from_midi(m, ctx)?;
253 Ok((
254 Self::ChannelVoice {
255 channel: *channel,
256 msg: ChannelVoiceMsg::ControlChange { control },
257 },
258 2,
259 ))
260 }
261 }
262 _ => Err(ParseError::Invalid(
263 "ReceiverContext::previous_channel_message may only be a ChannelMode or ChannelVoice message.",
264 )),
265 }
266 } else {
267 Err(ParseError::ContextlessRunningStatus)
268 }
269 }
270 },
271 None => Err(ParseError::UnexpectedEnd),
272 }?;
273
274 if allow_extensions {
275 loop {
280 if let Self::ChannelVoice { channel, msg } = midi_msg {
281 if msg.is_extensible() {
282 let mut ctx = ctx.clone();
284 match Self::_from_midi_with_context(&m[len..], &mut ctx, false) {
286 Ok((
287 Self::ChannelVoice {
288 channel: next_channel,
289 msg: next_msg,
290 },
291 next_len,
292 )) => {
293 if channel == next_channel && next_msg.is_extension() {
294 match msg.maybe_extend(&next_msg) {
295 Ok(updated_msg) => {
296 midi_msg = Self::ChannelVoice {
297 channel,
298 msg: updated_msg,
299 };
300 len += next_len;
301 }
302 _ => break,
303 }
304 } else {
305 break;
306 }
307 }
308 _ => break,
309 }
310 } else {
311 break;
312 }
313 } else {
314 break;
315 }
316 }
317 }
318
319 Ok((midi_msg, len))
320 }
321
322 pub fn messages_to_midi(msgs: &[Self]) -> Vec<u8> {
325 let mut r: Vec<u8> = vec![];
326 for m in msgs.iter() {
327 m.extend_midi(&mut r);
328 }
329 r
330 }
331
332 pub fn extend_midi(&self, v: &mut Vec<u8>) {
334 match self {
335 MidiMsg::ChannelVoice { channel, msg } => {
336 let p = v.len();
337 msg.extend_midi(v);
338 v[p] += *channel as u8;
339 match msg {
340 ChannelVoiceMsg::HighResNoteOff { .. }
341 | ChannelVoiceMsg::HighResNoteOn { .. } => {
342 v[p + 3] += *channel as u8;
343 }
344 _ => (),
345 }
346 }
347 MidiMsg::RunningChannelVoice { msg, .. } => msg.extend_midi_running(v),
348 MidiMsg::ChannelMode { channel, msg } => {
349 let p = v.len();
350 msg.extend_midi(v);
351 v[p] += *channel as u8;
352 }
353 MidiMsg::RunningChannelMode { msg, .. } => msg.extend_midi_running(v),
354 MidiMsg::SystemCommon { msg } => msg.extend_midi(v),
355 MidiMsg::SystemRealTime { msg } => msg.extend_midi(v),
356 #[cfg(feature = "sysex")]
357 MidiMsg::SystemExclusive { msg } => msg.extend_midi(v, true),
358 #[cfg(feature = "file")]
359 MidiMsg::Meta { msg } => msg.extend_midi(v),
360 #[cfg(feature = "file")]
361 MidiMsg::Invalid { .. } => {
362 }
364 }
365 }
366
367 pub fn is_channel_voice(&self) -> bool {
369 matches!(
370 self,
371 Self::ChannelVoice { .. } | Self::RunningChannelVoice { .. }
372 )
373 }
374
375 pub fn is_note_on(&self) -> bool {
376 matches!(
377 self,
378 Self::ChannelVoice {
379 msg: ChannelVoiceMsg::NoteOn { .. } | ChannelVoiceMsg::HighResNoteOn { .. },
380 ..
381 } | Self::RunningChannelVoice {
382 msg: ChannelVoiceMsg::NoteOn { .. } | ChannelVoiceMsg::HighResNoteOn { .. },
383 ..
384 }
385 )
386 }
387
388 pub fn is_note_off(&self) -> bool {
389 matches!(
390 self,
391 Self::ChannelVoice {
392 msg: ChannelVoiceMsg::NoteOff { .. } | ChannelVoiceMsg::HighResNoteOff { .. },
393 ..
394 } | Self::RunningChannelVoice {
395 msg: ChannelVoiceMsg::NoteOff { .. } | ChannelVoiceMsg::HighResNoteOff { .. },
396 ..
397 }
398 )
399 }
400
401 pub fn is_note(&self) -> bool {
403 matches!(
404 self,
405 Self::ChannelVoice {
406 msg: ChannelVoiceMsg::NoteOn { .. }
407 | ChannelVoiceMsg::NoteOff { .. }
408 | ChannelVoiceMsg::HighResNoteOn { .. }
409 | ChannelVoiceMsg::HighResNoteOff { .. },
410 ..
411 } | Self::RunningChannelVoice {
412 msg: ChannelVoiceMsg::NoteOn { .. }
413 | ChannelVoiceMsg::NoteOff { .. }
414 | ChannelVoiceMsg::HighResNoteOn { .. }
415 | ChannelVoiceMsg::HighResNoteOff { .. },
416 ..
417 }
418 )
419 }
420
421 pub fn is_cc(&self) -> bool {
423 matches!(
424 self,
425 Self::ChannelVoice {
426 msg: ChannelVoiceMsg::ControlChange { .. },
427 ..
428 } | Self::RunningChannelVoice {
429 msg: ChannelVoiceMsg::ControlChange { .. },
430 ..
431 }
432 )
433 }
434
435 pub fn is_channel_mode(&self) -> bool {
437 matches!(
438 self,
439 Self::ChannelMode { .. } | Self::RunningChannelMode { .. }
440 )
441 }
442
443 pub fn is_system_common(&self) -> bool {
445 matches!(self, Self::SystemCommon { .. })
446 }
447
448 pub fn is_system_real_time(&self) -> bool {
450 matches!(self, Self::SystemRealTime { .. })
451 }
452
453 #[cfg(feature = "sysex")]
454 pub fn is_system_exclusive(&self) -> bool {
456 matches!(self, Self::SystemExclusive { .. })
457 }
458
459 #[cfg(feature = "file")]
460 pub fn is_meta(&self) -> bool {
462 matches!(self, Self::Meta { .. })
463 }
464
465 #[cfg(feature = "file")]
466 pub fn is_invalid(&self) -> bool {
468 matches!(self, Self::Invalid { .. })
469 }
470}
471
472impl From<&MidiMsg> for Vec<u8> {
473 fn from(m: &MidiMsg) -> Vec<u8> {
474 m.to_midi()
475 }
476}
477
478pub fn next_message(m: &[u8]) -> Option<usize> {
485 if m.is_empty() {
486 return None;
487 }
488 let start = if upper_bit_set(m[0]) { 1 } else { 0 };
491
492 (start..m.len()).find(|&i| upper_bit_set(m[i]))
493}
494
495fn upper_bit_set(x: u8) -> bool {
496 x & 0b10000000 != 0
497}
498
499#[cfg(feature = "std")]
500use strum::{EnumIter, EnumString};
501
502#[cfg_attr(feature = "std", derive(EnumIter, EnumString))]
504#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
505#[derive(Debug, Clone, Copy, PartialEq, Eq)]
506#[repr(u8)]
507pub enum Channel {
508 Ch1,
509 Ch2,
510 Ch3,
511 Ch4,
512 Ch5,
513 Ch6,
514 Ch7,
515 Ch8,
516 Ch9,
517 Ch10,
518 Ch11,
519 Ch12,
520 Ch13,
521 Ch14,
522 Ch15,
523 Ch16,
524}
525
526impl core::fmt::Display for Channel {
527 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
528 write!(f, "Ch{}", *self as u8 + 1)
529 }
530}
531
532impl Channel {
533 pub fn from_u8(x: u8) -> Self {
534 match x {
535 0 => Self::Ch1,
536 1 => Self::Ch2,
537 2 => Self::Ch3,
538 3 => Self::Ch4,
539 4 => Self::Ch5,
540 5 => Self::Ch6,
541 6 => Self::Ch7,
542 7 => Self::Ch8,
543 8 => Self::Ch9,
544 9 => Self::Ch10,
545 10 => Self::Ch11,
546 11 => Self::Ch12,
547 12 => Self::Ch13,
548 13 => Self::Ch14,
549 14 => Self::Ch15,
550 _ => Self::Ch16,
551 }
552 }
553}
554
555impl TryFrom<u8> for Channel {
556 type Error = &'static str;
557
558 fn try_from(value: u8) -> Result<Self, Self::Error> {
559 if value > 15 {
560 return Err("Invalid channel value");
561 }
562 Ok(Self::from_u8(value))
563 }
564}
565
566#[cfg(test)]
567mod tests {
568 use super::*;
569 use crate::Channel::*;
570
571 #[test]
572 fn test_ch() {
573 assert_eq!(Ch1, Channel::from_u8(0));
574 assert_eq!(Ch2, Channel::from_u8(1));
575 assert_eq!(Ch16, Channel::from_u8(255));
576 }
577
578 #[test]
579 fn test_ch_try_from() {
580 assert_eq!(Ch1, Channel::try_from(0).unwrap());
581 assert_eq!(Ch2, Channel::try_from(1).unwrap());
582 assert_eq!(Ch16, Channel::try_from(15).unwrap());
583 assert!(Channel::try_from(16).is_err());
584 }
585
586 #[test]
587 fn test_running_status() {
588 let noteon = MidiMsg::ChannelVoice {
589 channel: Channel::Ch1,
590 msg: ChannelVoiceMsg::NoteOn {
591 note: 0x42,
592 velocity: 0x60,
593 },
594 };
595 let running_noteon = MidiMsg::RunningChannelVoice {
596 channel: Channel::Ch1,
597 msg: ChannelVoiceMsg::NoteOn {
598 note: 0x42,
599 velocity: 0x60,
600 },
601 };
602 let reset = MidiMsg::ChannelMode {
603 channel: Channel::Ch1,
604 msg: ChannelModeMsg::ResetAllControllers,
605 };
606 let running_reset = MidiMsg::RunningChannelMode {
607 channel: Channel::Ch1,
608 msg: ChannelModeMsg::ResetAllControllers,
609 };
610 let cc = MidiMsg::ChannelVoice {
611 channel: Channel::Ch1,
612 msg: ChannelVoiceMsg::ControlChange {
613 control: crate::ControlChange::Volume(0x7F),
614 },
615 };
616 let running_cc = MidiMsg::RunningChannelVoice {
617 channel: Channel::Ch1,
618 msg: ChannelVoiceMsg::ControlChange {
619 control: crate::ControlChange::Volume(0x7F),
620 },
621 };
622
623 let mut midi = vec![];
625 noteon.extend_midi(&mut midi);
626 running_noteon.extend_midi(&mut midi);
627 reset.extend_midi(&mut midi);
629 running_reset.extend_midi(&mut midi);
630 cc.extend_midi(&mut midi);
632 running_cc.extend_midi(&mut midi);
633 reset.extend_midi(&mut midi);
635 running_cc.extend_midi(&mut midi);
636 cc.extend_midi(&mut midi);
637 running_reset.extend_midi(&mut midi);
638
639 let mut offset = 0;
641 let mut ctx = ReceiverContext::new().complex_cc();
642 let (msg1, len) = MidiMsg::from_midi_with_context(&midi, &mut ctx).expect("Not an error");
643 offset += len;
644 let (msg2, len) =
645 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
646 offset += len;
647 let (msg3, len) =
648 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
649 offset += len;
650 let (msg4, len) =
651 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
652 offset += len;
653 let (msg5, len) =
654 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
655 offset += len;
656 let (msg6, len) =
657 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
658 offset += len;
659 let (msg7, len) =
660 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
661 offset += len;
662 let (msg8, len) =
663 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
664 offset += len;
665 let (msg9, len) =
666 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
667 offset += len;
668 let (msg10, _) =
669 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
670
671 assert_eq!(msg1, noteon);
673 assert_eq!(msg2, noteon);
674 assert_eq!(msg3, reset);
675 assert_eq!(msg4, reset);
676 assert_eq!(msg5, cc);
677 assert_eq!(msg6, cc);
678 assert_eq!(msg7, reset);
679 assert_eq!(msg8, cc);
680 assert_eq!(msg9, cc);
681 assert_eq!(msg10, reset);
682 }
683
684 #[test]
685 fn test_simple_cc_running_status() {
686 let cc = MidiMsg::ChannelVoice {
687 channel: Channel::Ch1,
688 msg: ChannelVoiceMsg::ControlChange {
689 control: crate::ControlChange::Volume(0x7F),
690 },
691 };
692 let running_cc = MidiMsg::RunningChannelVoice {
693 channel: Channel::Ch1,
694 msg: ChannelVoiceMsg::ControlChange {
695 control: crate::ControlChange::Volume(0x7F),
696 },
697 };
698 let simple_cc_msb = MidiMsg::ChannelVoice {
699 channel: Channel::Ch1,
700 msg: ChannelVoiceMsg::ControlChange {
701 control: crate::ControlChange::CC {
702 control: 7,
703 value: 0,
704 },
705 },
706 };
707 let simple_cc_lsb = MidiMsg::ChannelVoice {
708 channel: Channel::Ch1,
709 msg: ChannelVoiceMsg::ControlChange {
710 control: crate::ControlChange::CC {
711 control: 7 + 32,
712 value: 0x7F,
713 },
714 },
715 };
716
717 let mut midi = vec![];
719 cc.extend_midi(&mut midi);
720 running_cc.extend_midi(&mut midi);
721
722 let mut offset = 0;
724 let mut ctx = ReceiverContext::new();
725 let (msg1, len) = MidiMsg::from_midi_with_context(&midi, &mut ctx).expect("Not an error");
726 offset += len;
727 let (msg2, len) =
728 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
729 offset += len;
730 let (msg3, len) =
731 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
732 offset += len;
733 let (msg4, _) =
734 MidiMsg::from_midi_with_context(&midi[offset..], &mut ctx).expect("Not an error");
735
736 assert_eq!(msg1, simple_cc_msb);
738 assert_eq!(msg2, simple_cc_lsb);
739 assert_eq!(msg3, simple_cc_msb);
740 assert_eq!(msg4, simple_cc_lsb);
741 }
742
743 #[test]
744 fn test_next_message() {
745 let mut midi = vec![];
746 MidiMsg::ChannelVoice {
747 channel: Channel::Ch1,
748 msg: ChannelVoiceMsg::NoteOn {
749 note: 0x42,
750 velocity: 0x60,
751 },
752 }
753 .extend_midi(&mut midi);
754 let first_message_len = midi.len();
755 MidiMsg::ChannelVoice {
756 channel: Channel::Ch1,
757 msg: ChannelVoiceMsg::NoteOn {
758 note: 0x42,
759 velocity: 0x60,
760 },
761 }
762 .extend_midi(&mut midi);
763
764 assert_eq!(next_message(&midi), Some(first_message_len));
765 assert_eq!(next_message(&midi[1..]), Some(first_message_len - 1));
767 assert_eq!(next_message(&midi[first_message_len..]), None);
768 }
769}