diff --git a/src/dsp/node_midip.rs b/src/dsp/node_midip.rs index c12581b..cb40826 100644 --- a/src/dsp/node_midip.rs +++ b/src/dsp/node_midip.rs @@ -2,9 +2,9 @@ // This file is a part of HexoDSP. Released under GPL-3.0-or-later. // See README.md and COPYING for details. -use crate::dsp::{at, inp, out_idx, DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom}; +use crate::dsp::{at, inp, denorm, out_idx, DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom}; use crate::nodes::{HxMidiEvent, MidiEventPointer, NodeAudioContext, NodeExecContext}; -use synfx_dsp::TrigSignal; +use synfx_dsp::{GateSignal, TrigSignal}; #[macro_export] macro_rules! fa_midip_chan { @@ -34,11 +34,19 @@ pub struct MidiP { cur_gate: u8, cur_vel: f32, trig_sig: TrigSignal, + gate_sig: GateSignal, } impl MidiP { pub fn new(_nid: &NodeId) -> Self { - Self { next_gate: 0, cur_note: 0, cur_gate: 0, cur_vel: 0.0, trig_sig: TrigSignal::new() } + Self { + next_gate: 0, + cur_note: 0, + cur_gate: 0, + cur_vel: 0.0, + trig_sig: TrigSignal::new(), + gate_sig: GateSignal::new(), + } } pub const chan: &'static str = "MidiP chan\nMIDI Channel 0 to 15\n"; @@ -91,9 +99,11 @@ impl DspNode for MidiP { fn set_sample_rate(&mut self, srate: f32) { self.trig_sig.set_sample_rate(srate); + self.gate_sig.set_sample_rate(srate); } fn reset(&mut self) { self.trig_sig.reset(); + self.gate_sig.reset(); } #[inline] @@ -108,6 +118,7 @@ impl DspNode for MidiP { ctx_vals: LedPhaseVals, ) { let det = inp::MidiP::det(inputs); + let glen = inp::MidiP::glen(inputs); let chan = at::MidiP::chan(atoms); let gmode = at::MidiP::gmode(atoms); let out_i = out_idx::MidiP::gate(); @@ -124,6 +135,8 @@ impl DspNode for MidiP { let gmode = gmode.i(); for frame in 0..ctx.nframes() { + let gate_len = denorm::MidiP::glen(glen, frame); + if self.next_gate > 0 { self.cur_gate = 1; } else if self.next_gate < 0 { @@ -144,11 +157,14 @@ impl DspNode for MidiP { } else { self.cur_gate = 1; } + println!("NOTE ON"); self.trig_sig.trigger(); + self.gate_sig.trigger(); self.cur_note = note; self.cur_vel = vel; } HxMidiEvent::NoteOff { channel, note } => { + println!("NOTE OFF"); if channel != midip_channel { continue; } @@ -165,6 +181,14 @@ impl DspNode for MidiP { 1 => { gate.write(frame, self.trig_sig.next()); } + 2 => { + println!("GOGOGO {} {}", gate_len, self.next_gate); + if self.next_gate > 0 { + gate.write(frame, 0.0); + } else { + gate.write(frame, self.gate_sig.next(gate_len)); + } + } _ => { gate.write(frame, if self.cur_gate > 0 { 1.0 } else { 0.0 }); } diff --git a/tests/node_midip.rs b/tests/node_midip.rs index 844e5bc..d21ced1 100644 --- a/tests/node_midip.rs +++ b/tests/node_midip.rs @@ -189,3 +189,56 @@ fn check_node_midip_trigger_test() { // As expected, now end of note at 106: assert_eq!(changes, vec![(100, 100), (106, -100)]); } + +#[test] +fn check_node_midip_gate_test() { + let (node_conf, mut node_exec) = new_node_engine(); + let mut matrix = Matrix::new(node_conf, 3, 3); + + let mut chain = MatrixCellChain::new(CellDir::B); + chain + .node_out("midip", "gate") + .set_denorm("det", 0.1) + .set_atom("gmode", SAtom::setting(2)) + .set_denorm("glen", 1.0) + .node_inp("out", "ch1") + .place(&mut matrix, 0, 0) + .unwrap(); + matrix.sync().unwrap(); + + let (ch1, _) = node_exec.test_run( + 0.015, + false, + &[HxTimedEvent::note_on(100, 0, 69, 1.0), HxTimedEvent::note_off(105, 0, 69)], + ); + + let changes = collect_signal_changes_both_edges(&ch1[..], 1); + assert_eq!(changes, vec![(100, 100), (145, -100)]); + + // Check double trigger: + let (ch1, _) = node_exec.test_run( + 0.015, + false, + &[ + HxTimedEvent::note_on(100, 0, 69, 1.0), + HxTimedEvent::note_off(105, 0, 69), + HxTimedEvent::note_on(120, 0, 69, 1.0), + ], + ); + + let changes = collect_signal_changes_both_edges(&ch1[..], 1); + assert_eq!(changes, vec![(100, 100), (145, -100)]); + + // // Now test without the trigger signal: + // node_pset_s(&mut matrix, "midip", 0, "gmode", 0); + // + // let (ch1, _) = node_exec.test_run( + // 0.015, + // false, + // &[HxTimedEvent::note_on(100, 0, 69, 1.0), HxTimedEvent::note_off(105, 0, 69)], + // ); + // + // let changes = collect_signal_changes_both_edges(&ch1[..], 1); + // // As expected, now end of note at 106: + // assert_eq!(changes, vec![(100, 100), (106, -100)]); +}