apres/
lib.rs

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    // Note: Tempo Stored in u32 but is a 3 byte value
36	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            //TODO: Figure out what ff/fr are, u16 for now
249            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); // Data length is limited to 1 byte
265                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 } // Error
686                };
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                        // Convert fake NoteOff (NoteOn where velocity is 0) to real NoteOff
760                        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                // System Exclusive
1033                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                // Song Position Pointer
1049                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); // Meta Type
1065                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                // Do Nothing. These are system-realtime and shouldn't be in a file.
1192            }
1193
1194            0xF4 | 0xF5 | 0xF9 | 0xFD => {
1195                // Undefined Behaviour
1196            }
1197        }
1198
1199        output
1200    }
1201}
1202
1203/// Structural representation of MIDI.
1204///
1205/// Can represent a file or a real-time performance.
1206///
1207/// # Examples
1208/// Load a Song
1209/// ```
1210/// use apres::MIDI;
1211/// // Create a MIDI from a file
1212/// match MIDI::from_path("/path/to/file.mid") {
1213///     Ok(midi) => {
1214///     }
1215///     Err(_) => {
1216///     }
1217///}
1218/// ```
1219/// Create a new MIDI
1220/// ```
1221/// use apres::MIDI;
1222/// // Create an empty MIDI file.
1223/// let midi = MIDI::new();
1224/// ```
1225/// Creating a song
1226/// ```
1227/// use apres::MIDI;
1228/// use apres::MIDIEvent::{NoteOff, NoteOn};
1229/// // Create an empty MIDI file.
1230/// let mut midi = MIDI::new();
1231///
1232/// // Press midi note 64 (Middle E) on the first track (0) at the first position (0 ticks)
1233/// midi.insert_event(0, 0, NoteOn(64, 100, 100));
1234///
1235/// // Release midi note 64 (Middle E) on the first track (0) one beat later (120 ticks)
1236/// midi.push_event(0, 120, NoteOn(64, 100, 100));
1237///
1238/// // Save it to a file
1239/// midi.save("beep.mid");
1240/// ```
1241#[derive(Debug)]
1242pub struct MIDI {
1243    ppqn: u16,
1244    midi_format: u16, // 16 because the format stores in 2 bytes, even though it only requires 2 bits (0,1,2)
1245    events: HashMap<u64, MIDIEvent>,
1246    event_id_gen: u64,
1247    event_positions: HashMap<u64, (usize, usize)>,
1248
1249    _active_byte: u8 // Only used when reading in a .mid
1250}
1251
1252
1253impl MIDI {
1254    /// Construct a new, empty MIDI
1255    pub fn new() -> MIDI {
1256        MIDI {
1257            event_id_gen: 1, // Reserve 0 for passing 'none' to bindings
1258            ppqn: 120,
1259            midi_format: 1,
1260            events: HashMap::new(),
1261            event_positions: HashMap::new(),
1262            _active_byte: 0x90
1263        }
1264    }
1265
1266    /// Construct a new MIDI from a .mid file
1267    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        //        Err(ApresError::InvalidMIDIFile(file_path.to_string()))
1298            }
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        // TODO: These Probably don't need to be 32
1314        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); // Get Size
1337                midi_format = dequeue_n(bytes, 2) as u16; // Midi Format
1338                dequeue_n(bytes, 2); // Get Number of tracks
1339                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        // First 8  bytes will always be the same
1408        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        // Tracks (MTrk)
1423        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            // Automatically handle EndOfTrackEvent Here instead of requiring it be in the MIDITrack Object
1445            track_event_bytes.push(0);
1446            track_event_bytes.extend(MIDIEvent::EndOfTrack.as_bytes().iter().copied());
1447
1448            // track length in bytes
1449            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    /// Save the MIDI Object to a file
1462    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    /// Get the track and tick of an event, given its id
1474    pub fn get_event_position(&self, event_id: u64) -> Option<&(usize, usize)> {
1475        self.event_positions.get(&event_id)
1476    }
1477
1478    /// Get a list of tracks, each populated by lists of event ids.
1479    /// Each list in each track represents a 'tick', so it could be empty
1480    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    /// Set Pulses Per Quarter Note
1534    pub fn set_ppqn(&mut self, new_ppqn: u16) {
1535        self.ppqn = new_ppqn;
1536    }
1537
1538    /// Get Pulses Per Quarter Note
1539    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    /// Change the track or position of an event, given it id in the MIDI
1552    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    /// Insert an event into the track
1559    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    /// Insert an event after the latest event in the track
1571    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
1661// input a number between (-1, 1), get an unsigned value with 0x2000 as midpoint
1662pub 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) // Default to C
1710        }
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}