Skip to main content

midi_toolkit/events/
event_variants.rs

1use crate::events::encode_var_length_value;
2use crate::io::MIDIWriteError;
3use crate::sequence::event::Delta;
4use std::io::{Error, ErrorKind, Write};
5
6use super::event::Event;
7use super::{ChannelEvent, KeyEvent, MIDIEvent, MIDINum, PlaybackEvent, SerializeEvent};
8use derive::{MIDIEvent, NewEvent};
9
10fn write_all_len<T: Write>(buf: &mut T, bytes: &[u8]) -> Result<usize, MIDIWriteError> {
11    buf.write_all(bytes)?;
12    Ok(bytes.len())
13}
14
15#[derive(Debug, Clone, Copy, PartialEq)]
16pub struct MIDIColor {
17    pub r: u8,
18    pub g: u8,
19    pub b: u8,
20    pub a: u8,
21}
22
23#[derive(Debug, Clone, PartialEq, Copy)]
24pub enum TextEventKind {
25    TextEvent = 1,
26    CopyrightNotice = 2,
27    TrackName = 3,
28    InstrumentName = 4,
29    Lyric = 5,
30    Marker = 6,
31    CuePoint = 7,
32    ProgramName = 8,
33    DeviceName = 9,
34    Undefined = 10,
35    MetaEvent = 0x7F,
36}
37
38impl TextEventKind {
39    pub fn from_val(val: u8) -> TextEventKind {
40        match val {
41            1 => TextEventKind::TextEvent,
42            2 => TextEventKind::CopyrightNotice,
43            3 => TextEventKind::TrackName,
44            4 => TextEventKind::InstrumentName,
45            5 => TextEventKind::Lyric,
46            6 => TextEventKind::Marker,
47            7 => TextEventKind::CuePoint,
48            8 => TextEventKind::ProgramName,
49            9 => TextEventKind::DeviceName,
50            10 => TextEventKind::Undefined,
51            0x7F => TextEventKind::MetaEvent,
52            _ => TextEventKind::Undefined,
53        }
54    }
55}
56
57#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
58#[playback]
59pub struct NoteOnEvent {
60    #[channel]
61    pub channel: u8,
62    #[key]
63    pub key: u8,
64    pub velocity: u8,
65}
66
67impl SerializeEvent for NoteOnEvent {
68    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
69        let event = [0x90 | self.channel, self.key, self.velocity];
70        write_all_len(buf, &event)
71    }
72}
73
74impl PlaybackEvent for NoteOnEvent {
75    fn as_u32(&self) -> u32 {
76        (0x90 | self.channel as u32) | (self.key as u32) << 8 | (self.velocity as u32) << 16
77    }
78}
79
80#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
81#[playback]
82pub struct NoteOffEvent {
83    #[channel]
84    pub channel: u8,
85    #[key]
86    pub key: u8,
87}
88
89impl SerializeEvent for NoteOffEvent {
90    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
91        let event = [0x80 | self.channel, self.key, 0];
92        write_all_len(buf, &event)
93    }
94}
95
96impl PlaybackEvent for NoteOffEvent {
97    fn as_u32(&self) -> u32 {
98        (0x80 | self.channel as u32) | (self.key as u32) << 8
99    }
100}
101
102#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
103#[playback]
104pub struct PolyphonicKeyPressureEvent {
105    #[channel]
106    pub channel: u8,
107    #[key]
108    pub key: u8,
109    pub velocity: u8,
110}
111
112impl SerializeEvent for PolyphonicKeyPressureEvent {
113    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
114        let event = [0xA0 | self.channel, self.key, self.velocity];
115        write_all_len(buf, &event)
116    }
117}
118
119impl PlaybackEvent for PolyphonicKeyPressureEvent {
120    fn as_u32(&self) -> u32 {
121        (0xA0 | self.channel as u32) | (self.key as u32) << 8 | (self.velocity as u32) << 16
122    }
123}
124
125#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
126#[playback]
127pub struct ControlChangeEvent {
128    #[channel]
129    pub channel: u8,
130    pub controller: u8,
131    pub value: u8,
132}
133
134impl SerializeEvent for ControlChangeEvent {
135    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
136        let event = [0xB0 | self.channel, self.controller, self.value];
137        write_all_len(buf, &event)
138    }
139}
140
141impl PlaybackEvent for ControlChangeEvent {
142    fn as_u32(&self) -> u32 {
143        (0xB0 | self.channel as u32) | (self.controller as u32) << 8 | (self.value as u32) << 16
144    }
145}
146
147#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
148#[playback]
149pub struct ProgramChangeEvent {
150    #[channel]
151    pub channel: u8,
152    pub program: u8,
153}
154
155impl SerializeEvent for ProgramChangeEvent {
156    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
157        let event = [0xC0 | self.channel, self.program];
158        write_all_len(buf, &event)
159    }
160}
161
162impl PlaybackEvent for ProgramChangeEvent {
163    fn as_u32(&self) -> u32 {
164        (0xC0 | self.channel as u32) | (self.program as u32) << 8
165    }
166}
167
168#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
169#[playback]
170pub struct ChannelPressureEvent {
171    #[channel]
172    pub channel: u8,
173    pub pressure: u8,
174}
175
176impl SerializeEvent for ChannelPressureEvent {
177    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
178        let event = [0xD0 | self.channel, self.pressure];
179        write_all_len(buf, &event)
180    }
181}
182
183impl PlaybackEvent for ChannelPressureEvent {
184    fn as_u32(&self) -> u32 {
185        (0xD0 | self.channel as u32) | (self.pressure as u32) << 8
186    }
187}
188
189#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
190#[playback]
191pub struct PitchWheelChangeEvent {
192    #[channel]
193    pub channel: u8,
194    pub pitch: i16,
195}
196
197impl SerializeEvent for PitchWheelChangeEvent {
198    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
199        let value = self.pitch + 8192;
200        let event = [
201            0xE0 | self.channel,
202            (value & 0x7F) as u8,
203            ((value >> 7) & 0x7F) as u8,
204        ];
205        write_all_len(buf, &event)
206    }
207}
208
209impl PlaybackEvent for PitchWheelChangeEvent {
210    fn as_u32(&self) -> u32 {
211        let value = self.pitch + 8192;
212        let val1 = value & 0x7F;
213        let val2 = (value >> 7) & 0x7F;
214        (0xE0 | self.channel as u32) | (val1 as u32) << 8 | (val2 as u32) << 16
215    }
216}
217
218#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
219pub struct SystemExclusiveMessageEvent {
220    pub data: Vec<u8>,
221}
222
223impl SerializeEvent for SystemExclusiveMessageEvent {
224    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
225        let mut vec = Vec::with_capacity(self.data.len() + 5);
226        vec.push(0xF0u8);
227        vec.extend(encode_var_length_value(self.data.len() as u64));
228        vec.extend(self.data.iter().copied());
229        write_all_len(buf, &vec)
230    }
231}
232
233#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
234pub struct UndefinedEvent {
235    pub event: u8,
236}
237
238impl SerializeEvent for UndefinedEvent {
239    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
240        let event = [self.event];
241        write_all_len(buf, &event)
242    }
243}
244
245#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
246pub struct SongPositionPointerEvent {
247    pub position: u16,
248}
249
250impl SerializeEvent for SongPositionPointerEvent {
251    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
252        let event = [
253            0xF2,
254            (self.position & 0x7F) as u8,
255            ((self.position >> 7) & 0x7F) as u8,
256        ];
257        write_all_len(buf, &event)
258    }
259}
260
261#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
262pub struct SongSelectEvent {
263    pub song: u8,
264}
265
266impl SerializeEvent for SongSelectEvent {
267    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
268        let event = [0xF3, self.song];
269        write_all_len(buf, &event)
270    }
271}
272
273#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
274pub struct TuneRequestEvent {}
275
276impl SerializeEvent for TuneRequestEvent {
277    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
278        let event = [0xF6];
279        write_all_len(buf, &event)
280    }
281}
282
283#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
284pub struct EndOfExclusiveEvent {}
285
286impl SerializeEvent for EndOfExclusiveEvent {
287    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
288        let event = [0xF7];
289        write_all_len(buf, &event)
290    }
291}
292
293#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
294pub struct TrackStartEvent {}
295
296impl SerializeEvent for TrackStartEvent {
297    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
298        let event = [0xFF, 0x00, 0x02, 0x00, 0x00];
299        write_all_len(buf, &event)
300    }
301}
302
303#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
304pub struct TextEvent {
305    pub kind: TextEventKind,
306    pub bytes: Vec<u8>,
307}
308
309impl SerializeEvent for TextEvent {
310    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
311        let mut vec = Vec::with_capacity(self.bytes.len() + 2);
312        vec.push(0xFF);
313        vec.push(self.kind as u8);
314        vec.append(&mut encode_var_length_value(self.bytes.len() as u64));
315        for v in self.bytes.iter() {
316            vec.push(*v);
317        }
318        write_all_len(buf, &vec)
319    }
320}
321
322#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
323pub struct UnknownMetaEvent {
324    pub kind: u8,
325    pub bytes: Vec<u8>,
326}
327
328impl SerializeEvent for UnknownMetaEvent {
329    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
330        let mut vec = Vec::with_capacity(self.bytes.len() + 2);
331        vec.push(0xFF);
332        vec.push(self.kind);
333        vec.append(&mut encode_var_length_value(self.bytes.len() as u64));
334        for v in self.bytes.iter() {
335            vec.push(*v);
336        }
337        write_all_len(buf, &vec)
338    }
339}
340
341#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
342pub struct ColorEvent {
343    pub channel: u8,
344    pub col: MIDIColor,
345    pub col2: Option<MIDIColor>,
346}
347
348impl SerializeEvent for ColorEvent {
349    fn serialize_event<T: std::io::Write>(&self, _buf: &mut T) -> Result<usize, MIDIWriteError> {
350        Err(MIDIWriteError::FilesystemError(Error::new(
351            ErrorKind::Unsupported,
352            "ColorEvent serialization is not supported",
353        )))
354    }
355}
356
357#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
358pub struct ChannelPrefixEvent {
359    #[channel]
360    pub channel: u8,
361}
362
363impl SerializeEvent for ChannelPrefixEvent {
364    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
365        let event = [0xFF, 0x20, 0x01, self.channel];
366        write_all_len(buf, &event)
367    }
368}
369
370#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
371pub struct MIDIPortEvent {
372    #[channel]
373    pub channel: u8,
374}
375
376impl SerializeEvent for MIDIPortEvent {
377    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
378        let event = [0xFF, 0x21, 0x01, self.channel];
379        write_all_len(buf, &event)
380    }
381}
382
383#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
384pub struct TempoEvent {
385    pub tempo: u32,
386}
387
388impl SerializeEvent for TempoEvent {
389    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
390        let event = [
391            0xFF,
392            0x51,
393            0x03,
394            ((self.tempo >> 16) & 0xFF) as u8,
395            ((self.tempo >> 8) & 0xFF) as u8,
396            (self.tempo & 0xFF) as u8,
397        ];
398        write_all_len(buf, &event)
399    }
400}
401
402#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
403pub struct SMPTEOffsetEvent {
404    pub hours: u8,
405    pub minutes: u8,
406    pub seconds: u8,
407    pub frames: u8,
408    pub fractional_frames: u8,
409}
410
411impl SerializeEvent for SMPTEOffsetEvent {
412    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
413        let event = [
414            0xFF,
415            0x54,
416            0x05,
417            self.hours,
418            self.minutes,
419            self.seconds,
420            self.frames,
421            self.fractional_frames,
422        ];
423        write_all_len(buf, &event)
424    }
425}
426
427#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
428pub struct TimeSignatureEvent {
429    pub numerator: u8,
430    pub denominator: u8,
431    pub ticks_per_click: u8,
432    pub bb: u8,
433}
434
435impl SerializeEvent for TimeSignatureEvent {
436    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
437        let event = [
438            0xFF,
439            0x58,
440            0x04,
441            self.numerator,
442            self.denominator,
443            self.ticks_per_click,
444            self.bb,
445        ];
446        write_all_len(buf, &event)
447    }
448}
449
450#[derive(Debug, MIDIEvent, Clone, NewEvent, PartialEq)]
451pub struct KeySignatureEvent {
452    pub sf: u8,
453    pub mi: u8,
454}
455
456impl SerializeEvent for KeySignatureEvent {
457    fn serialize_event<T: std::io::Write>(&self, buf: &mut T) -> Result<usize, MIDIWriteError> {
458        let event = [0xFF, 0x59, 0x02, self.sf, self.mi];
459        write_all_len(buf, &event)
460    }
461}
462
463#[cfg(test)]
464mod tests {
465    use super::{
466        ColorEvent, MIDIColor, SerializeEvent, SystemExclusiveMessageEvent, TrackStartEvent,
467    };
468    use crate::io::MIDIWriteError;
469    use std::io::{ErrorKind, Write};
470
471    struct PartialWriter {
472        bytes: Vec<u8>,
473        max_write: usize,
474    }
475
476    impl PartialWriter {
477        fn new(max_write: usize) -> Self {
478            Self {
479                bytes: Vec::new(),
480                max_write,
481            }
482        }
483    }
484
485    impl Write for PartialWriter {
486        fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
487            let written = self.max_write.min(buf.len());
488            self.bytes.extend_from_slice(&buf[..written]);
489            Ok(written)
490        }
491
492        fn flush(&mut self) -> std::io::Result<()> {
493            Ok(())
494        }
495    }
496
497    #[test]
498    fn track_start_serializes_with_two_payload_bytes() {
499        let mut buf = Vec::new();
500        TrackStartEvent {}
501            .serialize_event(&mut buf)
502            .expect("track start should serialize");
503
504        assert_eq!(buf, vec![0xFF, 0x00, 0x02, 0x00, 0x00]);
505    }
506
507    #[test]
508    fn color_event_returns_typed_unsupported_error() {
509        let mut buf = Vec::new();
510        let err = ColorEvent {
511            channel: 0,
512            col: MIDIColor {
513                r: 1,
514                g: 2,
515                b: 3,
516                a: 4,
517            },
518            col2: None,
519        }
520        .serialize_event(&mut buf)
521        .expect_err("color serialization should not panic");
522
523        match err {
524            MIDIWriteError::FilesystemError(err) => assert_eq!(err.kind(), ErrorKind::Unsupported),
525            other => panic!("unexpected write error variant: {:?}", other),
526        }
527    }
528
529    #[test]
530    fn sysex_serializes_as_smf_event_without_implicit_terminator() {
531        let mut buf = Vec::new();
532        SystemExclusiveMessageEvent {
533            data: vec![0x12, 0xF7, 0x34],
534        }
535        .serialize_event(&mut buf)
536        .expect("sysex should serialize");
537
538        assert_eq!(buf, vec![0xF0, 0x03, 0x12, 0xF7, 0x34]);
539    }
540
541    #[test]
542    fn serializers_handle_partial_writes() {
543        let mut buf = PartialWriter::new(1);
544
545        let note = SystemExclusiveMessageEvent {
546            data: vec![0x41, 0x42, 0x43],
547        };
548
549        note.serialize_event(&mut buf)
550            .expect("write_all should handle partial writes");
551
552        assert_eq!(buf.bytes, vec![0xF0, 0x03, 0x41, 0x42, 0x43]);
553    }
554}