note_chopper/
note_chopper.rs1#![feature(coroutines)]
2
3use midi_toolkit::{
4 gen_iter,
5 io::{MIDIFile, MIDIWriter},
6 notes::{MIDINote, Note},
7 prelude::*,
8 sequence::event::merge_events,
9};
10
11fn chop_note(note: Note<u64>, chop_size: u64) -> impl Iterator<Item = Note<u64>> {
12 gen_iter!(move {
13 let mut pos = note.start;
14 while pos < note.end() {
15 let start = pos;
16 let end = (pos + chop_size).min(note.end());
17 yield Note {
18 channel: note.channel,
19 key: note.key,
20 velocity: note.velocity,
21 len: end - start,
22 start,
23 };
24 pos = end;
25 }
26 })
27}
28
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 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}