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