use crate::core::*; pub type MIDIMessage = Vec; pub type MIDIChunk = [Vec]; /// Add "all notes off" to the start of a buffer. pub fn all_notes_off (output: &mut MIDIChunk) { let mut buf = vec![]; let msg = MidiMessage::Controller { controller: 123.into(), value: 0.into() }; let evt = LiveEvent::Midi { channel: 0.into(), message: msg }; evt.write(&mut buf).unwrap(); output[0].push(buf); } pub fn parse_midi_input (input: MidiIter) -> Box + '_> { Box::new(input.map(|RawMidi { time, bytes }|( time as usize, LiveEvent::parse(bytes).unwrap(), bytes ))) } /// Write to JACK port from output buffer (containing notes from sequence and/or monitor) pub fn write_midi_output (writer: &mut ::jack::MidiWriter, output: &MIDIChunk, frames: usize) { for time in 0..frames { for event in output[time].iter() { writer.write(&::jack::RawMidi { time: time as u32, bytes: &event }) .expect(&format!("{event:?}")); } } } /// (pulses, name) pub const NOTE_DURATIONS: [(u16, &str);26] = [ (1, "1/384"), (2, "1/192"), (3, "1/128"), (4, "1/96"), (6, "1/64"), (8, "1/48"), (12, "1/32"), (16, "1/24"), (24, "1/16"), (32, "1/12"), (48, "1/8"), (64, "1/6"), (96, "1/4"), (128, "1/3"), (192, "1/2"), (256, "2/3"), (384, "1/1"), (512, "4/3"), (576, "3/2"), (768, "2/1"), (1152, "3/1"), (1536, "4/1"), (2304, "6/1"), (3072, "8/1"), (3456, "9/1"), (6144, "16/1"), ]; pub fn prev_note_length (ppq: u16) -> u16 { for i in 1..=16 { let length = NOTE_DURATIONS[16-i].0; if length < ppq { return length } } ppq } pub fn next_note_length (ppq: u16) -> u16 { for (length, _) in &NOTE_DURATIONS { if *length > ppq { return *length } } ppq } pub fn ppq_to_name (ppq: u16) -> &'static str { for (length, name) in &NOTE_DURATIONS { if *length == ppq { return name } } "" }