midi_stream_parser/
lib.rs1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(test), no_std)]
3
4#[derive(Debug)]
7pub struct MidiStreamParser<const SYSEX_MAX_LEN: usize> {
8 message: [u8; 3],
10
11 message_length: usize,
13
14 realtime_message: [u8; 1],
16
17 sysex_running: bool,
19
20 sysex_message: [u8; SYSEX_MAX_LEN],
22
23 sysex_message_length: usize,
25}
26
27#[derive(Debug)]
29pub enum ParserError {
30 InvalidStatus,
32
33 SysexOverflow,
35}
36
37impl<const SYSEX_MAX_LEN: usize> Default for MidiStreamParser<SYSEX_MAX_LEN> {
38 fn default() -> Self {
40 Self::new()
41 }
42}
43
44impl<const SYSEX_MAX_LEN: usize> MidiStreamParser<SYSEX_MAX_LEN> {
45 pub fn new() -> Self {
47 Self {
48 message: [0; 3],
49 message_length: 0,
50 realtime_message: [0; 1],
51 sysex_running: false,
52 sysex_message: [0; SYSEX_MAX_LEN],
53 sysex_message_length: 0,
54 }
55 }
56
57 pub fn parse(&mut self, byte: u8) -> Result<Option<&[u8]>, ParserError> {
61 match byte {
62 0x00..=0x7F => {
63 if self.sysex_running {
65 if self.sysex_message_length >= SYSEX_MAX_LEN {
66 return Err(ParserError::SysexOverflow);
67 }
68 self.sysex_message[self.sysex_message_length] = byte;
69 self.sysex_message_length += 1;
70 } else {
71 if self.message_length == 0 {
72 return Err(ParserError::InvalidStatus);
74 }
75 self.message[self.message_length] = byte;
76 self.message_length += 1;
77 if self.message_length == 3 {
78 self.message_length = 1;
80 return Ok(Some(&self.message));
81 } else if matches!(self.message[0] & 0xF0, 0xC0 | 0xD0)
82 || matches!(self.message[0], 0xF1 | 0xF3)
83 {
84 self.message_length = 1;
86 return Ok(Some(&self.message[0..2]));
87 }
88 }
89 }
90 0x80..=0xEF => {
91 self.message[0] = byte;
93 self.message_length = 1;
94 }
95 0xF0..=0xF7 => {
96 match byte {
98 0xF0 => {
99 self.message[0] = 0;
101 self.message_length = 0;
102 self.sysex_running = true;
103 self.sysex_message[0] = byte;
104 self.sysex_message_length = 1;
105 }
106 0xF7 => {
107 self.sysex_running = false;
109 if self.sysex_message_length >= SYSEX_MAX_LEN {
110 return Err(ParserError::SysexOverflow);
111 }
112 self.sysex_message[self.sysex_message_length] = byte;
113 self.sysex_message_length += 1;
114 return Ok(Some(&self.sysex_message[0..self.sysex_message_length]));
115 }
116 _ => {
117 self.message[0] = byte;
118 self.message_length = 1;
119 }
120 }
121 }
122 0xF8..=0xFF => {
123 self.realtime_message[0] = byte;
125 return Ok(Some(&self.realtime_message));
126 }
127 }
128
129 Ok(None)
130 }
131}
132
133#[cfg(test)]
134mod tests;