1use std::fs::File;
2use std::io::prelude::*;
3use std::cmp::{max, min};
4use std::collections::{HashMap, HashSet};
5
6pub mod tests;
7pub mod controller;
8
9use controller::Controller;
10
11#[derive(Debug)]
12pub enum ApresError {
13 InvalidMIDIFile(String),
14 InvalidBytes(Vec<u8>),
15 UnknownMetaEvent(Vec<u8>),
16 EventNotFound(u64),
17 IllegibleString(Vec<u8>),
18 PathNotFound(String),
19 PipeBroken,
20 Killed
21}
22
23
24#[derive(Clone, Debug, PartialEq)]
25pub enum MIDIEvent {
26 SequenceNumber(u16),
27 Text(String),
28 CopyRightNotice(String),
29 TrackName(String),
30 InstrumentName(String),
31 Lyric(String),
32 Marker(String),
33 CuePoint(String),
34 ChannelPrefix(u8),
35 SetTempo(u32),
37 SMPTEOffset(u8, u8, u8, u8, u8),
38 TimeSignature(u8, u8, u8, u8),
39 KeySignature(String),
40 SequencerSpecific(Vec<u8>),
41
42 NoteOn(u8, u8, u8),
43 NoteOff(u8, u8, u8),
44 AfterTouch(u8, u8, u8),
45
46 BankSelect(u8, u8),
47 BankSelectLSB(u8, u8),
48 ModulationWheel(u8, u8),
49 ModulationWheelLSB(u8, u8),
50 BreathController(u8, u8),
51 BreathControllerLSB(u8, u8),
52 FootPedal(u8, u8),
53 FootPedalLSB(u8, u8),
54 PortamentoTime(u8, u8),
55 PortamentoTimeLSB(u8, u8),
56 DataEntry(u8, u8),
57 DataEntryLSB(u8, u8),
58 Volume(u8, u8),
59 VolumeLSB(u8, u8),
60 Balance(u8, u8),
61 BalanceLSB(u8, u8),
62 Pan(u8, u8),
63 PanLSB(u8, u8),
64 Expression(u8, u8),
65 ExpressionLSB(u8, u8),
66 EffectControl1(u8, u8),
67 EffectControl1LSB(u8, u8),
68 EffectControl2(u8, u8),
69 EffectControl2LSB(u8, u8),
70 GeneralPurpose1(u8, u8),
71 GeneralPurpose1LSB(u8, u8),
72 GeneralPurpose2(u8, u8),
73 GeneralPurpose2LSB(u8, u8),
74 GeneralPurpose3(u8, u8),
75 GeneralPurpose3LSB(u8, u8),
76 GeneralPurpose4(u8, u8),
77 GeneralPurpose4LSB(u8, u8),
78 HoldPedal(u8, u8),
79 Portamento(u8, u8),
80 Sustenuto(u8, u8),
81 SoftPedal(u8, u8),
82 Legato(u8, u8),
83 Hold2Pedal(u8, u8),
84 SoundVariation(u8, u8),
85 SoundTimbre(u8, u8),
86 SoundReleaseTime(u8, u8),
87 SoundAttack(u8, u8),
88 SoundBrightness(u8, u8),
89 SoundControl1(u8, u8),
90 SoundControl2(u8, u8),
91 SoundControl3(u8, u8),
92 SoundControl4(u8, u8),
93 SoundControl5(u8, u8),
94 GeneralPurpose5(u8, u8),
95 GeneralPurpose6(u8, u8),
96 GeneralPurpose7(u8, u8),
97 GeneralPurpose8(u8, u8),
98 EffectsLevel(u8, u8),
99 TremuloLevel(u8, u8),
100 ChorusLevel(u8, u8),
101 CelesteLevel(u8, u8),
102 PhaserLevel(u8, u8),
103 DataIncrement(u8),
104 DataDecrement(u8),
105 RegisteredParameterNumber(u8, u8),
106 RegisteredParameterNumberLSB(u8, u8),
107 NonRegisteredParameterNumber(u8, u8),
108 NonRegisteredParameterNumberLSB(u8, u8),
109 AllControllersOff(u8),
110 LocalControl(u8, u8),
111 AllNotesOff(u8),
112 AllSoundOff(u8),
113 OmniOff(u8),
114 OmniOn(u8),
115 MonophonicOperation(u8, u8),
116 PolyphonicOperation(u8),
117 ControlChange(u8, u8, u8),
118
119 ProgramChange(u8, u8),
120 ChannelPressure(u8, u8),
121 PitchWheelChange(u8, f64),
122 SystemExclusive(Vec<u8>),
123 MTCQuarterFrame(u8, u8),
124 SongPositionPointer(u16),
125 SongSelect(u8),
126 TimeCode(f32, u8, u8, u8, u8),
127
128 EndOfTrack,
129 TuneRequest,
130 MIDIClock,
131 MIDIStart,
132 MIDIContinue,
133 MIDIStop,
134 ActiveSense,
135 Reset
136}
137
138pub trait MIDIBytes {
139 fn as_bytes(&self) -> Vec<u8>;
140 fn from_bytes(bytes: &mut Vec<u8>, default_byte: u8) -> Result<Self, ApresError> where Self: std::marker::Sized;
141}
142
143impl MIDIBytes for MIDIEvent {
144 fn as_bytes(&self) -> Vec<u8> {
145 match self {
146 MIDIEvent::SequenceNumber(sequence) => {
147 vec![
148 0xFF, 0x00, 0x02,
149 (sequence / 256) as u8,
150 (sequence % 256) as u8
151 ]
152 }
153
154 MIDIEvent::Text(text) => {
155 let text_bytes = text.as_bytes();
156 let length_bytes = to_variable_length_bytes(text_bytes.len());
157
158 let mut output = vec![0xFF, 0x01];
159 output.extend(length_bytes.iter().copied());
160 output.extend(text_bytes.iter().copied());
161
162 output
163 }
164
165 MIDIEvent::CopyRightNotice(text) => {
166 let text_bytes = text.as_bytes();
167 let length_bytes = to_variable_length_bytes(text_bytes.len());
168
169 let mut output = vec![0xFF, 0x02];
170 output.extend(length_bytes.iter().copied());
171 output.extend(text_bytes.iter().copied());
172
173 output
174 }
175
176 MIDIEvent::TrackName(track_name) => {
177 let text_bytes = track_name.as_bytes();
178 let length_bytes = to_variable_length_bytes(text_bytes.len());
179
180 let mut output = vec![0xFF, 0x03];
181 output.extend(length_bytes.iter().copied());
182 output.extend(text_bytes.iter().copied());
183
184 output
185 }
186
187 MIDIEvent::InstrumentName(instrument_name) => {
188 let text_bytes = instrument_name.as_bytes();
189 let length_bytes = to_variable_length_bytes(text_bytes.len());
190
191 let mut output = vec![0xFF, 0x04];
192 output.extend(length_bytes.iter().copied());
193 output.extend(text_bytes.iter().copied());
194
195 output
196 }
197
198 MIDIEvent::Lyric(lyric) => {
199 let text_bytes = lyric.as_bytes();
200 let length_bytes = to_variable_length_bytes(text_bytes.len());
201
202 let mut output = vec![0xFF, 0x05];
203 output.extend(length_bytes.iter().copied());
204 output.extend(text_bytes.iter().copied());
205
206 output
207 }
208
209 MIDIEvent::Marker(text) => {
210 let text_bytes = text.as_bytes();
211 let length_bytes = to_variable_length_bytes(text_bytes.len());
212
213 let mut output = vec![0xFF, 0x06];
214 output.extend(length_bytes.iter().copied());
215 output.extend(text_bytes.iter().copied());
216
217 output
218 }
219
220 MIDIEvent::CuePoint(text) => {
221 let text_bytes = text.as_bytes();
222 let length_bytes = to_variable_length_bytes(text_bytes.len());
223
224 let mut output = vec![0xFF, 0x07];
225 output.extend(length_bytes.iter().copied());
226 output.extend(text_bytes.iter().copied());
227
228 output
229 }
230
231 MIDIEvent::EndOfTrack => {
232 vec![0xFF, 0x2F, 0x00]
233 }
234
235 MIDIEvent::ChannelPrefix(channel) => {
236 vec![0xFF, 0x20, 0x01, *channel]
237 }
238
239 MIDIEvent::SetTempo(us_per_quarter_note) => {
240 vec![
241 0xFF, 0x51, 0x03,
242 ((*us_per_quarter_note / 256u32.pow(2)) % 256) as u8,
243 ((*us_per_quarter_note / 256u32.pow(1)) % 256) as u8,
244 (*us_per_quarter_note % 256) as u8,
245 ]
246 }
247
248 MIDIEvent::SMPTEOffset(hour, minute, second, ff, fr) => {
250 vec![0xFF, 0x54, 05, *hour, *minute, *second, *ff, *fr]
251 }
252
253 MIDIEvent::TimeSignature(numerator, denominator, clocks_per_metronome, thirtysecondths_per_quarter) => {
254 vec![0xFF, 0x58, 04, *numerator, *denominator, *clocks_per_metronome, *thirtysecondths_per_quarter]
255 }
256
257 MIDIEvent::KeySignature(string) => {
258 let (mi, sf) = get_mi_sf(string);
259 vec![0xFF, 0x59, 0x02, sf, mi]
260 }
261
262 MIDIEvent::SequencerSpecific(data) => {
263 let mut output: Vec<u8> = vec![0xFF, 0x7F];
264 output.push(data.len() as u8); output.extend(data.iter().copied());
266 output
267 }
268
269 MIDIEvent::NoteOn(channel, note, velocity) => {
270 vec![
271 0x90 | *channel,
272 *note,
273 *velocity
274 ]
275 }
276
277 MIDIEvent::NoteOff(channel, note, velocity) => {
278 vec![
279 0x80 | *channel,
280 *note,
281 *velocity
282 ]
283 }
284
285 MIDIEvent::AfterTouch(channel, note, pressure) => {
286 vec![
287 0xA0 | *channel,
288 *note,
289 *pressure
290 ]
291 }
292
293 MIDIEvent::BankSelect(channel, value) => {
294 vec![ 0xB0 | *channel, 0x00, *value ]
295 }
296 MIDIEvent::BankSelectLSB(channel, value) => {
297 vec![ 0xB0 | *channel, 0x20, *value ]
298 }
299
300 MIDIEvent::ModulationWheel(channel, value) => {
301 vec![ 0xB0 | *channel, 0x01, *value ]
302 }
303 MIDIEvent::ModulationWheelLSB(channel, value) => {
304 vec![ 0xB0 | *channel, 0x21, *value ]
305 }
306
307 MIDIEvent::BreathController(channel, value) => {
308 vec![ 0xB0 | *channel, 0x02, *value ]
309 }
310 MIDIEvent::BreathControllerLSB(channel, value) => {
311 vec![ 0xB0 | *channel, 0x22, *value ]
312 }
313
314 MIDIEvent::FootPedal(channel, value) => {
315 vec![ 0xB0 | *channel, 0x04, *value ]
316 }
317 MIDIEvent::FootPedalLSB(channel, value) => {
318 vec![ 0xB0 | *channel, 0x24, *value ]
319 }
320
321 MIDIEvent::PortamentoTime(channel, value) => {
322 vec![ 0xB0 | *channel, 0x05, *value ]
323 }
324 MIDIEvent::PortamentoTimeLSB(channel, value) => {
325 vec![ 0xB0 | *channel, 0x25, *value ]
326 }
327
328 MIDIEvent::DataEntry(channel, value) => {
329 vec![ 0xB0 | *channel, 0x06, *value ]
330 }
331 MIDIEvent::DataEntryLSB(channel, value) => {
332 vec![ 0xB0 | *channel, 0x26, *value ]
333 }
334
335 MIDIEvent::Volume(channel, value) => {
336 vec![ 0xB0 | *channel, 0x07, *value ]
337 }
338 MIDIEvent::VolumeLSB(channel, value) => {
339 vec![ 0xB0 | *channel, 0x27, *value ]
340 }
341
342 MIDIEvent::Balance(channel, value) => {
343 vec![ 0xB0 | *channel, 0x08, *value ]
344 }
345 MIDIEvent::BalanceLSB(channel, value) => {
346 vec![ 0xB0 | *channel, 0x28, *value ]
347 }
348
349 MIDIEvent::Pan(channel, value) => {
350 vec![ 0xB0 | *channel, 0x0A, *value ]
351 }
352 MIDIEvent::PanLSB(channel, value) => {
353 vec![ 0xB0 | *channel, 0x2A, *value ]
354 }
355
356 MIDIEvent::Expression(channel, value) => {
357 vec![ 0xB0 | *channel, 0x0B, *value ]
358 }
359 MIDIEvent::ExpressionLSB(channel, value) => {
360 vec![ 0xB0 | *channel, 0x2B, *value ]
361 }
362
363 MIDIEvent::EffectControl1(channel, value) => {
364 vec![ 0xB0 | *channel, 0x0C, *value ]
365 }
366 MIDIEvent::EffectControl1LSB(channel, value) => {
367 vec![ 0xB0 | *channel, 0x2C, *value ]
368 }
369 MIDIEvent::EffectControl2(channel, value) => {
370 vec![ 0xB0 | *channel, 0x0D, *value ]
371 }
372 MIDIEvent::EffectControl2LSB(channel, value) => {
373 vec![ 0xB0 | *channel, 0x2D, *value ]
374 }
375
376 MIDIEvent::GeneralPurpose1(channel, value) => {
377 vec![ 0xB0 | *channel, 0x10, *value ]
378 }
379 MIDIEvent::GeneralPurpose1LSB(channel, value) => {
380 vec![ 0xB0 | *channel, 0x30, *value ]
381 }
382 MIDIEvent::GeneralPurpose2(channel, value) => {
383 vec![ 0xB0 | *channel, 0x11, *value ]
384 }
385 MIDIEvent::GeneralPurpose2LSB(channel, value) => {
386 vec![ 0xB0 | *channel, 0x31, *value ]
387 }
388 MIDIEvent::GeneralPurpose3(channel, value) => {
389 vec![ 0xB0 | *channel, 0x12, *value ]
390 }
391 MIDIEvent::GeneralPurpose3LSB(channel, value) => {
392 vec![ 0xB0 | *channel, 0x32, *value ]
393 }
394 MIDIEvent::GeneralPurpose4(channel, value) => {
395 vec![ 0xB0 | *channel, 0x13, *value ]
396 }
397 MIDIEvent::GeneralPurpose4LSB(channel, value) => {
398 vec![ 0xB0 | *channel, 0x33, *value ]
399 }
400 MIDIEvent::GeneralPurpose5(channel, value) => {
401 vec![ 0xB0 | *channel, 0x50, *value]
402 }
403 MIDIEvent::GeneralPurpose6(channel, value) => {
404 vec![ 0xB0 | *channel, 0x51, *value]
405 }
406 MIDIEvent::GeneralPurpose7(channel, value) => {
407 vec![ 0xB0 | *channel, 0x52, *value]
408 }
409 MIDIEvent::GeneralPurpose8(channel, value) => {
410 vec![ 0xB0 | *channel, 0x53, *value]
411 }
412
413 MIDIEvent::HoldPedal(channel, value) => {
414 vec![
415 0xB0 | *channel,
416 0x40,
417 *value
418 ]
419 }
420
421 MIDIEvent::Portamento(channel, value) => {
422 vec![
423 0xB0 | *channel,
424 0x41,
425 *value
426 ]
427 }
428
429 MIDIEvent::Sustenuto(channel, value) => {
430 vec![
431 0xB0 | *channel,
432 0x42,
433 *value
434 ]
435 }
436
437 MIDIEvent::SoftPedal(channel, value) => {
438 vec![
439 0xB0 | *channel,
440 0x43,
441 *value
442 ]
443 }
444
445 MIDIEvent::Legato(channel, value) => {
446 vec![
447 0xB0 | *channel,
448 0x44,
449 *value
450 ]
451 }
452
453 MIDIEvent::Hold2Pedal(channel, value) => {
454 vec![
455 0xB0 | *channel,
456 0x45,
457 *value
458 ]
459 }
460
461 MIDIEvent::SoundVariation(channel, value) => {
462 vec![
463 0xB0 | *channel,
464 0x46,
465 *value
466 ]
467 }
468
469 MIDIEvent::SoundTimbre(channel, value) => {
470 vec![
471 0xB0 | *channel,
472 0x47,
473 *value
474 ]
475 }
476
477 MIDIEvent::SoundReleaseTime(channel, value) => {
478 vec![
479 0xB0 | *channel,
480 0x48,
481 *value
482 ]
483 }
484
485 MIDIEvent::SoundAttack(channel, value) => {
486 vec![
487 0xB0 | *channel,
488 0x49,
489 *value
490 ]
491 }
492
493 MIDIEvent::SoundBrightness(channel, value) => {
494 vec![
495 0xB0 | *channel,
496 0x4A,
497 *value
498 ]
499 }
500
501 MIDIEvent::SoundControl1(channel, value) => {
502 vec![ 0xB0 | *channel, 0x4B, *value ]
503 }
504 MIDIEvent::SoundControl2(channel, value) => {
505 vec![ 0xB0 | *channel, 0x4C, *value ]
506 }
507 MIDIEvent::SoundControl3(channel, value) => {
508 vec![ 0xB0 | *channel, 0x4D, *value ]
509 }
510 MIDIEvent::SoundControl4(channel, value) => {
511 vec![ 0xB0 | *channel, 0x4E, *value ]
512 }
513 MIDIEvent::SoundControl5(channel, value) => {
514 vec![ 0xB0 | *channel, 0x4F, *value ]
515 }
516
517 MIDIEvent::EffectsLevel(channel, value) => {
518 vec![
519 0xB0 | *channel,
520 0x5B,
521 *value
522 ]
523 }
524
525 MIDIEvent::TremuloLevel(channel, value) => {
526 vec![
527 0xB0 | *channel,
528 0x5C,
529 *value
530 ]
531 }
532
533 MIDIEvent::ChorusLevel(channel, value) => {
534 vec![
535 0xB0 | *channel,
536 0x5D,
537 *value
538 ]
539 }
540
541 MIDIEvent::CelesteLevel(channel, value) => {
542 vec![
543 0xB0 | *channel,
544 0x5E,
545 *value
546 ]
547 }
548
549 MIDIEvent::PhaserLevel(channel, value) => {
550 vec![
551 0xB0 | *channel,
552 0x5F,
553 *value
554 ]
555 }
556
557 MIDIEvent::DataIncrement(channel) => {
558 vec![0xB0 | *channel, 0x60, 0x00]
559 }
560
561 MIDIEvent::DataDecrement(channel) => {
562 vec![0xB0 | *channel, 0x61, 0x00]
563 }
564
565 MIDIEvent::NonRegisteredParameterNumber(channel, value) => {
566 vec![ 0xB0 | *channel, 0x63, *value ]
567 }
568 MIDIEvent::NonRegisteredParameterNumberLSB(channel, value) => {
569 vec![ 0xB0 | *channel, 0x62, *value ]
570 }
571 MIDIEvent::RegisteredParameterNumber(channel, value) => {
572 vec![ 0xB0 | *channel, 0x65, *value ]
573 }
574 MIDIEvent::RegisteredParameterNumberLSB(channel, value) => {
575 vec![ 0xB0 | *channel, 0x64, *value ]
576 }
577
578
579 MIDIEvent::AllControllersOff(channel) => {
580 vec![
581 0xB0 | *channel,
582 0x79, 0x00
583 ]
584 }
585
586 MIDIEvent::LocalControl(channel, value) => {
587 vec![ 0xB0 | *channel, 0x7A, *value ]
588 }
589
590 MIDIEvent::AllNotesOff(channel) => {
591 vec![
592 0xB0 | *channel,
593 0x7B, 0x00
594 ]
595 }
596
597 MIDIEvent::AllSoundOff(channel) => {
598 vec![
599 0xB0 | *channel,
600 0x78, 0x00
601 ]
602 }
603
604 MIDIEvent::OmniOff(channel) => {
605 vec![
606 0xB0 | *channel,
607 0x7C, 0x00
608 ]
609 }
610
611 MIDIEvent::OmniOn(channel) => {
612 vec![
613 0xB0 | *channel,
614 0x7D, 0x00
615 ]
616 }
617
618 MIDIEvent::MonophonicOperation(channel, value) => {
619 vec![
620 0xB0 | *channel, 0xFE, *value
621 ]
622 }
623
624 MIDIEvent::PolyphonicOperation(channel) => {
625 vec![
626 0xB0 | *channel, 0xFF, 0
627 ]
628 }
629
630 MIDIEvent::ControlChange(channel, controller, value) => {
631 vec![
632 0xB0 | *channel,
633 *controller,
634 *value
635 ]
636 }
637
638 MIDIEvent::ProgramChange(channel, program) => {
639 vec![
640 0xC0 | *channel,
641 *program
642 ]
643 }
644
645 MIDIEvent::ChannelPressure(channel, pressure) => {
646 vec![
647 0xD0 | *channel,
648 *pressure
649 ]
650 }
651
652 MIDIEvent::PitchWheelChange(channel, value) => {
653 let unsigned_value = get_pitchwheel_value(*value);
654 let lsb: u8 = (unsigned_value & 0x007F) as u8;
655 let msb: u8 = ((unsigned_value >> 8) & 0x007F) as u8;
656 vec![
657 0xE0 | *channel,
658 lsb,
659 msb
660 ]
661 }
662
663 MIDIEvent::SystemExclusive(data) => {
664 let mut output = vec![0xF0];
665 output.extend(data.iter().copied());
666 output.push(0xF7);
667 output
668 }
669
670 MIDIEvent::MTCQuarterFrame(message_type, values) => {
671 let mut b = 0;
672 b |= *message_type;
673 b <<= 3;
674 b |= *values;
675
676 vec![ 0xF1, b ]
677 }
678
679 MIDIEvent::TimeCode(rate, hour, minute, second, frame) => {
680 let coded_rate = match rate {
681 24.0 => { 0 }
682 25.0 => { 1 }
683 27.97 => { 2 }
684 30.0 => { 3 }
685 _ => { 3 } };
687 let first_byte: u8 = (coded_rate << 5) + hour;
688 vec![0xF1, first_byte, *minute, *second, *frame]
689 }
690
691 MIDIEvent::SongPositionPointer(beat) => {
692 vec![
693 0xF2,
694 (*beat & 0x7F) as u8,
695 ((*beat >> 8) & 0x7F) as u8
696 ]
697 }
698
699 MIDIEvent::SongSelect(song) => {
700 vec![
701 0xF3,
702 *song & 0x7F
703 ]
704 }
705
706 MIDIEvent::TuneRequest => {
707 vec![ 0xF6 ]
708 }
709 MIDIEvent::MIDIClock => {
710 vec![ 0xF8 ]
711 }
712 MIDIEvent::MIDIStart => {
713 vec![ 0xFA ]
714 }
715 MIDIEvent::MIDIContinue => {
716 vec![ 0xFB ]
717 }
718 MIDIEvent::MIDIStop => {
719 vec![ 0xFC ]
720 }
721 MIDIEvent::ActiveSense => {
722 vec![ 0xFE ]
723 }
724 MIDIEvent::Reset => {
725 vec![ 0xFF ]
726 }
727 }
728 }
729
730 fn from_bytes(bytes: &mut Vec<u8>, default_byte: u8) -> Result<MIDIEvent, ApresError> {
731 let mut output = Err(ApresError::InvalidBytes(bytes.clone()));
732
733 let n: u32;
734 let varlength: u64;
735 let leadbyte = bytes.remove(0);
736
737 match leadbyte {
738 0..=0x7F => {
739 bytes.insert(0, leadbyte);
740 bytes.insert(0, default_byte);
741 output = MIDIEvent::from_bytes(bytes, default_byte);
742 }
743
744 0x80..=0xEF => {
745 let channel: u8;
746 let leadnibble: u8 = leadbyte >> 4;
747 match leadnibble {
748 0x8 => {
749 channel = leadbyte & 0x0F;
750 let note = bytes.remove(0);
751 let velocity = bytes.remove(0);
752 let event = MIDIEvent::NoteOff(channel, note, velocity);
753 output = Ok(event);
754 }
755 0x9 => {
756 channel = leadbyte & 0x0F;
757 let note = bytes.remove(0);
758 let velocity = bytes.remove(0);
759 let event = if velocity == 0 {
761 MIDIEvent::NoteOff(channel, note, velocity)
762 } else {
763 MIDIEvent::NoteOn(channel, note, velocity)
764 };
765
766 output = Ok(event);
767 }
768 0xA => {
769 channel = leadbyte & 0x0F;
770 let note = bytes.remove(0);
771 let velocity = bytes.remove(0);
772 let event = MIDIEvent::AfterTouch(channel, note, velocity);
773 output = Ok(event);
774 }
775 0xB => {
776 channel = leadbyte & 0x0F;
777 let controller = bytes.remove(0);
778 let value = bytes.remove(0);
779 output = match controller {
780 0x00 => {
781 Ok(MIDIEvent::BankSelect(channel, value))
782 }
783 0x20 => {
784 Ok(MIDIEvent::BankSelectLSB(channel, value))
785 }
786 0x01 => {
787 Ok(MIDIEvent::ModulationWheel(channel, value))
788 }
789 0x21 => {
790 Ok(MIDIEvent::ModulationWheelLSB(channel, value))
791 }
792 0x02 => {
793 Ok(MIDIEvent::BreathController(channel, value))
794 }
795 0x22 => {
796 Ok(MIDIEvent::BreathControllerLSB(channel, value))
797 }
798 0x04 => {
799 Ok(MIDIEvent::FootPedal(channel, value))
800 }
801 0x24 => {
802 Ok(MIDIEvent::FootPedalLSB(channel, value))
803 }
804 0x05 => {
805 Ok(MIDIEvent::PortamentoTime(channel, value))
806 }
807 0x25 => {
808 Ok(MIDIEvent::PortamentoTimeLSB(channel, value))
809 }
810 0x06 => {
811 Ok(MIDIEvent::DataEntry(channel, value))
812 }
813 0x26 => {
814 Ok(MIDIEvent::DataEntryLSB(channel, value))
815 }
816 0x07 => {
817 Ok(MIDIEvent::Volume(channel, value))
818 }
819 0x27 => {
820 Ok(MIDIEvent::VolumeLSB(channel, value))
821 }
822 0x08 => {
823 Ok(MIDIEvent::Balance(channel, value))
824 }
825 0x28 => {
826 Ok(MIDIEvent::BalanceLSB(channel, value))
827 }
828 0x0A => {
829 Ok(MIDIEvent::Pan(channel, value))
830 }
831 0x2A => {
832 Ok(MIDIEvent::PanLSB(channel, value))
833 }
834 0x0B => {
835 Ok(MIDIEvent::Expression(channel, value))
836 }
837 0x2B => {
838 Ok(MIDIEvent::ExpressionLSB(channel, value))
839 }
840 0x0C => {
841 Ok(MIDIEvent::EffectControl1(channel, value))
842 }
843 0x2C => {
844 Ok(MIDIEvent::EffectControl1LSB(channel, value))
845 }
846 0x0D => {
847 Ok(MIDIEvent::EffectControl2(channel, value))
848 }
849 0x2D => {
850 Ok(MIDIEvent::EffectControl2LSB(channel, value))
851 }
852
853 0x10 => {
854 Ok(MIDIEvent::GeneralPurpose1(channel, value))
855 }
856 0x30 => {
857 Ok(MIDIEvent::GeneralPurpose1LSB(channel, value))
858 }
859 0x11 => {
860 Ok(MIDIEvent::GeneralPurpose2(channel, value))
861 }
862 0x31 => {
863 Ok(MIDIEvent::GeneralPurpose2LSB(channel, value))
864 }
865 0x12 => {
866 Ok(MIDIEvent::GeneralPurpose3(channel, value))
867 }
868 0x32 => {
869 Ok(MIDIEvent::GeneralPurpose3LSB(channel, value))
870 }
871 0x13 => {
872 Ok(MIDIEvent::GeneralPurpose4(channel, value))
873 }
874 0x33 => {
875 Ok(MIDIEvent::GeneralPurpose4LSB(channel, value))
876 }
877 0x40 => {
878 Ok(MIDIEvent::HoldPedal(channel, value))
879 }
880 0x41 => {
881 Ok(MIDIEvent::Portamento(channel, value))
882 }
883 0x42 => {
884 Ok(MIDIEvent::Sustenuto(channel, value))
885 }
886 0x43 => {
887 Ok(MIDIEvent::SoftPedal(channel, value))
888 }
889 0x44 => {
890 Ok(MIDIEvent::Legato(channel, value))
891 }
892 0x45 => {
893 Ok(MIDIEvent::Hold2Pedal(channel, value))
894 }
895 0x46 => {
896 Ok(MIDIEvent::SoundVariation(channel, value))
897 }
898 0x47 => {
899 Ok(MIDIEvent::SoundTimbre(channel, value))
900 }
901 0x48 => {
902 Ok(MIDIEvent::SoundReleaseTime(channel, value))
903 }
904 0x49 => {
905 Ok(MIDIEvent::SoundAttack(channel, value))
906 }
907 0x4A => {
908 Ok(MIDIEvent::SoundBrightness(channel, value))
909 }
910 0x4B => {
911 Ok(MIDIEvent::SoundControl1(channel, value))
912 }
913 0x4C => {
914 Ok(MIDIEvent::SoundControl2(channel, value))
915 }
916 0x4D => {
917 Ok(MIDIEvent::SoundControl3(channel, value))
918 }
919 0x4E => {
920 Ok(MIDIEvent::SoundControl4(channel, value))
921 }
922 0x4F => {
923 Ok(MIDIEvent::SoundControl5(channel, value))
924 }
925 0x50 => {
926 Ok(MIDIEvent::GeneralPurpose5(channel, value))
927 }
928 0x51 => {
929 Ok(MIDIEvent::GeneralPurpose6(channel, value))
930 }
931 0x52 => {
932 Ok(MIDIEvent::GeneralPurpose7(channel, value))
933 }
934 0x53 => {
935 Ok(MIDIEvent::GeneralPurpose8(channel, value))
936 }
937
938 0x5B => {
939 Ok(MIDIEvent::EffectsLevel(channel, value))
940 }
941
942 0x5C => {
943 Ok(MIDIEvent::TremuloLevel(channel, value))
944 }
945
946 0x5D => {
947 Ok(MIDIEvent::ChorusLevel(channel, value))
948 }
949 0x5E => {
950 Ok(MIDIEvent::CelesteLevel(channel, value))
951 }
952
953 0x5F => {
954 Ok(MIDIEvent::PhaserLevel(channel, value))
955 }
956
957 0x60 => {
958 Ok(MIDIEvent::DataIncrement(channel))
959 }
960
961 0x61 => {
962 Ok(MIDIEvent::DataDecrement(channel))
963 }
964 0x62 => {
965 Ok(MIDIEvent::NonRegisteredParameterNumberLSB(channel, value))
966 }
967
968 0x63 => {
969 Ok(MIDIEvent::NonRegisteredParameterNumber(channel, value))
970 }
971
972 0x64 => {
973 Ok(MIDIEvent::RegisteredParameterNumberLSB(channel, value))
974 }
975 0x65 => {
976 Ok(MIDIEvent::RegisteredParameterNumber(channel, value))
977 }
978 0x78 => {
979 Ok(MIDIEvent::AllSoundOff(channel))
980 }
981 0x79 => {
982 Ok(MIDIEvent::AllControllersOff(channel))
983 }
984 0x7A => {
985 Ok(MIDIEvent::LocalControl(channel, value))
986 }
987 0x7B => {
988 Ok(MIDIEvent::AllNotesOff(channel))
989 }
990 0x7C => {
991 Ok(MIDIEvent::OmniOff(channel))
992 }
993 0x7D => {
994 Ok(MIDIEvent::OmniOn(channel))
995 }
996 0xFE => {
997 Ok(MIDIEvent::MonophonicOperation(channel, value))
998 }
999 0xFF => {
1000 Ok(MIDIEvent::PolyphonicOperation(channel))
1001 }
1002 _ => {
1003 Ok(MIDIEvent::ControlChange(channel, controller, value))
1004 }
1005 }
1006 }
1007 0xC => {
1008 channel = leadbyte & 0x0F;
1009 let new_program = bytes.remove(0);
1010 let event = MIDIEvent::ProgramChange(channel, new_program);
1011 output = Ok(event);
1012 }
1013 0xD => {
1014 channel = leadbyte & 0x0F;
1015 let pressure = bytes.remove(0);
1016 let event = MIDIEvent::ChannelPressure(channel, pressure);
1017 output = Ok(event);
1018 }
1019 0xE => {
1020 channel = leadbyte & 0x0F;
1021 let least_significant_byte = bytes.remove(0);
1022 let most_significant_byte = bytes.remove(0);
1023 let event = build_pitch_wheel_change(channel, least_significant_byte, most_significant_byte);
1024 output = Ok(event);
1025 }
1026 _ => {
1027 }
1028 }
1029 }
1030
1031 0xF0 => {
1032 let mut bytedump = Vec::new();
1034 loop {
1035 let byte = bytes.remove(0);
1036 if byte == 0xF7 {
1037 break;
1038 } else {
1039 bytedump.push(byte);
1040 }
1041 }
1042
1043 let event = MIDIEvent::SystemExclusive(bytedump);
1044 output = Ok(event);
1045 }
1046
1047 0xF2 => {
1048 let least_significant_byte = bytes.remove(0);
1050 let most_significant_byte = bytes.remove(0);
1051
1052 let beat = ((most_significant_byte as u16) << 8) + (least_significant_byte as u16);
1053 let event = MIDIEvent::SongPositionPointer(beat);
1054 output = Ok(event);
1055 }
1056
1057 0xF3 => {
1058 let song = bytes.remove(0);
1059 let event = MIDIEvent::SongSelect(song & 0x7F);
1060 output = Ok(event);
1061 }
1062
1063 0xFF => {
1064 let meta_byte = bytes.remove(0); varlength = get_variable_length_number(bytes);
1066 if meta_byte == 0x51 {
1067 let event = MIDIEvent::SetTempo(dequeue_n(bytes, varlength as usize));
1068 output = Ok(event);
1069 } else {
1070 let mut bytedump = Vec::new();
1071 for _ in 0..varlength {
1072 bytedump.push(bytes.remove(0));
1073 }
1074 match meta_byte {
1075 0x00 => {
1076 let event = MIDIEvent::SequenceNumber((bytedump[0] as u16 * 256) + bytedump[1] as u16);
1077 output = Ok(event);
1078 }
1079
1080 0x01 => {
1081 match std::str::from_utf8(bytedump.as_slice()) {
1082 Ok(textdump) => {
1083 let event = MIDIEvent::Text(textdump.to_string());
1084 output = Ok(event);
1085 }
1086 Err(_e) => {
1087 output = Err(ApresError::IllegibleString(bytedump.clone()));
1088 }
1089 }
1090 }
1091 0x02 => {
1092 match std::str::from_utf8(bytedump.as_slice()) {
1093 Ok(textdump) => {
1094 let event = MIDIEvent::CopyRightNotice(textdump.to_string());
1095 output = Ok(event);
1096 }
1097 Err(_e) => {
1098 output = Err(ApresError::IllegibleString(bytedump.clone()));
1099 }
1100 }
1101 }
1102 0x03 => {
1103 match std::str::from_utf8(bytedump.as_slice()) {
1104 Ok(textdump) => {
1105 let event = MIDIEvent::TrackName(textdump.to_string());
1106 output = Ok(event);
1107 }
1108 Err(_e) => {
1109 output = Err(ApresError::IllegibleString(bytedump.clone()));
1110 }
1111 }
1112 }
1113 0x04 => {
1114 match std::str::from_utf8(bytedump.as_slice()) {
1115 Ok(textdump) => {
1116 let event = MIDIEvent::InstrumentName(textdump.to_string());
1117 output = Ok(event);
1118 }
1119 Err(_e) => {
1120 output = Err(ApresError::IllegibleString(bytedump.clone()));
1121 }
1122 }
1123 }
1124 0x05 => {
1125 match std::str::from_utf8(bytedump.as_slice()) {
1126 Ok(textdump) => {
1127 let event = MIDIEvent::Lyric(textdump.to_string());
1128 output = Ok(event);
1129 }
1130 Err(_e) => {
1131 output = Err(ApresError::IllegibleString(bytedump.clone()));
1132 }
1133 }
1134 }
1135 0x06 => {
1136 match std::str::from_utf8(bytedump.as_slice()) {
1137 Ok(textdump) => {
1138 let event = MIDIEvent::Marker(textdump.to_string());
1139 output = Ok(event);
1140 }
1141 Err(_e) => {
1142 output = Err(ApresError::IllegibleString(bytedump.clone()));
1143 }
1144 }
1145 }
1146 0x07 => {
1147 match std::str::from_utf8(bytedump.as_slice()) {
1148 Ok(textdump) => {
1149 let event = MIDIEvent::CuePoint(textdump.to_string());
1150 output = Ok(event);
1151 }
1152 Err(_e) => {
1153 output = Err(ApresError::IllegibleString(bytedump.clone()));
1154 }
1155 }
1156 }
1157 0x20 => {
1158 let event = MIDIEvent::ChannelPrefix(bytedump[0]);
1159 output = Ok(event);
1160 }
1161 0x2F => {
1162 output = Ok(MIDIEvent::EndOfTrack);
1163 }
1164 0x51 => {
1165 }
1166 0x54 => {
1167 let event = MIDIEvent::SMPTEOffset(bytedump[0], bytedump[1], bytedump[2], bytedump[3], bytedump[4]);
1168 output = Ok(event);
1169 }
1170 0x58 => {
1171 let event = MIDIEvent::TimeSignature(bytedump[0], bytedump[1], bytedump[2], bytedump[3]);
1172 output = Ok(event);
1173 }
1174 0x59 => {
1175 let event = build_key_signature(bytedump[1], bytedump[0]);
1176 output = Ok(event);
1177 }
1178 0x7F => {
1179 let event = MIDIEvent::SequencerSpecific(bytedump[3..].to_vec());
1180
1181 output = Ok(event);
1182 }
1183 _ => {
1184 output = Err(ApresError::UnknownMetaEvent(bytes.to_vec()));
1185 }
1186 }
1187 }
1188 }
1189
1190 0xF1 | 0xF6 | 0xF8 | 0xFA | 0xFB | 0xFC | 0xFE | 0xF7 => {
1191 }
1193
1194 0xF4 | 0xF5 | 0xF9 | 0xFD => {
1195 }
1197 }
1198
1199 output
1200 }
1201}
1202
1203#[derive(Debug)]
1242pub struct MIDI {
1243 ppqn: u16,
1244 midi_format: u16, events: HashMap<u64, MIDIEvent>,
1246 event_id_gen: u64,
1247 event_positions: HashMap<u64, (usize, usize)>,
1248
1249 _active_byte: u8 }
1251
1252
1253impl MIDI {
1254 pub fn new() -> MIDI {
1256 MIDI {
1257 event_id_gen: 1, ppqn: 120,
1259 midi_format: 1,
1260 events: HashMap::new(),
1261 event_positions: HashMap::new(),
1262 _active_byte: 0x90
1263 }
1264 }
1265
1266 pub fn from_path(file_path: &str) -> Result<MIDI, ApresError> {
1268 let mut midibytes = Vec::new();
1269 match File::open(file_path) {
1270 Ok(mut file) => {
1271 let file_length = match file.metadata() {
1272 Ok(meta) => {
1273 meta.len()
1274 }
1275 Err(_) => {
1276 0
1277 }
1278 };
1279 let mut buffer: Vec<u8> = vec![0; file_length as usize];
1280 file.read(&mut buffer);
1281
1282 for byte in buffer.iter() {
1283 midibytes.push(*byte);
1284 }
1285 }
1286 Err(e) => {
1287 Err(ApresError::InvalidMIDIFile(file_path.to_string()))?;
1288 }
1289 }
1290
1291 match MIDI::from_bytes(midibytes) {
1292 Ok(midi_ob) => {
1293 Ok(midi_ob)
1294 }
1295 Err(e) => {
1296 Err(e)
1297 }
1299 }
1300 }
1301
1302 fn from_bytes(file_bytes: Vec<u8>) -> Result<MIDI, ApresError> {
1303 let bytes = &mut file_bytes.clone();
1304 let mut mlo: MIDI = MIDI::new();
1305 let mut sub_bytes: Vec<u8>;
1306 let mut chunkcount: HashMap<(u8, u8,u8, u8), u16> = HashMap::new();
1307 let mut current_track: usize = 0;
1308 let mut current_deltatime: usize;
1309
1310 let mut chunk_type: (u8, u8, u8, u8);
1311
1312
1313 let mut divword: u32;
1315 let mut smpte: u32;
1316 let mut tpf: u32;
1317 let mut midi_format: u16;
1318
1319 let mut track_length: u32;
1320
1321 let mut found_header = false;
1322
1323 let mut ppqn: u16 = 120;
1324 while bytes.len() > 0 {
1325 chunk_type = (
1326 bytes.remove(0),
1327 bytes.remove(0),
1328 bytes.remove(0),
1329 bytes.remove(0)
1330 );
1331
1332 let val = chunkcount.entry(chunk_type).or_insert(0);
1333 *val += 1;
1334
1335 if chunk_type == ('M' as u8, 'T' as u8, 'h' as u8, 'd' as u8) {
1336 dequeue_n(bytes, 4); midi_format = dequeue_n(bytes, 2) as u16; dequeue_n(bytes, 2); divword = dequeue_n(bytes, 2);
1340 if divword & 0x8000 > 0 {
1341 smpte = (((divword & 0x7F00) >> 8) as i8) as u32;
1342 tpf = divword & 0x00FF;
1343
1344 } else {
1345 ppqn = (divword & 0x7FFF) as u16;
1346 }
1347 mlo.set_ppqn(ppqn);
1348 mlo.set_format(midi_format);
1349 found_header = true;
1350 } else if chunk_type == ('M' as u8, 'T' as u8, 'r' as u8, 'k' as u8) {
1351 current_deltatime = 0;
1352 track_length = dequeue_n(bytes, 4);
1353 sub_bytes = Vec::new();
1354 for _ in 0..track_length {
1355 sub_bytes.push(bytes.remove(0))
1356 }
1357
1358 while sub_bytes.len() > 0 {
1359 current_deltatime += get_variable_length_number(&mut sub_bytes) as usize;
1360 match mlo.process_mtrk_event(&mut sub_bytes, &mut current_deltatime, current_track) {
1361 Ok(_) => {
1362 Ok(())
1363 }
1364 Err(ApresError::UnknownMetaEvent(bytes)) => {
1365 Ok(())
1366 }
1367 Err(ApresError::IllegibleString(bytes)) => {
1368 Ok(())
1369 }
1370 Err(e) => {
1371 Err(e)
1372 }
1373 }?;
1374 }
1375 current_track += 1;
1376 } else {
1377 Err(ApresError::InvalidBytes(bytes.clone()))?;
1378 }
1379 }
1380
1381 Ok(mlo)
1382 }
1383
1384 fn process_mtrk_event(&mut self, bytes: &mut Vec<u8>, current_deltatime: &mut usize, track: usize) -> Result<u64, ApresError> {
1385 let n: u32;
1386 let varlength: u64;
1387
1388 match bytes.first() {
1389 Some(status_byte) => {
1390 match status_byte {
1391 0x80..=0xEF => {
1392 self._active_byte = *status_byte;
1393 }
1394 _ => ()
1395 }
1396 }
1397 None => ()
1398 }
1399
1400 let event = MIDIEvent::from_bytes(bytes, self._active_byte)?;
1401
1402 Ok(self.insert_event(track, *current_deltatime, event))
1403 }
1404
1405
1406 fn as_bytes(&self) -> Vec<u8> {
1407 let mut output: Vec<u8> = vec!['M' as u8, 'T' as u8, 'h' as u8, 'd' as u8, 0, 0, 0, 6];
1409
1410 let format: u16 = self.get_format();
1411 output.push((format / 256) as u8);
1412 output.push((format % 256) as u8);
1413
1414 let track_count: u16 = self.count_tracks() as u16;
1415 output.push((track_count / 256) as u8);
1416 output.push((track_count % 256) as u8);
1417
1418 let ppqn: u16 = self.get_ppqn();
1419 output.push((ppqn / 256) as u8);
1420 output.push((ppqn % 256) as u8);
1421
1422 let mut track_event_bytes: Vec<u8>;
1424 let mut track_byte_length: u32;
1425 let tracks: Vec<Vec<(usize, u64)>> = self.get_tracks();
1426
1427 for ticks in tracks.iter() {
1428 output.push('M' as u8);
1429 output.push('T' as u8);
1430 output.push('r' as u8);
1431 output.push('k' as u8);
1432
1433 track_event_bytes = Vec::new();
1434 for (tick_delay, eid) in ticks.iter() {
1435 match self.get_event(*eid) {
1436 Some(working_event) => {
1437 track_event_bytes.extend(to_variable_length_bytes(*tick_delay).iter().copied());
1438 track_event_bytes.extend(working_event.as_bytes());
1439 }
1440 None => { }
1441 }
1442 }
1443
1444 track_event_bytes.push(0);
1446 track_event_bytes.extend(MIDIEvent::EndOfTrack.as_bytes().iter().copied());
1447
1448 track_byte_length = track_event_bytes.len() as u32;
1450 output.push((track_byte_length / 256_u32.pow(3)) as u8);
1451 output.push(((track_byte_length / 256_u32.pow(2)) % 256) as u8);
1452 output.push(((track_byte_length / 256_u32.pow(1)) % 256) as u8);
1453 output.push((track_byte_length % 256) as u8);
1454
1455 output.extend(track_event_bytes.iter().copied());
1456 }
1457
1458 output
1459 }
1460
1461 pub fn save(&self, path: &str) {
1463 let bytes = self.as_bytes();
1464 match File::create(path) {
1465 Ok(mut file) => {
1466 file.write_all(bytes.as_slice());
1467 }
1468 Err(e) => {
1469 }
1470 }
1471 }
1472
1473 pub fn get_event_position(&self, event_id: u64) -> Option<&(usize, usize)> {
1475 self.event_positions.get(&event_id)
1476 }
1477
1478 pub fn get_tracks(&self) -> Vec<Vec<(usize, u64)>> {
1481 let mut tracks = Vec::new();
1482 for (eid, (track, tick)) in self.event_positions.iter() {
1483 while tracks.len() <= *track {
1484 tracks.push(Vec::new())
1485 }
1486 match tracks.get_mut(*track) {
1487 Some(ticklist) => {
1488 ticklist.push((*tick, *eid));
1489 }
1490 None => ()
1491 }
1492 }
1493
1494 let mut output = Vec::new();
1495 let mut previous_tick;
1496 let mut current;
1497 for track in tracks.iter_mut() {
1498 track.sort();
1499 current = Vec::new();
1500 previous_tick = 0;
1501 for (current_tick, eid) in track.iter() {
1502 current.push((*current_tick - previous_tick, *eid));
1503 previous_tick = *current_tick;
1504 }
1505 output.push(current);
1506 }
1507
1508 output
1509 }
1510
1511 pub fn count_tracks(&self) -> usize {
1512 let mut used_tracks = HashSet::new();
1513 for (_, (current_track, __)) in self.event_positions.iter() {
1514 used_tracks.insert(current_track);
1515 }
1516
1517 used_tracks.len()
1518 }
1519
1520 pub fn count_events(&self) -> usize {
1521 self.event_positions.len()
1522 }
1523
1524 pub fn get_track_length(&self, track: usize) -> usize {
1525 let mut highest_tick = 0;
1526 for (_, (_current_track, test_tick)) in self.event_positions.iter() {
1527 highest_tick = max(highest_tick, *test_tick);
1528 }
1529
1530 highest_tick + 1
1531 }
1532
1533 pub fn set_ppqn(&mut self, new_ppqn: u16) {
1535 self.ppqn = new_ppqn;
1536 }
1537
1538 pub fn get_ppqn(&self) -> u16 {
1540 self.ppqn
1541 }
1542
1543 pub fn set_format(&mut self, new_format: u16) {
1544 self.midi_format = new_format;
1545 }
1546
1547 pub fn get_format(&self) -> u16 {
1548 self.midi_format
1549 }
1550
1551 pub fn move_event(&mut self, new_track: usize, new_tick: usize, event_id: u64) {
1553 self.event_positions.entry(event_id)
1554 .and_modify(|pair| { *pair = (new_track, new_tick); })
1555 .or_insert((new_track, new_tick));
1556 }
1557
1558 pub fn insert_event(&mut self, track: usize, tick: usize, event: MIDIEvent) -> u64 {
1560 let new_event_id = self.event_id_gen;
1561 self.event_id_gen += 1;
1562
1563 self.events.insert(new_event_id, event);
1564
1565 self.move_event(track, tick, new_event_id);
1566
1567 new_event_id
1568 }
1569
1570 pub fn push_event(&mut self, track: usize, wait: usize, event: MIDIEvent) -> u64 {
1572 let new_event_id = self.event_id_gen;
1573
1574 self.events.insert(new_event_id, event);
1575 self.event_id_gen += 1;
1576
1577 let last_tick_in_track = self.get_track_length(track) - 1;
1578 self.move_event(track, last_tick_in_track + wait, new_event_id);
1579
1580 new_event_id
1581 }
1582
1583 pub fn get_event(&self, event_id: u64) -> Option<MIDIEvent> {
1584 match self.events.get(&event_id) {
1585 Some(event) => {
1586 Some(event.clone())
1587 }
1588 None => {
1589 None
1590 }
1591 }
1592 }
1593
1594 pub fn replace_event(&mut self, event_id: u64, new_midi_event: MIDIEvent) -> Result<(), ApresError> {
1595 if self.events.contains_key(&event_id) {
1596 self.events.entry(event_id)
1597 .and_modify(|e| *e = new_midi_event);
1598 Ok(())
1599 } else {
1600 Err(ApresError::EventNotFound(event_id))
1601 }
1602 }
1603}
1604
1605pub fn listen<T>(path: &str, context: &mut T, callback: fn(&mut Controller, &mut T, &MIDIEvent) -> ()) -> Result<(), ApresError> {
1606 match Controller::new(path) {
1607 Ok(mut controller) => {
1608 controller.listen(context, callback)
1609 }
1610 Err(e) => {
1611 Err(e)
1612 }
1613 }
1614}
1615
1616fn dequeue_n(bytes: &mut Vec<u8>, n: usize) -> u32 {
1617 let mut tn: u32 = 0;
1618 for _ in 0..n {
1619 tn *= 256;
1620 let x = bytes.remove(0);
1621 tn += x as u32;
1622 }
1623 tn
1624}
1625
1626fn get_variable_length_number(bytes: &mut Vec<u8>) -> u64 {
1627 let mut n = 0u64;
1628
1629 loop {
1630 n <<= 7;
1631 let x = bytes.remove(0);
1632 n |= (x & 0x7F) as u64;
1633 if x & 0x80 == 0 {
1634 break;
1635 }
1636 }
1637 n
1638}
1639
1640fn to_variable_length_bytes(number: usize) -> Vec<u8> {
1641 let mut output = Vec::new();
1642 let mut first_pass = true;
1643 let mut working_number = number;
1644 let mut tmp;
1645 while working_number > 0 || first_pass {
1646 tmp = working_number & 0x7F;
1647 working_number >>= 7;
1648
1649 if ! first_pass {
1650 tmp |= 0x80;
1651 }
1652
1653 output.push(tmp as u8);
1654 first_pass = false;
1655 }
1656 output.reverse();
1657
1658 output
1659}
1660
1661pub fn get_pitchwheel_value(n: f64) -> u16 {
1663 if n < 0_f64 {
1664 ((1_f64 + n) * (0x2000 as f64)) as u16
1665 } else if n > 0_f64 {
1666 (n * (0x1FFF as f64)) as u16 + 0x2000
1667 } else {
1668 0x2000
1669 }
1670}
1671
1672fn build_key_signature(mut mi: u8, mut sf: u8) -> MIDIEvent {
1673 let chord_name = get_chord_name_from_mi_sf(mi, sf);
1674
1675 MIDIEvent::KeySignature(chord_name.to_string())
1676}
1677
1678fn build_pitch_wheel_change(channel: u8, lsb: u8, msb: u8) -> MIDIEvent {
1679 let unsigned_value: f64 = (((msb as u16) << 8) + (lsb as u16)) as f64;
1680 let new_value: f64 = ((unsigned_value * 2_f64) as f64 / 0x3FFF as f64) - 1_f64;
1681 MIDIEvent::PitchWheelChange(channel, new_value)
1682}
1683
1684pub fn get_mi_sf(chord_name: &str) -> (u8, u8) {
1685 match chord_name {
1686 "A" => (0, 3),
1687 "A#" | "Bb" => (0, 8 | 2),
1688 "B" => (0, 5),
1689 "C" => (0, 0),
1690 "C#" | "Db" => (0, 7),
1691 "D" => (0, 2),
1692 "D#" | "Eb" => (0, 8 | 3),
1693 "E" => (0, 4),
1694 "F" => (0, 8 | 1),
1695 "F#" | "Gb" => (0, 6),
1696 "G" => (0, 1),
1697 "Am" => (1, 0),
1698 "A#m" | "Bbm" => (1, 7),
1699 "Bm" => (1, 2),
1700 "Cm" => (1, 8 | 3),
1701 "C#m" | "Dbm" => (1, 4),
1702 "Dm" => (1, 8 | 1),
1703 "D#m" | "Ebm" => (1, 6),
1704 "Em" => (1, 1),
1705 "Fm" => (1, 8 | 4),
1706 "F#m" | "Gbm" => (1, 3),
1707 "Gm" => (1, 8 | 2),
1708 _ => {
1709 (0, 0) }
1711 }
1712}
1713
1714fn get_chord_name_from_mi_sf(mi: u8, sf: u8) -> String {
1715 let map = vec![
1716 vec![
1717 "Cb", "Gb", "Db", "Ab",
1718 "Eb", "Bb", "F",
1719 "C", "G", "D", "A",
1720 "E", "B", "F#", "C#",
1721 ],
1722 vec![
1723 "Abm", "Ebm", "Bbm", "Fm",
1724 "Cm", "Gm", "Dm",
1725 "Am", "Em", "Bm", "F#m",
1726 "C#m", "G#m", "D#m", "A#m",
1727 ]
1728 ];
1729
1730 map[mi as usize][((sf as i8) + 7) as usize].to_string()
1731}