pub trait EventSequenceExt<D: MIDINum, E, Err>: Iterator<Item = Result<Delta<D, E>, Err>> + Sized {
// Provided methods
fn cast_event_delta<ND: MIDINum>(
self,
) -> impl Iterator<Item = Result<<Delta<D, E> as CastEventDelta<ND>>::Output, Err>>
where Delta<D, E>: CastEventDelta<ND> { ... }
fn scale_event_time(
self,
multiplier: D,
) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: MIDIDelta<D> { ... }
fn scale_event_ppq(
self,
from: D,
to: D,
) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: MIDIEvent + MIDIDelta<D> { ... }
fn filter_events(
self,
predicate: impl Fn(&Delta<D, E>) -> bool,
) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: MIDIEventEnum + MIDIDelta<D> { ... }
fn filter_map_events<NE>(
self,
mapper: impl FnMut(E) -> Option<NE>,
) -> impl Iterator<Item = Result<Delta<D, NE>, Err>> { ... }
fn filter_note_events(
self,
) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: MIDIEventEnum + MIDIDelta<D> { ... }
fn filter_non_note_events(
self,
) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: MIDIEventEnum + MIDIDelta<D> { ... }
fn cancel_tempo_events(
self,
new_tempo: u32,
) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: BatchTempo + MIDIDelta<D> { ... }
fn event_batches(
self,
) -> impl Iterator<Item = Result<Delta<D, EventBatch<E>>, Err>>
where Delta<D, E>: MIDIDelta<D> { ... }
fn into_track_events(
self,
track: u32,
) -> impl Iterator<Item = Result<Delta<D, Track<E>>, Err>> { ... }
fn events_to_notes(self) -> impl Iterator<Item = Result<Note<D>, Err>>
where E: MIDIEventEnum { ... }
fn channel_statistics(self) -> Result<ChannelStatistics<D>, Err>
where Delta<D, E>: MIDIEventEnum + MIDIDelta<D> { ... }
}Provided Methods§
Sourcefn cast_event_delta<ND: MIDINum>(
self,
) -> impl Iterator<Item = Result<<Delta<D, E> as CastEventDelta<ND>>::Output, Err>>where
Delta<D, E>: CastEventDelta<ND>,
fn cast_event_delta<ND: MIDINum>(
self,
) -> impl Iterator<Item = Result<<Delta<D, E> as CastEventDelta<ND>>::Output, Err>>where
Delta<D, E>: CastEventDelta<ND>,
Examples found in repository?
examples/nps_bench.rs (line 20)
9pub fn main() {
10 println!("Opening midi...");
11 let midi = MIDIFile::open_in_ram(
12 "/mnt/fat/Midis/Ra Ra Rasputin Ultimate Black MIDI Final.mid",
13 None,
14 )
15 .unwrap();
16
17 let ppq = midi.ppq();
18 let merged = midi
19 .iter_all_track_events_merged_batches()
20 .cast_event_delta::<f64>()
21 .cancel_tempo_events(250000)
22 .scale_event_time(1.0 / ppq as f64)
23 .unwrap_items();
24
25 println!("Tracks: {}", midi.track_count());
26
27 let start = Instant::now();
28 let mut note_count = 0;
29 for batch in merged {
30 for e in batch.iter_events() {
31 if let Event::NoteOn(_) = e.as_event() {
32 note_count += 1;
33 }
34 }
35 }
36
37 println!("Note count: {} \tTime: {:?}", note_count, start.elapsed());
38 println!(
39 "Notes per second: {}",
40 note_count as f64 / start.elapsed().as_secs_f64()
41 );
42}More examples
examples/parse_benchmark.rs (line 54)
31fn main() {
32 let filename = "D:/Midis/toilet story 3 2020 ver 3840 black with tempo.mid";
33 let repeats = 4;
34
35 println!("Opening midi...");
36 let file = MIDIFile::open(filename, None).unwrap();
37
38 println!("Tracks: {}", file.track_count());
39
40 // Make windows cache stuff
41 let stats = file.iter_all_tracks().channel_statistics().unwrap();
42
43 println!("Note count: {}", stats.note_count());
44
45 do_run("Parse tracks in parallel", repeats, || {
46 let stats = file.iter_all_tracks().channel_statistics().unwrap();
47 stats.note_count()
48 });
49
50 do_run("Iter event batches merged", repeats, || {
51 let ppq = file.ppq();
52 let merged = file
53 .iter_all_track_events_merged_batches()
54 .cast_event_delta::<f64>()
55 .cancel_tempo_events(250000)
56 .scale_event_time(1.0 / ppq as f64)
57 .unwrap_items();
58
59 let mut note_count = 0;
60 for batch in merged {
61 for e in batch.into_iter() {
62 if let Event::NoteOn(_) = e.as_event() {
63 note_count += 1
64 }
65 }
66 }
67
68 note_count
69 });
70
71 // do_run("Merge all tracks together while parsing", repeats, || {
72 // let merged = pipe!(file.iter_all_tracks()|>to_vec()|>merge_events_array());
73 // for _ in merged {}
74 // });
75 // do_run("Clone all events", repeats, || {
76 // let iters = pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned())));
77 // for track in iters {
78 // for _ in track {}
79 // }
80 // });
81 // do_run(
82 // "Clone all events, then wrap and unwrap them in Result",
83 // repeats,
84 // || {
85 // let iters = pipe!(loaded_tracks
86 // .iter()
87 // .map(|t| pipe!(t.iter().cloned()|>wrap_ok()|>unwrap_items())));
88 // for track in iters {
89 // for _ in track {}
90 // }
91 // },
92 // );
93 // do_run("Merge all tracks together while cloning", repeats, || {
94 // let iters =
95 // pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned()|>wrap_ok()))|>to_vec());
96 // let merged = pipe!(iters|>merge_events_array());
97 // for _ in merged {}
98 // });
99 // do_run("Write each track while cloning", repeats, || {
100 // let output = Cursor::new(Vec::<u8>::new());
101 // let writer = MIDIWriter::new_from_stream(Box::new(output), file.ppq()).unwrap();
102
103 // let iters = pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned())));
104 // for track in iters {
105 // let mut track_writer = writer.open_next_track();
106 // for e in track {
107 // track_writer.write_event(e).unwrap();
108 // }
109 // }
110 // });
111 // do_run("Merge each track while cloning then write", repeats, || {
112 // let output = Cursor::new(Vec::<u8>::new());
113 // let writer = MIDIWriter::new_from_stream(Box::new(output), file.ppq()).unwrap();
114
115 // let iters =
116 // pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned()|>wrap_ok()))|>to_vec());
117 // let merged = pipe!(iters|>merge_events_array()|>unwrap_items());
118 // let mut track_writer = writer.open_next_track();
119 // for e in merged {
120 // track_writer.write_event(e).unwrap();
121 // }
122 // });
123}Sourcefn scale_event_time(
self,
multiplier: D,
) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
fn scale_event_time( self, multiplier: D, ) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
Examples found in repository?
examples/nps_bench.rs (line 22)
9pub fn main() {
10 println!("Opening midi...");
11 let midi = MIDIFile::open_in_ram(
12 "/mnt/fat/Midis/Ra Ra Rasputin Ultimate Black MIDI Final.mid",
13 None,
14 )
15 .unwrap();
16
17 let ppq = midi.ppq();
18 let merged = midi
19 .iter_all_track_events_merged_batches()
20 .cast_event_delta::<f64>()
21 .cancel_tempo_events(250000)
22 .scale_event_time(1.0 / ppq as f64)
23 .unwrap_items();
24
25 println!("Tracks: {}", midi.track_count());
26
27 let start = Instant::now();
28 let mut note_count = 0;
29 for batch in merged {
30 for e in batch.iter_events() {
31 if let Event::NoteOn(_) = e.as_event() {
32 note_count += 1;
33 }
34 }
35 }
36
37 println!("Note count: {} \tTime: {:?}", note_count, start.elapsed());
38 println!(
39 "Notes per second: {}",
40 note_count as f64 / start.elapsed().as_secs_f64()
41 );
42}More examples
examples/parse_benchmark.rs (line 56)
31fn main() {
32 let filename = "D:/Midis/toilet story 3 2020 ver 3840 black with tempo.mid";
33 let repeats = 4;
34
35 println!("Opening midi...");
36 let file = MIDIFile::open(filename, None).unwrap();
37
38 println!("Tracks: {}", file.track_count());
39
40 // Make windows cache stuff
41 let stats = file.iter_all_tracks().channel_statistics().unwrap();
42
43 println!("Note count: {}", stats.note_count());
44
45 do_run("Parse tracks in parallel", repeats, || {
46 let stats = file.iter_all_tracks().channel_statistics().unwrap();
47 stats.note_count()
48 });
49
50 do_run("Iter event batches merged", repeats, || {
51 let ppq = file.ppq();
52 let merged = file
53 .iter_all_track_events_merged_batches()
54 .cast_event_delta::<f64>()
55 .cancel_tempo_events(250000)
56 .scale_event_time(1.0 / ppq as f64)
57 .unwrap_items();
58
59 let mut note_count = 0;
60 for batch in merged {
61 for e in batch.into_iter() {
62 if let Event::NoteOn(_) = e.as_event() {
63 note_count += 1
64 }
65 }
66 }
67
68 note_count
69 });
70
71 // do_run("Merge all tracks together while parsing", repeats, || {
72 // let merged = pipe!(file.iter_all_tracks()|>to_vec()|>merge_events_array());
73 // for _ in merged {}
74 // });
75 // do_run("Clone all events", repeats, || {
76 // let iters = pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned())));
77 // for track in iters {
78 // for _ in track {}
79 // }
80 // });
81 // do_run(
82 // "Clone all events, then wrap and unwrap them in Result",
83 // repeats,
84 // || {
85 // let iters = pipe!(loaded_tracks
86 // .iter()
87 // .map(|t| pipe!(t.iter().cloned()|>wrap_ok()|>unwrap_items())));
88 // for track in iters {
89 // for _ in track {}
90 // }
91 // },
92 // );
93 // do_run("Merge all tracks together while cloning", repeats, || {
94 // let iters =
95 // pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned()|>wrap_ok()))|>to_vec());
96 // let merged = pipe!(iters|>merge_events_array());
97 // for _ in merged {}
98 // });
99 // do_run("Write each track while cloning", repeats, || {
100 // let output = Cursor::new(Vec::<u8>::new());
101 // let writer = MIDIWriter::new_from_stream(Box::new(output), file.ppq()).unwrap();
102
103 // let iters = pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned())));
104 // for track in iters {
105 // let mut track_writer = writer.open_next_track();
106 // for e in track {
107 // track_writer.write_event(e).unwrap();
108 // }
109 // }
110 // });
111 // do_run("Merge each track while cloning then write", repeats, || {
112 // let output = Cursor::new(Vec::<u8>::new());
113 // let writer = MIDIWriter::new_from_stream(Box::new(output), file.ppq()).unwrap();
114
115 // let iters =
116 // pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned()|>wrap_ok()))|>to_vec());
117 // let merged = pipe!(iters|>merge_events_array()|>unwrap_items());
118 // let mut track_writer = writer.open_next_track();
119 // for e in merged {
120 // track_writer.write_event(e).unwrap();
121 // }
122 // });
123}fn scale_event_ppq( self, from: D, to: D, ) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
fn filter_events( self, predicate: impl Fn(&Delta<D, E>) -> bool, ) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
fn filter_map_events<NE>( self, mapper: impl FnMut(E) -> Option<NE>, ) -> impl Iterator<Item = Result<Delta<D, NE>, Err>>
fn filter_note_events(self) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
Sourcefn filter_non_note_events(
self,
) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
fn filter_non_note_events( self, ) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
Examples found in repository?
examples/note_chopper.rs (line 41)
29fn main() {
30 let file = MIDIFile::open("D:/Midis/tau2.5.9.mid", None).unwrap();
31
32 let chop_size = file.ppq() as u64 / 16;
33
34 let writer = MIDIWriter::new("./out.mid", file.ppq()).unwrap();
35
36 for (i, track) in file.iter_all_tracks().enumerate() {
37 println!("Chopping track {} of {}", i, file.track_count());
38
39 let cached = track.collect_vec_result().unwrap();
40
41 let non_note_events = cached.iter().cloned().into_ok().filter_non_note_events();
42
43 let notes = cached
44 .iter()
45 .cloned()
46 .into_ok()
47 .events_to_notes()
48 .unwrap_items();
49 let chopped = notes.map(|n| chop_note(n, chop_size).into_ok());
50 let flattened = chopped.merge_all().notes_to_events();
51
52 // let notes = pipe!(cached.iter().cloned()|>wrap_ok()|>events_to_notes()|>unwrap_items());
53 // let flattened = pipe!(notes|>wrap_ok()|>notes_to_events());
54
55 let merged = merge_events(flattened, non_note_events);
56
57 writer
58 .try_open_next_track()
59 .unwrap()
60 .write_events_iter(merged.unwrap_items())
61 .unwrap();
62 }
63}Sourcefn cancel_tempo_events(
self,
new_tempo: u32,
) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
fn cancel_tempo_events( self, new_tempo: u32, ) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
Examples found in repository?
examples/nps_bench.rs (line 21)
9pub fn main() {
10 println!("Opening midi...");
11 let midi = MIDIFile::open_in_ram(
12 "/mnt/fat/Midis/Ra Ra Rasputin Ultimate Black MIDI Final.mid",
13 None,
14 )
15 .unwrap();
16
17 let ppq = midi.ppq();
18 let merged = midi
19 .iter_all_track_events_merged_batches()
20 .cast_event_delta::<f64>()
21 .cancel_tempo_events(250000)
22 .scale_event_time(1.0 / ppq as f64)
23 .unwrap_items();
24
25 println!("Tracks: {}", midi.track_count());
26
27 let start = Instant::now();
28 let mut note_count = 0;
29 for batch in merged {
30 for e in batch.iter_events() {
31 if let Event::NoteOn(_) = e.as_event() {
32 note_count += 1;
33 }
34 }
35 }
36
37 println!("Note count: {} \tTime: {:?}", note_count, start.elapsed());
38 println!(
39 "Notes per second: {}",
40 note_count as f64 / start.elapsed().as_secs_f64()
41 );
42}More examples
examples/parse_benchmark.rs (line 55)
31fn main() {
32 let filename = "D:/Midis/toilet story 3 2020 ver 3840 black with tempo.mid";
33 let repeats = 4;
34
35 println!("Opening midi...");
36 let file = MIDIFile::open(filename, None).unwrap();
37
38 println!("Tracks: {}", file.track_count());
39
40 // Make windows cache stuff
41 let stats = file.iter_all_tracks().channel_statistics().unwrap();
42
43 println!("Note count: {}", stats.note_count());
44
45 do_run("Parse tracks in parallel", repeats, || {
46 let stats = file.iter_all_tracks().channel_statistics().unwrap();
47 stats.note_count()
48 });
49
50 do_run("Iter event batches merged", repeats, || {
51 let ppq = file.ppq();
52 let merged = file
53 .iter_all_track_events_merged_batches()
54 .cast_event_delta::<f64>()
55 .cancel_tempo_events(250000)
56 .scale_event_time(1.0 / ppq as f64)
57 .unwrap_items();
58
59 let mut note_count = 0;
60 for batch in merged {
61 for e in batch.into_iter() {
62 if let Event::NoteOn(_) = e.as_event() {
63 note_count += 1
64 }
65 }
66 }
67
68 note_count
69 });
70
71 // do_run("Merge all tracks together while parsing", repeats, || {
72 // let merged = pipe!(file.iter_all_tracks()|>to_vec()|>merge_events_array());
73 // for _ in merged {}
74 // });
75 // do_run("Clone all events", repeats, || {
76 // let iters = pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned())));
77 // for track in iters {
78 // for _ in track {}
79 // }
80 // });
81 // do_run(
82 // "Clone all events, then wrap and unwrap them in Result",
83 // repeats,
84 // || {
85 // let iters = pipe!(loaded_tracks
86 // .iter()
87 // .map(|t| pipe!(t.iter().cloned()|>wrap_ok()|>unwrap_items())));
88 // for track in iters {
89 // for _ in track {}
90 // }
91 // },
92 // );
93 // do_run("Merge all tracks together while cloning", repeats, || {
94 // let iters =
95 // pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned()|>wrap_ok()))|>to_vec());
96 // let merged = pipe!(iters|>merge_events_array());
97 // for _ in merged {}
98 // });
99 // do_run("Write each track while cloning", repeats, || {
100 // let output = Cursor::new(Vec::<u8>::new());
101 // let writer = MIDIWriter::new_from_stream(Box::new(output), file.ppq()).unwrap();
102
103 // let iters = pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned())));
104 // for track in iters {
105 // let mut track_writer = writer.open_next_track();
106 // for e in track {
107 // track_writer.write_event(e).unwrap();
108 // }
109 // }
110 // });
111 // do_run("Merge each track while cloning then write", repeats, || {
112 // let output = Cursor::new(Vec::<u8>::new());
113 // let writer = MIDIWriter::new_from_stream(Box::new(output), file.ppq()).unwrap();
114
115 // let iters =
116 // pipe!(loaded_tracks.iter().map(|t| pipe!(t.iter().cloned()|>wrap_ok()))|>to_vec());
117 // let merged = pipe!(iters|>merge_events_array()|>unwrap_items());
118 // let mut track_writer = writer.open_next_track();
119 // for e in merged {
120 // track_writer.write_event(e).unwrap();
121 // }
122 // });
123}fn event_batches( self, ) -> impl Iterator<Item = Result<Delta<D, EventBatch<E>>, Err>>
fn into_track_events( self, track: u32, ) -> impl Iterator<Item = Result<Delta<D, Track<E>>, Err>>
Sourcefn events_to_notes(self) -> impl Iterator<Item = Result<Note<D>, Err>>where
E: MIDIEventEnum,
fn events_to_notes(self) -> impl Iterator<Item = Result<Note<D>, Err>>where
E: MIDIEventEnum,
Examples found in repository?
examples/note_chopper.rs (line 47)
29fn main() {
30 let file = MIDIFile::open("D:/Midis/tau2.5.9.mid", None).unwrap();
31
32 let chop_size = file.ppq() as u64 / 16;
33
34 let writer = MIDIWriter::new("./out.mid", file.ppq()).unwrap();
35
36 for (i, track) in file.iter_all_tracks().enumerate() {
37 println!("Chopping track {} of {}", i, file.track_count());
38
39 let cached = track.collect_vec_result().unwrap();
40
41 let non_note_events = cached.iter().cloned().into_ok().filter_non_note_events();
42
43 let notes = cached
44 .iter()
45 .cloned()
46 .into_ok()
47 .events_to_notes()
48 .unwrap_items();
49 let chopped = notes.map(|n| chop_note(n, chop_size).into_ok());
50 let flattened = chopped.merge_all().notes_to_events();
51
52 // let notes = pipe!(cached.iter().cloned()|>wrap_ok()|>events_to_notes()|>unwrap_items());
53 // let flattened = pipe!(notes|>wrap_ok()|>notes_to_events());
54
55 let merged = merge_events(flattened, non_note_events);
56
57 writer
58 .try_open_next_track()
59 .unwrap()
60 .write_events_iter(merged.unwrap_items())
61 .unwrap();
62 }
63}Sourcefn channel_statistics(self) -> Result<ChannelStatistics<D>, Err>
fn channel_statistics(self) -> Result<ChannelStatistics<D>, Err>
Examples found in repository?
examples/statistics.rs (line 22)
13fn main() {
14 println!("Opening midi...");
15 let file = MIDIFile::open_in_ram("D:/Midis/tau2.5.9.mid", None).unwrap();
16 println!("Parsing midi...");
17
18 let now = Instant::now();
19 let stats1 = file
20 .iter_all_tracks()
21 .merge_all()
22 .channel_statistics()
23 .unwrap();
24
25 println!("Calculated merged stats in {:?}", now.elapsed());
26 println!(
27 "MIDI length: {}",
28 duration_to_minutes_seconds(stats1.calculate_total_duration(file.ppq()))
29 );
30 println!("Other stats: {stats1:#?}\n\n");
31
32 let now = Instant::now();
33 let stats2 = file.iter_all_tracks().channel_statistics().unwrap();
34 println!("Calculated multithreaded stats in {:?}", now.elapsed());
35 println!(
36 "MIDI length: {}",
37 duration_to_minutes_seconds(stats2.calculate_total_duration(file.ppq()))
38 );
39 println!("Other stats: {stats2:#?}");
40}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.