perf: use Vec instead of BTreeMap in Phrase

This commit is contained in:
🪞👃🪞 2024-07-11 16:53:15 +03:00
parent db25099268
commit 4a8f5b267f
7 changed files with 150 additions and 221 deletions

View file

@ -11,6 +11,8 @@ use crate::{core::*, model::App};
}}
}
pub type PhraseData = Vec<Vec<MidiMessage>>;
#[derive(Debug)]
pub struct Phrase {
pub name: String,
@ -30,13 +32,20 @@ impl Phrase {
Self {
name: name.to_string(),
length,
notes: notes.unwrap_or(BTreeMap::new()),
notes: notes.unwrap_or(vec![Vec::with_capacity(16);length]),
looped: Some((0, length))
}
}
pub fn record_event (&mut self, pulse: usize, message: MidiMessage) {
if pulse >= self.length {
panic!("extend phrase first")
}
self.notes[pulse].push(message);
}
/// Check if a range `start..end` contains MIDI Note On `k`
pub fn contains_note_on (&self, k: u7, start: usize, end: usize) -> bool {
for (_, (_, events)) in self.notes.range(start..end).enumerate() {
//panic!("{:?} {start} {end}", &self);
for events in self.notes[start.max(0)..end.min(self.notes.len())].iter() {
for event in events.iter() {
match event {
MidiMessage::NoteOn {key,..} => {
@ -63,31 +72,20 @@ impl Phrase {
frame0, frame0 + frames
) {
let tick = tick % self.length;
if let Some(events) = self.notes.get(&(tick as usize)) {
for message in events.iter() {
buf.clear();
let channel = 0.into();
let message = *message;
LiveEvent::Midi { channel, message }.write(&mut buf).unwrap();
output[time as usize].push(buf.clone());
match message {
MidiMessage::NoteOn { key, .. } => notes_on[key.as_int() as usize] = true,
MidiMessage::NoteOff { key, .. } => notes_on[key.as_int() as usize] = false,
_ => {}
}
for message in self.notes[tick].iter() {
buf.clear();
let channel = 0.into();
let message = *message;
LiveEvent::Midi { channel, message }.write(&mut buf).unwrap();
output[time as usize].push(buf.clone());
match message {
MidiMessage::NoteOn { key, .. } => notes_on[key.as_int() as usize] = true,
MidiMessage::NoteOff { key, .. } => notes_on[key.as_int() as usize] = false,
_ => {}
}
}
}
}
pub fn record_event (&mut self, pulse: usize, message: MidiMessage) {
let contains = self.notes.contains_key(&pulse);
if contains {
self.notes.get_mut(&pulse).unwrap().push(message.clone());
} else {
self.notes.insert(pulse, vec![message.clone()]);
}
}
}
impl App {