Skip to main content

midi_toolkit/
events.rs

1use std::io::Write;
2
3use crate::{io::MIDIWriteError, num::MIDINum};
4pub use event::Event;
5pub use event_variants::*;
6
7mod event;
8
9mod event_variants;
10
11pub fn encode_var_length_value(mut val: u64) -> Vec<u8> {
12    let mut vec = Vec::new();
13    let mut added = 0x00u8;
14    loop {
15        let v = (val & 0x7F) as u8 | added;
16        vec.push(v);
17        val >>= 7;
18        added = 0x80;
19        if val == 0 {
20            break;
21        }
22    }
23    vec.reverse();
24    vec
25}
26
27pub trait SerializeEvent {
28    fn serialize_event<T: Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError>;
29}
30
31pub trait SerializeEventWithDelta: SerializeEvent {
32    fn serialize_delta<T: Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError>;
33    fn serialize_event_with_delta<T: Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
34        Ok(self.serialize_delta(buf)? + self.serialize_event(buf)?)
35    }
36}
37
38pub trait MIDIEvent: SerializeEvent + std::fmt::Debug {
39    fn key(&self) -> Option<u8>;
40    fn key_mut(&mut self) -> Option<&mut u8>;
41
42    fn channel(&self) -> Option<u8>;
43    fn channel_mut(&mut self) -> Option<&mut u8>;
44
45    fn as_u32(&self) -> Option<u32>;
46}
47
48pub trait BatchTempo: Sized {
49    fn inner_tempo(&self) -> Option<u32>;
50    fn without_tempo(self) -> Option<Self>;
51}
52
53pub trait MIDIEventEnum: MIDIEvent {
54    fn as_event(&self) -> &Event;
55    fn as_event_mut(&mut self) -> &mut Event;
56}
57
58pub trait MIDIDelta<D: MIDINum> {
59    fn delta(&self) -> D;
60    fn delta_mut(&mut self) -> &mut D;
61
62    #[inline(always)]
63    fn set_delta(&mut self, delta: D) {
64        *self.delta_mut() = delta;
65    }
66}
67
68impl MIDIEventEnum for Event {
69    fn as_event(&self) -> &Event {
70        self
71    }
72
73    fn as_event_mut(&mut self) -> &mut Event {
74        self
75    }
76}
77
78pub trait CastEventDelta<DT: MIDINum> {
79    type Output;
80
81    fn cast_delta(self) -> Self::Output;
82}
83
84/// A trait that describes an event that is always connected to a channel
85pub trait ChannelEvent {
86    fn channel(&self) -> u8;
87    fn channel_mut(&mut self) -> &mut u8;
88}
89
90/// A trait that describes an event that is always connected to a key
91pub trait KeyEvent: ChannelEvent {
92    fn key(&self) -> u8;
93    fn key_mut(&mut self) -> &mut u8;
94}
95
96/// A trait that describes an event that is always serializable to u32 for playback
97pub trait PlaybackEvent: ChannelEvent {
98    fn as_u32(&self) -> u32;
99}
100
101#[cfg(test)]
102mod tests {
103    use crate::{
104        events::{Event, MIDIEvent},
105        io::FullRamTrackReader,
106        sequence::event::Delta,
107    };
108
109    fn make_example_playback_events() -> Vec<Vec<u8>> {
110        vec![
111            vec![0x82, 0x40, 0x00],
112            vec![0x94, 0x40, 0x20],
113            vec![0xA3, 0x40, 0x20],
114            vec![0xA3, 0x40, 0x20],
115            vec![0xBF, 0x32, 0x12],
116            vec![0xC0, 0x14],
117            vec![0xD5, 0x7F],
118            vec![0xE7, 0x23, 0x68],
119        ]
120    }
121
122    fn parse_from_vec(mut vec: Vec<u8>) -> Delta<u64, Event> {
123        vec.insert(0, 64);
124        let reader = FullRamTrackReader::new_from_vec(None, vec);
125        let mut parser = crate::io::TrackParser::new(reader);
126        parser.next().unwrap().unwrap()
127    }
128
129    #[test]
130    fn end_to_end_parse_serialize() {
131        let events = make_example_playback_events();
132        for event_bytes in events.iter() {
133            let event = parse_from_vec(event_bytes.clone());
134            let serialized = event.as_u32().unwrap();
135            let mut compressed: u32 = 0x00;
136            let mut offset: u32 = 0;
137            for v in event_bytes.iter() {
138                compressed |= (*v as u32) << offset;
139                offset += 8;
140            }
141            assert_eq!(serialized, compressed);
142        }
143    }
144}