midi_toolkit/io/
track_parser.rs1use crate::{events::*, sequence::event::Delta};
2
3use super::{errors::MIDIParseError, readers::TrackReader};
4
5pub struct TrackParser<T: TrackReader> {
6 reader: T,
7 pushback: i16,
8 prev_command: u8,
9 errored: bool,
10}
11
12pub struct ParserCheckpoint {
13 pushback: i16,
14 prev_command: u8,
15 reader_pos: u64,
16 ended: bool,
17}
18
19impl ParserCheckpoint {
20 pub fn reader_pos(&self) -> u64 {
21 self.reader_pos
22 }
23}
24
25impl<T: TrackReader> TrackParser<T> {
26 pub fn from_checkpoint(reader: T, checkpoint: ParserCheckpoint) -> Self {
27 assert_eq!(
28 checkpoint.reader_pos,
29 reader.pos(),
30 "Checkpoint reader pos does not match reader pos"
31 );
32
33 Self {
34 reader,
35 pushback: checkpoint.pushback,
36 prev_command: checkpoint.prev_command,
37 errored: checkpoint.ended,
38 }
39 }
40
41 pub fn new(reader: T) -> Self {
42 Self {
43 reader,
44 pushback: -1,
45 prev_command: 0,
46 errored: false,
47 }
48 }
49
50 fn read(&mut self) -> Result<u8, MIDIParseError> {
51 if self.pushback != -1 {
52 let p: u8 = self.pushback as u8;
53 self.pushback = -1;
54 return Ok(p);
55 }
56 self.reader.read()
57 }
58
59 fn read_fast(&mut self) -> Result<u8, MIDIParseError> {
60 self.reader.read()
61 }
62
63 fn read_var_length(&mut self) -> Result<u64, MIDIParseError> {
64 let mut n: u64 = 0;
65 loop {
66 let byte = self.read()?;
67 n = (n << 7) | (byte & 0x7F) as u64;
68 if (byte & 0x80) == 0 {
69 break;
70 }
71 }
72 Ok(n)
73 }
74
75 fn try_parse_next_event(&mut self) -> Result<Option<Delta<u64, Event>>, MIDIParseError> {
76 macro_rules! ret {
77 ($val:expr) => {
78 Ok(Some($val))
79 };
80 }
81
82 macro_rules! assert_len {
83 ($size:expr) => {
84 if self.read_fast()? != $size {
85 return Err(MIDIParseError::CorruptEvent {
86 track_number: self.reader.track_number(),
87 position: self.reader.pos(),
88 });
89 }
90 };
91 }
92
93 let delta = self.read_var_length()?;
94 let mut command = self.read()?;
95 if command < 0x80 {
96 self.pushback = command as i16;
97 command = self.prev_command;
98 }
99 self.prev_command = command;
100 let comm = command & 0xF0;
101 match comm {
102 0x80 => {
103 let channel = command & 0x0F;
104 let key = self.read()?;
105 let _vel = self.read_fast()?;
106 ret!(Event::new_delta_note_off_event(delta, channel, key))
107 }
108 0x90 => {
109 let channel = command & 0x0F;
110 let key = self.read()?;
111 let vel = self.read_fast()?;
112 if vel == 0 {
113 ret!(Event::new_delta_note_off_event(delta, channel, key))
114 } else {
115 ret!(Event::new_delta_note_on_event(delta, channel, key, vel))
116 }
117 }
118 0xA0 => {
119 let channel = command & 0x0F;
120 let key = self.read()?;
121 let vel = self.read_fast()?;
122 ret!(Event::new_delta_polyphonic_key_pressure_event(
123 delta, channel, key, vel
124 ))
125 }
126 0xB0 => {
127 let channel = command & 0x0F;
128 let controller = self.read()?;
129 let value = self.read_fast()?;
130 ret!(Event::new_delta_control_change_event(
131 delta, channel, controller, value
132 ))
133 }
134 0xC0 => {
135 let channel = command & 0x0F;
136 let program = self.read()?;
137 ret!(Event::new_delta_program_change_event(
138 delta, channel, program
139 ))
140 }
141 0xD0 => {
142 let channel = command & 0x0F;
143 let pressure = self.read()?;
144 ret!(Event::new_delta_channel_pressure_event(
145 delta, channel, pressure
146 ))
147 }
148 0xE0 => {
149 let channel = command & 0x0F;
150 let var1 = self.read()?;
151 let var2 = self.read_fast()?;
152 ret!(Event::new_delta_pitch_wheel_change_event(
153 delta,
154 channel,
155 (((var2 as i16) << 7) | var1 as i16) - 8192
156 ))
157 }
158 _ => match command {
159 0xF0 => {
160 let size = self.read_var_length()?;
161 let mut data = Vec::new();
162 for _ in 0..size {
163 data.push(self.read_fast()?);
164 }
165 data.shrink_to_fit();
166 ret!(Event::new_delta_system_exclusive_message_event(delta, data))
167 }
168 0xF2 => {
169 let var1 = self.read()?;
170 let var2 = self.read_fast()?;
171 ret!(Event::new_delta_song_position_pointer_event(
172 delta,
173 ((var2 as u16) << 7) | var1 as u16
174 ))
175 }
176 0xF3 => {
177 let pos = self.read()?;
178 ret!(Event::new_delta_song_select_event(delta, pos))
179 }
180 0xF6 => {
181 ret!(Event::new_delta_tune_request_event(delta))
182 }
183 0xF7 => {
184 ret!(Event::new_delta_end_of_exclusive_event(delta))
185 }
186 0xF8 => {
187 ret!(Event::new_delta_end_of_exclusive_event(delta))
188 }
189 0xFF => {
190 let command = self.read()?;
191 match command {
192 0x00 => {
193 assert_len!(2);
194 ret!(Event::new_delta_track_start_event(delta))
195 }
196 0x01..=0x0A | 0xF7 => {
197 let size = self.read_var_length()?;
198 let mut data = Vec::new();
199 for _ in 0..size {
200 data.push(self.read_fast()?);
201 }
202 data.shrink_to_fit();
203
204 ret!(Event::new_delta_text_event(
205 delta,
206 TextEventKind::from_val(command),
207 data
208 ))
209 }
210 0x20 => {
211 assert_len!(1);
212 let prefix = self.read_fast()?;
213 ret!(Event::new_delta_channel_prefix_event(delta, prefix))
214 }
215 0x21 => {
216 assert_len!(1);
217 let port = self.read_fast()?;
218 ret!(Event::new_delta_midi_port_event(delta, port))
219 }
220 0x2F => {
221 assert_len!(0);
222 Ok(None)
224 }
225 0x51 => {
226 assert_len!(3);
227 let mut tempo: u32 = 0;
228 for _ in 0..3 {
229 tempo = (tempo << 8) | self.read_fast()? as u32;
230 }
231 ret!(Event::new_delta_tempo_event(delta, tempo))
232 }
233 0x54 => {
234 assert_len!(5);
235 let hr = self.read_fast()?;
236 let mn = self.read_fast()?;
237 let se = self.read_fast()?;
238 let fr = self.read_fast()?;
239 let ff = self.read_fast()?;
240 ret!(Event::new_delta_smpte_offset_event(
241 delta, hr, mn, se, fr, ff
242 ))
243 }
244 0x58 => {
245 assert_len!(4);
246 let nn = self.read_fast()?;
247 let dd = self.read_fast()?;
248 let cc = self.read_fast()?;
249 let bb = self.read_fast()?;
250 ret!(Event::new_delta_time_signature_event(delta, nn, dd, cc, bb))
251 }
252 0x59 => {
253 assert_len!(2);
254 let sf = self.read_fast()?;
255 let mi = self.read_fast()?;
256 ret!(Event::new_delta_key_signature_event(delta, sf, mi))
257 }
258 _ => {
259 let size = self.read_var_length()?;
260 let mut data = Vec::new();
261 for _ in 0..size {
262 data.push(self.read_fast()?);
263 }
264 data.shrink_to_fit();
265
266 ret!(Event::new_delta_unknown_meta_event(delta, command, data))
267 }
268 }
269 }
270 _ => ret!(Event::new_delta_undefined_event(delta, command)),
271 },
272 }
273 }
274}
275
276impl<T: TrackReader> Iterator for TrackParser<T> {
277 type Item = Result<Delta<u64, Event>, MIDIParseError>;
278
279 fn next(&mut self) -> Option<Self::Item> {
280 loop {
281 if self.errored || self.reader.is_at_end() {
282 return None;
283 }
284
285 let next_event = self.try_parse_next_event();
286 match next_event {
287 Ok(Some(event)) => return Some(Ok(event)),
288 Ok(None) => {
289 continue;
292 }
293 Err(e) => {
294 self.errored = true;
295 return Some(Err(e));
296 }
297 }
298 }
299 }
300}