midi_codec/
de.rs

1use core::{fmt::Debug, time::Duration};
2
3use crate::{
4    error::DecodeError,
5    io::ReadSimple,
6    message::{ChannelVoiceMessage, Message, RealTimeMessage, SystemCommonMessage},
7    status::{ChannelStatus, ChannelVoiceStatus, RequiredDataBytes, Status, SystemCommonStatus},
8};
9
10use self::builder::DecoderBuilder;
11
12pub mod builder;
13
14/// A decoder state machine.
15pub struct Decoder<R, B> {
16    decoder_buf: DecoderBuf<R, B>,
17
18    running_status: Option<ChannelVoiceStatus>,
19    partial_message: Option<PartialMessage>,
20}
21
22struct DecoderBuf<R, B> {
23    reader: R,
24    buf: B,
25
26    buf_fill: usize,
27    buf_used: usize,
28}
29
30impl Decoder<(), ()> {
31    pub fn builder() -> DecoderBuilder {
32        DecoderBuilder::default()
33    }
34}
35
36impl<R, B> DecoderBuf<R, B>
37where
38    R: ReadSimple,
39    B: AsMut<[u8]>,
40{
41    fn refill_buf(&mut self) -> Result<(), R::Error> {
42        // tracing::trace!("refill");
43        let bytes_read = self.reader.read_simple(self.buf.as_mut())?;
44        self.buf_fill = bytes_read;
45        self.buf_used = 0;
46        // tracing::trace!("refilled {bytes_read} bytes");
47        Ok(())
48    }
49
50    fn peek_byte(&mut self) -> Result<u8, R::Error> {
51        let mut should_wait = false;
52        while self.buf_used >= self.buf_fill {
53            #[cfg(feature = "std")]
54            if should_wait {
55                std::thread::sleep(Duration::from_millis(1));
56            }
57
58            self.refill_buf()?;
59            should_wait = true;
60        }
61
62        tracing::trace!("peeked {}", self.buf_used);
63
64        Ok(self.buf.as_mut()[self.buf_used])
65    }
66
67    fn skip_byte(&mut self) {
68        tracing::trace!("skipped {}", self.buf_used);
69        self.buf_used += 1;
70    }
71
72    fn read_byte(&mut self) -> Result<u8, R::Error> {
73        let byte = self.peek_byte()?;
74        self.skip_byte();
75
76        Ok(byte)
77    }
78
79    fn read_data_byte(&mut self) -> Result<Result<u8, RealTimeMessage>, DecodeError<R::Error>> {
80        let byte = self.read_byte()?;
81        match parse_byte(byte) {
82            ByteType::Data(d) => Ok(Ok(d)),
83            ByteType::Status(_status) => return Err(DecodeError::UnexpectedStatus(byte)),
84            ByteType::RealTimeStatus(real_time) => return Ok(Err(real_time)),
85        }
86    }
87
88    fn flush(&mut self) -> Result<(), R::Error> {
89        self.buf_fill = 0;
90        self.buf_used = 0;
91
92        loop {
93            let size = self.reader.read_simple(self.buf.as_mut())?;
94
95            if size == 0 {
96                break;
97            }
98        }
99
100        Ok(())
101    }
102}
103
104impl<R, B> Decoder<R, B>
105where
106    R: ReadSimple,
107    B: AsMut<[u8]>,
108{
109    fn new(reader: R, buf: B) -> Self {
110        Self {
111            decoder_buf: DecoderBuf {
112                reader,
113                buf,
114
115                buf_fill: 0,
116                buf_used: 0,
117            },
118
119            running_status: None,
120            partial_message: None,
121        }
122    }
123
124    pub fn next_message(&mut self) -> Result<Message, DecodeError<R::Error>> {
125        tracing::trace!("read message");
126        let partial_message = if let Some(ref mut partial_message) = self.partial_message {
127            partial_message
128        } else {
129            let mut data0 = None;
130
131            let status = match parse_byte(self.decoder_buf.read_byte()?) {
132                ByteType::Data(data) => {
133                    if let Some(running_status) = self.running_status {
134                        data0 = Some(data);
135                        Status::ChannelVoice(running_status)
136                    } else {
137                        return Err(DecodeError::ExtraneousData(data));
138                    }
139                }
140                ByteType::Status(status) => status,
141                ByteType::RealTimeStatus(real_time) => {
142                    if real_time == RealTimeMessage::SystemReset {
143                        self.running_status = None;
144                    }
145                    return Ok(Message::RealTime(real_time));
146                }
147            };
148
149            let required_data_bytes = status.required_data_bytes();
150
151            if required_data_bytes == RequiredDataBytes::D0 {
152                return Ok(construct_message(status, [0, 0]));
153            }
154
155            self.partial_message
156                .insert(PartialMessage { status, data0 })
157        };
158        let required_data_bytes = partial_message.status.required_data_bytes();
159
160        let next_data = match self.decoder_buf.read_data_byte()? {
161            Ok(d) => d,
162            Err(real_time) => {
163                if real_time == RealTimeMessage::SystemReset {
164                    self.running_status = None;
165                }
166                return Ok(Message::RealTime(real_time));
167            }
168        };
169
170        if required_data_bytes == RequiredDataBytes::D1 {
171            let status = partial_message.status;
172            self.partial_message = None;
173
174            return Ok(construct_message(status, [next_data, 0]));
175        } else {
176            let (data0, data1) = match partial_message.data0 {
177                Some(data0) => (data0, next_data),
178                None => {
179                    let data0 = next_data;
180                    partial_message.data0 = Some(data0); // In case we return a realtime message below
181
182                    let data1 = match self.decoder_buf.read_data_byte()? {
183                        Ok(d) => d,
184                        Err(real_time) => {
185                            if real_time == RealTimeMessage::SystemReset {
186                                self.running_status = None;
187                            }
188                            return Ok(Message::RealTime(real_time));
189                        }
190                    };
191
192                    (data0, data1)
193                }
194            };
195
196            let status = partial_message.status;
197            self.partial_message = None;
198
199            return Ok(construct_message(status, [data0, data1]));
200        }
201    }
202
203    pub fn read_sysex(&mut self) -> SysexReader<'_, R, B> {
204        tracing::trace!("read sysex");
205        SysexReader { decoder: self }
206    }
207
208    pub fn flush(&mut self) -> Result<(), R::Error> {
209        tracing::trace!("flush");
210        self.decoder_buf.flush()
211    }
212}
213
214pub struct SysexReader<'a, R, B> {
215    decoder: &'a mut Decoder<R, B>,
216}
217
218impl<'a, R, B> Iterator for SysexReader<'a, R, B>
219where
220    R: ReadSimple,
221    B: AsMut<[u8]>,
222{
223    type Item = Result<u8, R::Error>;
224
225    fn next(&mut self) -> Option<Self::Item> {
226        let byte = match self.decoder.decoder_buf.peek_byte() {
227            Ok(byte) => byte,
228            Err(e) => return Some(Err(e)),
229        };
230
231        if is_data_byte(byte) {
232            tracing::trace!("returning sysex byte");
233            self.decoder.decoder_buf.skip_byte();
234            Some(Ok(byte))
235        } else {
236            None
237        }
238    }
239}
240
241fn is_data_byte(byte: u8) -> bool {
242    byte & 0b1000_0000 == 0
243}
244
245fn parse_byte(byte: u8) -> ByteType {
246    if is_data_byte(byte) {
247        ByteType::Data(byte)
248    } else if byte & 0b1111_1000 == 0b1111_1000 {
249        let index = byte & 0b0111;
250
251        let real_time = match index {
252            0 => RealTimeMessage::TimingClock,
253            1 => RealTimeMessage::Undefined1,
254            2 => RealTimeMessage::Start,
255            3 => RealTimeMessage::Continue,
256            4 => RealTimeMessage::Stop,
257            5 => RealTimeMessage::Undefined2,
258            6 => RealTimeMessage::ActiveSensing,
259            7 => RealTimeMessage::SystemReset,
260            _ => unreachable!(),
261        };
262
263        ByteType::RealTimeStatus(real_time)
264    } else {
265        let status_upper = (byte & 0b0111_0000) >> 4;
266        let status_lower = byte & 0b1111;
267
268        let status = if status_upper == 7 {
269            // System Messages
270            // status_lower > 7 is handled above in the real time status block
271
272            if status_lower == 0 {
273                Status::SystemExclusive
274            } else {
275                let common = match status_lower {
276                    1 => SystemCommonStatus::MTCQuarterFrame,
277                    2 => SystemCommonStatus::SongPositionPointer,
278                    3 => SystemCommonStatus::SongSelect,
279                    4 => SystemCommonStatus::Undefined1,
280                    5 => SystemCommonStatus::Undefined2,
281                    6 => SystemCommonStatus::TuneRequest,
282                    7 => SystemCommonStatus::EOX,
283                    _ => unreachable!(),
284                };
285
286                Status::SystemCommon(common)
287            }
288        } else {
289            let channel_voice = match status_upper {
290                0 => ChannelStatus::NoteOff,
291                1 => ChannelStatus::NoteOn,
292                2 => ChannelStatus::PolyphonicPressure,
293                3 => ChannelStatus::ControlChange,
294                4 => ChannelStatus::ProgramChange,
295                5 => ChannelStatus::ChannelPressure,
296                6 => ChannelStatus::PitchBend,
297                _ => unreachable!(),
298            };
299
300            Status::ChannelVoice(ChannelVoiceStatus {
301                status: channel_voice,
302                channel: status_lower,
303            })
304        };
305
306        ByteType::Status(status)
307    }
308}
309
310fn construct_message(status: Status, data: [u8; 2]) -> Message {
311    match status {
312        Status::ChannelVoice(ChannelVoiceStatus { status, channel }) => {
313            let message = match status {
314                ChannelStatus::NoteOff => ChannelVoiceMessage::NoteOff {
315                    note: data[0],
316                    velocity: data[1],
317                },
318                ChannelStatus::NoteOn => ChannelVoiceMessage::NoteOn {
319                    note: data[0],
320                    velocity: data[1],
321                },
322                ChannelStatus::PolyphonicPressure => ChannelVoiceMessage::PolyphonicPressure {
323                    note: data[0],
324                    pressure: data[1],
325                },
326                ChannelStatus::ControlChange => ChannelVoiceMessage::ControlChange {
327                    control: data[0],
328                    value: data[1],
329                },
330                ChannelStatus::ProgramChange => {
331                    ChannelVoiceMessage::ProgramChange { program: data[0] }
332                }
333                ChannelStatus::ChannelPressure => {
334                    ChannelVoiceMessage::ChannelPressure { pressure: data[0] }
335                }
336                ChannelStatus::PitchBend => {
337                    let lsb = data[0];
338                    let msb = data[1];
339
340                    let pitch_bend = (lsb as u16) | ((msb as u16) << 7);
341
342                    ChannelVoiceMessage::PitchBend { pitch_bend }
343                }
344            };
345
346            Message::ChannelVoice { channel, message }
347        }
348        Status::SystemCommon(system_common) => {
349            let message = match system_common {
350                SystemCommonStatus::MTCQuarterFrame => {
351                    SystemCommonMessage::MTCQuarterFrame { data: data[0] }
352                }
353                SystemCommonStatus::SongPositionPointer => {
354                    SystemCommonMessage::SongPositionPointer {
355                        low: data[0],
356                        high: data[1],
357                    }
358                }
359                SystemCommonStatus::SongSelect => SystemCommonMessage::SongSelect { song: data[0] },
360                SystemCommonStatus::Undefined1 => SystemCommonMessage::Undefined1,
361                SystemCommonStatus::Undefined2 => SystemCommonMessage::Undefined2,
362                SystemCommonStatus::TuneRequest => SystemCommonMessage::TuneRequest,
363                SystemCommonStatus::EOX => SystemCommonMessage::EOX,
364            };
365
366            Message::SystemCommon(message)
367        }
368        Status::SystemExclusive => Message::SystemExclusive,
369    }
370}
371
372struct PartialMessage {
373    status: Status,
374    data0: Option<u8>,
375}
376
377#[derive(Debug, Clone, Copy)]
378enum ByteType {
379    Data(u8),
380    Status(Status),
381    RealTimeStatus(RealTimeMessage),
382}