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
14pub 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 let bytes_read = self.reader.read_simple(self.buf.as_mut())?;
44 self.buf_fill = bytes_read;
45 self.buf_used = 0;
46 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); 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 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}