bmidi/
reader.rs

1use crate::note::Note;
2
3use crate::types::EventType::*;
4use crate::types::KeyEventType::*;
5use crate::types::*;
6
7use crate::errors::*;
8
9#[derive(Clone, Copy)]
10struct Status {
11    channel: Byte,
12    opcode: Byte,
13}
14
15pub trait MidiRead {
16    fn read(&mut self, output: &mut [u8]) -> Result<(), MidiError>;
17
18    fn read_byte(&mut self) -> Result<u8, MidiError> {
19        let mut res = [0u8];
20        self.read(&mut res)?;
21        Ok(res[0])
22    }
23
24    fn read_short(&mut self) -> Result<u16, MidiError> {
25        let mut res = [0_u8; 2];
26        self.read(&mut res)?;
27        Ok(u16::from(res[0]) << 8 | u16::from(res[1]))
28    }
29
30    fn read_int(&mut self) -> Result<u32, MidiError> {
31        let mut res = [0_u8; 4];
32        self.read(&mut res)?;
33        Ok(
34            (((res[0] as u32) << 8 | (res[1] as u32)) << 8 | (res[2] as u32)) << 8
35                | (res[3] as u32),
36        )
37    }
38
39    fn read_var_len(&mut self) -> Result<u32, MidiError> {
40        let mut res = 0;
41
42        loop {
43            let next_byte = u32::from(self.read_byte()?);
44            res <<= 7;
45            res |= next_byte & 0x7f;
46            if next_byte & 0x80 == 0 {
47                break;
48            }
49        }
50
51        Ok(res)
52    }
53}
54
55impl<T> MidiRead for T
56where
57    T: Iterator<Item = u8>,
58{
59    fn read(&mut self, output: &mut [u8]) -> Result<(), MidiError> {
60        for field in output.iter_mut() {
61            match self.next() {
62                Some(value) => *field = value,
63                None => return Err(MidiError::EndOfStream),
64            }
65        }
66
67        Ok(())
68    }
69
70    fn read_byte(&mut self) -> Result<u8, MidiError> {
71        match self.next() {
72            Some(value) => Ok(value),
73            None => Err(MidiError::EndOfStream),
74        }
75    }
76}
77
78/* Disabled until inverse trait bounds are supported
79 * Needs: use std::io::Read;
80
81impl<T: Read + !Iterator<Item=u8>> MidiRead for T {
82    fn read(&mut self, output: &mut [u8]) -> Result<(), MidiError> {
83        match Read::read(self, output).ok() {
84            Some(len) if len == output.len() => Ok(()),
85            _ => Err(MidiError::EndOfStream)
86        }
87    }
88}
89
90*/
91
92pub struct MidiReader<I: MidiRead> {
93    reader: I,
94    running_status: Status,
95}
96
97impl<I: MidiRead> MidiReader<I> {
98    pub fn new(reader: I) -> MidiReader<I> {
99        MidiReader {
100            reader,
101            running_status: Status {
102                channel: 0,
103                opcode: 0,
104            },
105        }
106    }
107
108    fn read_byte(&mut self) -> u8 {
109        self.reader.read_byte().unwrap()
110    }
111
112    pub fn read_int(&mut self) -> u32 {
113        self.reader.read_int().unwrap()
114    }
115
116    pub fn read_short(&mut self) -> u16 {
117        self.reader.read_short().unwrap()
118    }
119
120    pub fn read_bytes(&mut self, length: usize) -> Vec<u8> {
121        let mut res = vec![0u8; length];
122        self.reader.read(&mut res).unwrap();
123        res
124    }
125
126    pub fn read_string(&mut self, length: usize) -> String {
127        String::from_utf8(self.read_bytes(length)).unwrap()
128    }
129}
130
131impl<I: MidiRead> Iterator for MidiReader<I> {
132    // type Item = Result<Event, MidiError>;
133    type Item = Event;
134
135    fn next(&mut self) -> Option<Event> /* Option<Result<Event, MidiError>>*/ {
136        // TODO: Break cleanly if self.reader is exhausted
137        let ticks = self.reader.read_var_len().unwrap();
138
139        let mut first_byte = self.read_byte();
140
141        if (first_byte & 1 << 7) != 0 {
142            let status_byte = first_byte;
143            first_byte = self.read_byte();
144            self.running_status = Status {
145                channel: status_byte & 0xf,
146                opcode: (status_byte & 0xf0) >> 4,
147            };
148        }
149
150        let status = self.running_status;
151
152        let event_type = match status.opcode {
153            0x8 | 0x9 | 0xa => {
154                let note = Note::new(first_byte);
155                let velocity = self.read_byte();
156
157                let typ = if status.opcode == 0x8 || (status.opcode == 0x9 && velocity == 0) {
158                    Release
159                } else if status.opcode == 0x9 {
160                    Press
161                } else {
162                    Aftertouch
163                };
164
165                Key {
166                    typ,
167                    note,
168                    velocity,
169                }
170            }
171            0xb => ControlChange {
172                controller: first_byte,
173                value: self.read_byte(),
174            },
175            0xc => PatchChange {
176                program: first_byte,
177            },
178            0xd => ChannelAftertouch {
179                channel: first_byte,
180            },
181            0xe => PitchWheelChange {
182                value: ((first_byte as u16) << 7) | self.read_byte() as u16,
183            },
184            0xf => {
185                if status.channel == 0xf {
186                    let typ = first_byte;
187
188                    if typ == 0x2f {
189                        // End-of-track
190                        let null_byte = self.read_byte();
191                        assert!(null_byte == 0u8);
192                        return None;
193                    }
194
195                    let length = self.reader.read_var_len().unwrap() as usize;
196                    let data = self.read_bytes(length);
197
198                    Meta { typ, data }
199                } else {
200                    panic!("Nope")
201                }
202            }
203            _ => unreachable!("Invalid opcode"),
204        };
205
206        let event = Event {
207            delay: ticks,
208            channel: status.channel,
209            typ: event_type,
210        };
211
212        Some(event)
213    }
214}