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.
|
// This file is a part of HexoDSP. Released under GPL-3.0-or-later.
|
||||||
// See README.md and COPYING for details.
|
// 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 crate::nodes::{HxMidiEvent, MidiEventPointer, NodeAudioContext, NodeExecContext};
|
||||||
use synfx_dsp::TrigSignal;
|
use synfx_dsp::{GateSignal, TrigSignal};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fa_midip_chan {
|
macro_rules! fa_midip_chan {
|
||||||
|
@ -34,11 +34,19 @@ pub struct MidiP {
|
||||||
cur_gate: u8,
|
cur_gate: u8,
|
||||||
cur_vel: f32,
|
cur_vel: f32,
|
||||||
trig_sig: TrigSignal,
|
trig_sig: TrigSignal,
|
||||||
|
gate_sig: GateSignal,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MidiP {
|
impl MidiP {
|
||||||
pub fn new(_nid: &NodeId) -> Self {
|
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";
|
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) {
|
fn set_sample_rate(&mut self, srate: f32) {
|
||||||
self.trig_sig.set_sample_rate(srate);
|
self.trig_sig.set_sample_rate(srate);
|
||||||
|
self.gate_sig.set_sample_rate(srate);
|
||||||
}
|
}
|
||||||
fn reset(&mut self) {
|
fn reset(&mut self) {
|
||||||
self.trig_sig.reset();
|
self.trig_sig.reset();
|
||||||
|
self.gate_sig.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -108,6 +118,7 @@ impl DspNode for MidiP {
|
||||||
ctx_vals: LedPhaseVals,
|
ctx_vals: LedPhaseVals,
|
||||||
) {
|
) {
|
||||||
let det = inp::MidiP::det(inputs);
|
let det = inp::MidiP::det(inputs);
|
||||||
|
let glen = inp::MidiP::glen(inputs);
|
||||||
let chan = at::MidiP::chan(atoms);
|
let chan = at::MidiP::chan(atoms);
|
||||||
let gmode = at::MidiP::gmode(atoms);
|
let gmode = at::MidiP::gmode(atoms);
|
||||||
let out_i = out_idx::MidiP::gate();
|
let out_i = out_idx::MidiP::gate();
|
||||||
|
@ -124,6 +135,8 @@ impl DspNode for MidiP {
|
||||||
let gmode = gmode.i();
|
let gmode = gmode.i();
|
||||||
|
|
||||||
for frame in 0..ctx.nframes() {
|
for frame in 0..ctx.nframes() {
|
||||||
|
let gate_len = denorm::MidiP::glen(glen, frame);
|
||||||
|
|
||||||
if self.next_gate > 0 {
|
if self.next_gate > 0 {
|
||||||
self.cur_gate = 1;
|
self.cur_gate = 1;
|
||||||
} else if self.next_gate < 0 {
|
} else if self.next_gate < 0 {
|
||||||
|
@ -144,11 +157,14 @@ impl DspNode for MidiP {
|
||||||
} else {
|
} else {
|
||||||
self.cur_gate = 1;
|
self.cur_gate = 1;
|
||||||
}
|
}
|
||||||
|
println!("NOTE ON");
|
||||||
self.trig_sig.trigger();
|
self.trig_sig.trigger();
|
||||||
|
self.gate_sig.trigger();
|
||||||
self.cur_note = note;
|
self.cur_note = note;
|
||||||
self.cur_vel = vel;
|
self.cur_vel = vel;
|
||||||
}
|
}
|
||||||
HxMidiEvent::NoteOff { channel, note } => {
|
HxMidiEvent::NoteOff { channel, note } => {
|
||||||
|
println!("NOTE OFF");
|
||||||
if channel != midip_channel {
|
if channel != midip_channel {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -165,6 +181,14 @@ impl DspNode for MidiP {
|
||||||
1 => {
|
1 => {
|
||||||
gate.write(frame, self.trig_sig.next());
|
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 });
|
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:
|
// As expected, now end of note at 106:
|
||||||
assert_eq!(changes, vec![(100, 100), (106, -100)]);
|
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