1use std::{
2 io::Cursor,
3 time::{Duration, Instant},
4};
5
6use midi_toolkit::{
7 events::Event,
8 io::{MIDIFile, MIDIWriter},
9 prelude::*,
10};
11
12fn do_run<T: Fn()>(name: &str, repeats: i32, run: T) {
13 let mut times = Vec::new();
14 for _ in 0..repeats {
15 let start = Instant::now();
16 run();
17 times.push(start.elapsed());
18 }
19
20 let mean = times.iter().map(|t| t.as_secs_f64()).sum::<f64>() / repeats as f64;
21
22 println!(
23 "Repeats: {} \tMin: {:?} \tMax: {:?} \tAvg: {:?} \tName: {}",
24 repeats,
25 times.iter().min().unwrap(),
26 times.iter().max().unwrap(),
27 Duration::from_secs_f64(mean),
28 name
29 );
30}
31
32fn main() {
33 let filename = "D:/Midis/Ra Ra Rasputin Ultimate Black MIDI Final.mid";
34 let repeats = 4;
35
36 println!("Opening midi...");
37 let file = MIDIFile::open(filename, None).unwrap();
38
39 println!("Tracks: {}", file.track_count());
40
41 let loaded_tracks = file
42 .iter_all_tracks()
43 .map(|t| t.collect_vec_result().unwrap())
44 .collect::<Vec<_>>();
45
46 let mut nc: u64 = 0;
47 for track in loaded_tracks.iter() {
48 for e in track {
49 if let Event::NoteOn(_) = **e {
50 nc += 1
51 }
52 }
53 }
54 println!("Note count: {nc}");
55
56 do_run("Parse all tracks individually", repeats, || {
57 for track in file.iter_all_tracks() {
58 for _ in track {}
59 }
60 });
61 do_run("Merge all tracks together while parsing", repeats, || {
62 let merged = file.iter_all_tracks().merge_all();
63 for _ in merged {}
64 });
65 do_run("Clone all events", repeats, || {
66 let iters = loaded_tracks.iter().map(|t| t.iter().cloned());
67 for track in iters {
68 for _ in track {}
69 }
70 });
71 do_run(
72 "Clone all events, then wrap and unwrap them in Result",
73 repeats,
74 || {
75 let iters = loaded_tracks
76 .iter()
77 .map(|t| t.iter().cloned().into_ok().unwrap_items());
78 for track in iters {
79 for _ in track {}
80 }
81 },
82 );
83 do_run("Merge all tracks together while cloning", repeats, || {
84 let iters = loaded_tracks
85 .iter()
86 .map(|t| t.iter().cloned().into_ok())
87 .collect::<Vec<_>>();
88 let merged = iters.into_iter().merge_all();
89 for _ in merged {}
90 });
91 do_run("Write each track while cloning", repeats, || {
92 let output = Cursor::new(Vec::<u8>::new());
93 let writer = MIDIWriter::new_from_stream(Box::new(output), file.ppq()).unwrap();
94
95 let iters = loaded_tracks.iter().map(|t| t.iter().cloned());
96 for track in iters {
97 let mut track_writer = writer.try_open_next_track().unwrap();
98 for e in track {
99 track_writer.write_event(e).unwrap();
100 }
101 }
102 });
103 do_run("Merge each track while cloning then write", repeats, || {
104 let output = Cursor::new(Vec::<u8>::new());
105 let writer = MIDIWriter::new_from_stream(Box::new(output), file.ppq()).unwrap();
106
107 let iters = loaded_tracks
108 .iter()
109 .map(|t| t.iter().cloned().into_ok())
110 .collect::<Vec<_>>();
111 let merged = iters.into_iter().merge_all().unwrap_items();
112 let mut track_writer = writer.try_open_next_track().unwrap();
113 for e in merged {
114 track_writer.write_event(e).unwrap();
115 }
116 });
117}