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
84pub trait ChannelEvent {
86 fn channel(&self) -> u8;
87 fn channel_mut(&mut self) -> &mut u8;
88}
89
90pub trait KeyEvent: ChannelEvent {
92 fn key(&self) -> u8;
93 fn key_mut(&mut self) -> &mut u8;
94}
95
96pub 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}