fn build_midi_input_blocks(
    settings: &AudioProcessorSettings,
    total_blocks: usize,
    midi_input_file: MIDIFile<String, Vec<u8>>,
) -> Vec<Vec<MIDIBytes>> {
    let tempo = 120_f32;
    let ticks_per_quarter_note = midi_input_file.ticks_per_quarter_note() as f32;
    let chunks = midi_input_file.chunks;
    let track_events: Vec<MIDITrackEvent<Vec<u8>>> = chunks
        .into_iter()
        .filter_map(|chunk| match chunk {
            MIDIFileChunk::Track { events } => {
                let events = convert_to_absolute_time(events);
                Some(events)
            }
            _ => None,
        })
        .flatten()
        .sorted_by_key(|event| event.delta_time)
        .collect();
    let mut track_events_position = 0;
    let mut result = Vec::with_capacity(total_blocks);
    let block_size = settings.block_size as f32;
    let inverse_sample_rate = 1.0 / settings.sample_rate;

    for i in 0..total_blocks {
        let delta_time_ticks = get_delta_time_ticks(
            tempo,
            ticks_per_quarter_note,
            block_size,
            inverse_sample_rate,
            i,
        );

        log::debug!(
            "Block - {} - ticks_per_beat={} - ticks={} input_len={} dt={}",
            i,
            ticks_per_quarter_note,
            delta_time_ticks,
            track_events.len(),
            track_events[track_events_position].delta_time
        );

        let midi_track_events: Vec<&MIDITrackEvent<Vec<u8>>> = track_events
            .iter()
            .skip(track_events_position)
            .filter(|event| event.delta_time <= delta_time_ticks as u32)
            .collect();

        let midi_block: Vec<MIDIBytes> = midi_track_events
            .iter()
            .filter_map(|event| {
                log::debug!("Filtering MIDI event {:?}", event);
                if let MIDITrackInner::Message(inner) = &event.inner {
                    Some(inner)
                } else {
                    None
                }
            })
            .filter_map(|event| match event {
                MIDIMessage::NoteOn(MIDIMessageNote { velocity, note, .. }) => Some(MIDIBytes {
                    bytes: vec![0x90, *note, *velocity],
                }),
                MIDIMessage::NoteOff(MIDIMessageNote { velocity, note, .. }) => Some(MIDIBytes {
                    bytes: vec![0x80, *note, *velocity],
                }),
                _ => None,
            })
            .collect();

        track_events_position += midi_track_events.len();
        result.push(midi_block);
    }

    result
}
/// Builds chunks containing MIDI messages over each block, aligned with their
/// timing and a 120bpm tempo.
Builds chunks containing MIDI messages over each block, aligned with their
timing and a 120bpm tempo.
Builds chunks containing MIDI messages over each block aligned with their timing and a 120bpm tempo .
fn build_midi_input_blocks(
    settings: &AudioProcessorSettings,
    total_blocks: usize,
    midi_input_file: MIDIFile<String, Vec<u8>>,
) -> Vec<Vec<MIDIBytes>> {
    let tempo = 120_f32;
    let ticks_per_quarter_note = midi_input_file.ticks_per_quarter_note() as f32;
    let chunks = midi_input_file.chunks;
    let track_events: Vec<MIDITrackEvent<Vec<u8>>> = chunks
        .into_iter()
        .filter_map(|chunk| match chunk {
            MIDIFileChunk::Track { events } => {
                let events = convert_to_absolute_time(events);
                Some(events)
            }
            _ => None,
        })
        .flatten()
        .sorted_by_key(|event| event.delta_time)
        .collect();
    let mut track_events_position = 0;
    let mut result = Vec::with_capacity(total_blocks);
    let block_size = settings.block_size as f32;
    let inverse_sample_rate = 1.0 / settings.sample_rate;
    for i in 0..total_blocks {
        let delta_time_ticks = get_delta_time_ticks(
            tempo,
            ticks_per_quarter_note,
            block_size,
            inverse_sample_rate,
            i,
        );
        log::debug!(
            "Block - {} - ticks_per_beat={} - ticks={} input_len={} dt={}",
            i,
            ticks_per_quarter_note,
            delta_time_ticks,
            track_events.len(),
            track_events[track_events_position].delta_time
        );
        let midi_track_events: Vec<&MIDITrackEvent<Vec<u8>>> = track_events
            .iter()
            .skip(track_events_position)
            .filter(|event| event.delta_time <= delta_time_ticks as u32)
            .collect();
        let midi_block: Vec<MIDIBytes> = midi_track_events
            .iter()
            .filter_map(|event| {
                log::debug!("Filtering MIDI event {:?}", event);
                if let MIDITrackInner::Message(inner) = &event.inner {
                    Some(inner)
                } else {
                    None
                }
            })
            .filter_map(|event| match event {
                MIDIMessage::NoteOn(MIDIMessageNote { velocity, note, .. }) => Some(MIDIBytes {
                    bytes: vec![0x90, *note, *velocity],
                }),
                MIDIMessage::NoteOff(MIDIMessageNote { velocity, note, .. }) => Some(MIDIBytes {
                    bytes: vec![0x80, *note, *velocity],
                }),
                _ => None,
            })
            .collect();
        track_events_position += midi_track_events.len();
        result.push(midi_block);
    }
    result
}
fn build_midi_input_blocks ( settings : & AudioProcessorSettings , total_blocks : usize , midi_input_file : MIDIFile < String , Vec < u8 > > , ) -> Vec < Vec < MIDIBytes > > { let tempo = 120_f32 ; let ticks_per_quarter_note = midi_input_file . ticks_per_quarter_note ( ) as f32 ; let chunks = midi_input_file . chunks ; let track_events : Vec < MIDITrackEvent < Vec < u8 > > > = chunks . into_iter ( ) . filter_map ( | chunk | match chunk { MIDIFileChunk :: Track { events } => { let events = convert_to_absolute_time ( events ) ; Some ( events ) } _ => None , } ) . flatten ( ) . sorted_by_key ( | event | event . delta_time ) . collect ( ) ; let mut track_events_position = 0 ; let mut result = Vec :: with_capacity ( total_blocks ) ; let block_size = settings . block_size as f32 ; let inverse_sample_rate = 1.0 / settings . sample_rate ; for i in 0 .. total_blocks { let delta_time_ticks = get_delta_time_ticks ( tempo , ticks_per_quarter_note , block_size , inverse_sample_rate , i , ) ; log :: debug ! ( " " i ticks_per_quarter_note delta_time_ticks track_events len ( ) track_events [ track_events_position ] delta_time ) ; let midi_track_events : Vec < & MIDITrackEvent < Vec < u8 > > > = track_events . iter ( ) . skip ( track_events_position ) . filter ( | event | event . delta_time <= delta_time_ticks as u32 ) . collect ( ) ; let midi_block : Vec < MIDIBytes > = midi_track_events . iter ( ) . filter_map ( | event | { log :: debug ! ( " " event ) ; if let MIDITrackInner :: Message ( inner ) = & event . inner { Some ( inner ) } else { None } } ) . filter_map ( | event | match event { MIDIMessage :: NoteOn ( MIDIMessageNote { velocity , note , .. } ) => Some ( MIDIBytes { bytes : vec ! [ 0x90 note velocity ] , } ) , MIDIMessage :: NoteOff ( MIDIMessageNote { velocity , note , .. } ) => Some ( MIDIBytes { bytes : vec ! [ 0x80 note velocity ] , } ) , _ => None , } ) . collect ( ) ; track_events_position += midi_track_events . len ( ) ; result . push ( midi_block ) ; } result }
Builds chunks containing MIDI messages over each block, aligned with their
timing and a 120bpm tempo.
Builds chunks containing MIDI messages over each block aligned with their timing and a 120bpm tempo .
settings
&AudioProcessorSettings
total_blocks
usize
midi_input_file
MIDIFile<String, Vec<u8>>
settings
&AudioProcessorSettings
total_blocks
usize
midi_input_file
MIDIFile<String, Vec<u8>>