mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
refactor: contains_note_on
This commit is contained in:
parent
edadfde1a4
commit
f5da2e6dad
4 changed files with 42 additions and 46 deletions
|
|
@ -123,8 +123,8 @@ pub fn lanes (
|
|||
let note_a = note0 + index as usize * 2;
|
||||
let note_b = note0 + index as usize * 2 + 1;
|
||||
let (character, style) = match (
|
||||
contains_note_on(phrase, u7::from_int_lossy(note_a as u8), a, b),
|
||||
contains_note_on(phrase, u7::from_int_lossy(note_b as u8), a, b),
|
||||
phrase.contains_note_on(u7::from_int_lossy(note_a as u8), a, b),
|
||||
phrase.contains_note_on(u7::from_int_lossy(note_b as u8), a, b),
|
||||
) {
|
||||
(true, true) => ("█", wh),
|
||||
(false, true) => ("▄", wh),
|
||||
|
|
|
|||
|
|
@ -86,20 +86,13 @@ impl Sequencer {
|
|||
}
|
||||
|
||||
pub fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
||||
// Get currently playing phrase
|
||||
if self.sequence.is_none() {
|
||||
return Control::Continue
|
||||
}
|
||||
if self.sequence.is_none() { return Control::Continue }
|
||||
let phrase = self.phrases.get_mut(self.sequence.unwrap());
|
||||
if phrase.is_none() {
|
||||
return Control::Continue
|
||||
}
|
||||
if phrase.is_none() { return Control::Continue }
|
||||
let phrase = phrase.unwrap();
|
||||
// Prepare output buffer and transport
|
||||
let frame = scope.last_frame_time() as usize;//transport.pos.frame() as usize;
|
||||
let frame = scope.last_frame_time() as usize;
|
||||
let frames = scope.n_frames() as usize;
|
||||
let mut output: Vec<Option<Vec<Vec<u8>>>> = vec![None;frames];
|
||||
// Check transport self. If starting or stopping, send "all notes off":
|
||||
let transport = self.transport.query().unwrap();
|
||||
if transport.state != self.playing {
|
||||
all_notes_off(&mut output);
|
||||
|
|
@ -124,22 +117,11 @@ impl Sequencer {
|
|||
&self.timebase,
|
||||
frame,
|
||||
);
|
||||
// Write to port from output buffer
|
||||
// (containing notes from sequence and/or monitor)
|
||||
let mut writer = self.midi_out.writer(scope);
|
||||
for time in 0..scope.n_frames() {
|
||||
if let Some(Some(frame)) = output.get_mut(time as usize) {
|
||||
for event in frame.iter() {
|
||||
writer.write(&::jack::RawMidi { time, bytes: &event })
|
||||
.expect(&format!("{event:?}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
write_output(&mut self.midi_out.writer(scope), &mut output, frames);
|
||||
Control::Continue
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
impl PortList for Sequencer {
|
||||
fn midi_ins (&self) -> Usually<Vec<String>> { Ok(vec![self.midi_in.name()?]) }
|
||||
fn midi_outs (&self) -> Usually<Vec<String>> { Ok(vec![self.midi_out.name()?]) }
|
||||
|
|
@ -204,21 +186,6 @@ pub fn draw_clips (s: &Sequencer, buf: &mut Buffer, area: Rect) -> Usually<Rect>
|
|||
}
|
||||
Ok(Rect { x, y, width: 14, height: 14 })
|
||||
}
|
||||
pub fn contains_note_on (sequence: &Phrase, k: u7, start: usize, end: usize) -> bool {
|
||||
for (_, (_, events)) in sequence.notes.range(start..end).enumerate() {
|
||||
for event in events.iter() {
|
||||
match event {
|
||||
MidiMessage::NoteOn {key,..} => {
|
||||
if *key == k {
|
||||
return true
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
/// Add "all notes off" to the start of a buffer.
|
||||
pub fn all_notes_off (output: &mut MIDIChunk) {
|
||||
output[0] = Some(vec![]);
|
||||
|
|
@ -230,3 +197,14 @@ pub fn all_notes_off (output: &mut MIDIChunk) {
|
|||
frame.push(buf);
|
||||
}
|
||||
}
|
||||
/// Write to JACK port from output buffer (containing notes from sequence and/or monitor)
|
||||
fn write_output (writer: &mut ::jack::MidiWriter, output: &mut MIDIChunk, frames: usize) {
|
||||
for time in 0..frames {
|
||||
if let Some(Some(frame)) = output.get_mut(time ) {
|
||||
for event in frame.iter() {
|
||||
writer.write(&::jack::RawMidi { time: time as u32, bytes: &event })
|
||||
.expect(&format!("{event:?}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,23 @@ impl Phrase {
|
|||
pub fn new (name: &str, length: usize, notes: Option<PhraseData>) -> Self {
|
||||
Self { name: name.to_string(), length, notes: notes.unwrap_or(BTreeMap::new()) }
|
||||
}
|
||||
/** Write a chunk of MIDI events to an output port. */
|
||||
/// 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() {
|
||||
for event in events.iter() {
|
||||
match event {
|
||||
MidiMessage::NoteOn {key,..} => {
|
||||
if *key == k {
|
||||
return true
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
/// Write a chunk of MIDI events to an output port.
|
||||
pub fn process_out (
|
||||
&self,
|
||||
output: &mut MIDIChunk,
|
||||
|
|
@ -55,7 +71,7 @@ impl Phrase {
|
|||
}
|
||||
}
|
||||
}
|
||||
/** Read a chunk of MIDI events from an input port. */
|
||||
/// Read a chunk of MIDI events from an input port.
|
||||
pub fn process_in (
|
||||
&mut self,
|
||||
input: ::jack::MidiIter,
|
||||
|
|
|
|||
|
|
@ -37,9 +37,10 @@ pub fn steps (s: &Sequencer, buf: &mut Buffer, area: Rect, beat: usize) {
|
|||
(step + 1) as usize * ppq / s.time_zoom as usize,
|
||||
(step + 2) as usize * ppq / s.time_zoom as usize,
|
||||
);
|
||||
let phrase = &s.phrases[s.sequence.unwrap()];
|
||||
let (character, style) = match (
|
||||
contains_note_on(&s.phrases[s.sequence.unwrap()], key, a, b),
|
||||
contains_note_on(&s.phrases[s.sequence.unwrap()], key, b, c),
|
||||
phrase.contains_note_on(key, a, b),
|
||||
phrase.contains_note_on(key, b, c),
|
||||
) {
|
||||
(true, true) => ("█", wh),
|
||||
(true, false) => ("▀", wh),
|
||||
|
|
@ -87,8 +88,9 @@ pub fn keys (s: &Sequencer, buf: &mut Buffer, area: Rect, beat: usize) {
|
|||
(step + 2) as usize * ppq / s.time_zoom as usize,
|
||||
);
|
||||
let key = ::midly::num::u7::from(key as u8);
|
||||
is_on = is_on || contains_note_on(&s.phrases[s.sequence.unwrap()], key, a, b);
|
||||
is_on = is_on || contains_note_on(&s.phrases[s.sequence.unwrap()], key, b, c);
|
||||
let phrase = &s.phrases[s.sequence.unwrap()];
|
||||
is_on = is_on || phrase.contains_note_on(key, a, b);
|
||||
is_on = is_on || phrase.contains_note_on(key, b, c);
|
||||
if is_on {
|
||||
color = Style::default().red();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue