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}