From fb3a7f98968bf36a7d2aa1c52446053d254cd403 Mon Sep 17 00:00:00 2001 From: Weird Constructor Date: Thu, 11 Aug 2022 05:11:26 +0200 Subject: [PATCH] Better note recalculation --- src/dsp/node_midip.rs | 25 ++++++++++++++++++------- src/nodes/note_buffer.rs | 9 +++------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/dsp/node_midip.rs b/src/dsp/node_midip.rs index bfe8a80..7b12b58 100644 --- a/src/dsp/node_midip.rs +++ b/src/dsp/node_midip.rs @@ -17,15 +17,12 @@ macro_rules! fa_midip_chan { /// The (stereo) output port of the plugin #[derive(Debug, Clone)] pub struct MidiP { - /// - 0: signal channel 1 - /// - 1: signal channel 2 - #[allow(dead_code)] - input: [f32; 2], + prev_gate: u8, } impl MidiP { pub fn new(_nid: &NodeId) -> Self { - Self { input: [0.0; 2] } + Self { prev_gate: 0 } } pub const chan: &'static str = "MidiP chan\nMIDI Channel 0 to 15\n"; @@ -94,8 +91,22 @@ impl DspNode for MidiP { for frame in 0..ctx.nframes() { let chan = ectx.note_buffer.get_chan_at(0, frame as u8); - freq.write(frame, chan.note as f32 * 1.0 / 127.0); - gate.write(frame, chan.gate as f32); + + let note = (chan.note as f32 - 57.0) / 120.0; + freq.write(frame, note); + + if chan.gate > 0 { + // insert a single sample of silence, for retriggering + // any envelopes if the note changed but no note-off came. + if self.prev_gate > 0 && self.prev_gate != chan.gate { + gate.write(frame, 0.0); + } else { + gate.write(frame, 1.0); + } + } else { + gate.write(frame, 0.0); + } + self.prev_gate = chan.gate; vel.write(frame, chan.vel as f32); } diff --git a/src/nodes/note_buffer.rs b/src/nodes/note_buffer.rs index 42d847f..7012482 100644 --- a/src/nodes/note_buffer.rs +++ b/src/nodes/note_buffer.rs @@ -61,18 +61,15 @@ impl NoteBuffer { #[inline] pub fn note_on(&mut self, channel: u8, note: u8) { let mut chan = &mut self.interleaved_chans[(self.buf_idx * 16) + (channel as usize % 16)]; - if chan.gate == 0 { - chan.gate = 1; - chan.note = note; - } + chan.gate = (chan.gate + 1) % 2 + 1; + chan.note = note; } #[inline] pub fn note_off(&mut self, channel: u8, note: u8) { let mut chan = &mut self.interleaved_chans[(self.buf_idx * 16) + (channel as usize % 16)]; - if chan.gate == 1 && chan.note == note { + if chan.gate > 0 && chan.note == note { chan.gate = 0; - chan.note = 0; } }