midi-toolkit-rs 0.3.1

A library for ultra high performance MIDI operations, designed for black MIDI. The library isn't perfect
Documentation
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();
    //     }
    // });
}