nom_midi/parser/event/
midi.rs

1//! Midi events
2
3use crate::{
4    parser::util::be_u7,
5    types::{MidiEvent, MidiEventType},
6};
7use nom::{
8    error::{make_error, ErrorKind},
9    Err, IResult,
10};
11
12pub fn parse_midi_event(i: &[u8]) -> IResult<&[u8], MidiEvent> {
13    use nom::number::streaming::be_u8;
14
15    let (i, code_chan) = be_u8(i)?;
16    let (i, evt_type) = match code_chan >> 4 {
17        0x8 => {
18            let (i, note_code) = be_u7(i)?;
19            let (i, velocity) = be_u7(i)?;
20            (i, MidiEventType::NoteOff(note_code.into(), velocity))
21        }
22        0x9 => {
23            let (i, note_code) = be_u7(i)?;
24            let (i, velocity) = be_u7(i)?;
25            (i, MidiEventType::NoteOn(note_code.into(), velocity))
26        }
27        0xA => {
28            let (i, note_code) = be_u7(i)?;
29            let (i, pressure) = be_u7(i)?;
30            (
31                i,
32                MidiEventType::PolyphonicPressure(note_code.into(), pressure),
33            )
34        }
35        0xB => {
36            let (i, controller) = be_u7(i)?;
37            let (i, value) = be_u7(i)?;
38            (i, MidiEventType::Controller(controller, value))
39        }
40        0xC => {
41            let (i, program) = be_u7(i)?;
42            (i, MidiEventType::ProgramChange(program))
43        }
44        0xD => {
45            let (i, pressure) = be_u7(i)?;
46            (i, MidiEventType::ChannelPressure(pressure))
47        }
48        0xE => {
49            let (i, lsb) = be_u7(i)?;
50            let (i, msb) = be_u7(i)?;
51            (i, MidiEventType::PitchBend(lsb, msb))
52        }
53        _ => return Err(Err::Error(make_error(i, ErrorKind::Digit))),
54    };
55    Ok((
56        i,
57        MidiEvent {
58            channel: code_chan & 0x0F,
59            event: evt_type,
60        },
61    ))
62}