Skip to main content

EventSequenceExt

Trait EventSequenceExt 

Source
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§

Source

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
Hide additional 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}
Source

fn scale_event_time( self, multiplier: D, ) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: MIDIDelta<D>,

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
Hide additional 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}
Source

fn scale_event_ppq( self, from: D, to: D, ) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: MIDIEvent + MIDIDelta<D>,

Source

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>,

Source

fn filter_map_events<NE>( self, mapper: impl FnMut(E) -> Option<NE>, ) -> impl Iterator<Item = Result<Delta<D, NE>, Err>>

Source

fn filter_note_events(self) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: MIDIEventEnum + MIDIDelta<D>,

Source

fn filter_non_note_events( self, ) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: MIDIEventEnum + MIDIDelta<D>,

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}
Source

fn cancel_tempo_events( self, new_tempo: u32, ) -> impl Iterator<Item = Result<Delta<D, E>, Err>>
where Delta<D, E>: BatchTempo + MIDIDelta<D>,

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
Hide additional 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}
Source

fn event_batches( self, ) -> impl Iterator<Item = Result<Delta<D, EventBatch<E>>, Err>>
where Delta<D, E>: MIDIDelta<D>,

Source

fn into_track_events( self, track: u32, ) -> impl Iterator<Item = Result<Delta<D, Track<E>>, Err>>

Source

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}
Source

fn channel_statistics(self) -> Result<ChannelStatistics<D>, Err>
where Delta<D, E>: MIDIEventEnum + MIDIDelta<D>,

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.

Implementors§

Source§

impl<D: MIDINum, E, Err, I> EventSequenceExt<D, E, Err> for I
where I: Iterator<Item = Result<Delta<D, E>, Err>> + Sized,