Work on the gate length mode for MidiP
This commit is contained in:
parent
5be2c93c45
commit
3b4e8a36f5
2 changed files with 80 additions and 3 deletions
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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)]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue