Program Listing for File dm_fx_variable_delay.h¶
↰ Return to documentation for file (src/effects/dm_fx_variable_delay.h
)
// Copyright (c) 2020 Run Jump Labs LLC. All right reserved.
// This code is licensed under MIT license (see license.txt for details)
#ifndef DM_FX_VARIABLE_DELAY_H
#define DM_FX_VARIABLE_DELAY_H
class fx_variable_delay: public fx_effect {
private:
// Parameters
float param_depth;
float param_rate_hz;
float param_initial_phase_deg;
float param_feedback;
float param_mix_clean;
float param_mix_delayed;
OSC_TYPES param_type;
float param_delay_buf_size_ms;
bool param_ext_modulator;
// Control nodes
fx_control_node node_ctrl_depth;
fx_control_node node_ctrl_rate_hz;
fx_control_node node_ctrl_feedback;
fx_control_node node_ctrl_mix_clean;
fx_control_node node_ctrl_mix_delayed;
// Additional audio nodes
fx_audio_node node_loop_ext_mod;
fx_audio_node node_modulated_out;
void init (void) {
// Set class
type = FX_VARIABLE_DELAY;
// Set name
strcpy(effect_name, "variable delay");
// initialize other variables
param_enabled = true;
// Assign programmable node names
input = &node_input;
output = &node_output;
ext_mod_in = &node_loop_ext_mod;
modulated_out = &node_modulated_out;
// Initialize parameter stack
int indx = 1;
param_stack[indx] = ¶m_rate_hz;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_depth;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_initial_phase_deg;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_feedback;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_type;
param_stack_types[indx++] = T_INT16;
param_stack[indx] = ¶m_ext_modulator;
param_stack_types[indx++] = T_BOOL;
param_stack[indx] = ¶m_delay_buf_size_ms;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_mix_clean;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_mix_delayed;
param_stack_types[indx++] = T_FLOAT;
total_params = indx;
// Add additional nodes to the audio stack
audio_node_stack[total_audio_nodes++] = &node_loop_ext_mod;
audio_node_stack[total_audio_nodes++] = &node_modulated_out;
// Add addititonal nodes to the control stack
control_node_stack[total_control_nodes++] = &node_ctrl_depth;
control_node_stack[total_control_nodes++] = &node_ctrl_rate_hz;
control_node_stack[total_control_nodes++] = &node_ctrl_feedback;
control_node_stack[total_control_nodes++] = &node_ctrl_mix_clean;
control_node_stack[total_control_nodes++] = &node_ctrl_mix_delayed;
depth = &node_ctrl_depth;
rate_hz = &node_ctrl_rate_hz;
feedback = &node_ctrl_feedback;
mix_clean = &node_ctrl_mix_clean;
mix_delayed = &node_ctrl_mix_delayed;
}
public:
fx_audio_node * input;
fx_audio_node * output;
fx_audio_node * ext_mod_in;
fx_audio_node * modulated_out;
fx_control_node * depth;
fx_control_node * rate_hz;
fx_control_node * feedback;
fx_control_node * mix_clean;
fx_control_node * mix_delayed;
fx_variable_delay(float rate_hz, float depth, float feedback, OSC_TYPES mod_type) :
node_loop_ext_mod(NODE_IN, "external modulator", this),
node_modulated_out(NODE_OUT, "modulated output", this),
node_ctrl_depth(NODE_IN, NODE_FLOAT, "node_ctrl_depth", this, FX_VAR_DELAY_PARAM_ID_MOD_DEPTH),
node_ctrl_rate_hz(NODE_IN, NODE_FLOAT, "node_ctrl_rate_hz", this, FX_VAR_DELAY_PARAM_ID_MOD_FREQ),
node_ctrl_mix_clean(NODE_IN, NODE_FLOAT, "node_ctrl_mix_clean", this, FX_VAR_DELAY_PARAM_ID_MIX_CLEAN),
node_ctrl_mix_delayed(NODE_IN, NODE_FLOAT, "node_ctrl_mix_delayed", this, FX_VAR_DELAY_PARAM_ID_MIX_DELAYED),
node_ctrl_feedback(NODE_IN, NODE_FLOAT, "node_ctrl_feedback", this, FX_VAR_DELAY_PARAM_ID_FEEDBACK) {
// Set parameters
param_initial_phase_deg = 0;
param_depth = depth;
param_rate_hz = rate_hz;
param_feedback = feedback;
param_mix_clean = 0.7;
param_mix_delayed = 0.5;
param_delay_buf_size_ms = 30.0;
param_type = mod_type;
param_ext_modulator = false;
init();
}
fx_variable_delay(float rate_hz, float depth, float feedback, float buf_size_ms, float mix_clean, float mix_delayed, OSC_TYPES mod_type, bool ext_mod ) :
node_loop_ext_mod(NODE_IN, "external modulator", this),
node_modulated_out(NODE_OUT, "modulated output", this),
node_ctrl_depth(NODE_IN, NODE_FLOAT, "node_ctrl_depth", this, FX_VAR_DELAY_PARAM_ID_MOD_DEPTH),
node_ctrl_rate_hz(NODE_IN, NODE_FLOAT, "node_ctrl_rate_hz", this, FX_VAR_DELAY_PARAM_ID_MOD_FREQ),
node_ctrl_mix_clean(NODE_IN, NODE_FLOAT, "node_ctrl_mix_clean", this, FX_VAR_DELAY_PARAM_ID_MIX_CLEAN),
node_ctrl_mix_delayed(NODE_IN, NODE_FLOAT, "node_ctrl_mix_delayed", this, FX_VAR_DELAY_PARAM_ID_MIX_DELAYED),
node_ctrl_feedback(NODE_IN, NODE_FLOAT, "node_ctrl_feedback", this, FX_VAR_DELAY_PARAM_ID_FEEDBACK) {
// Set parameters
param_initial_phase_deg = 0;
param_depth = depth;
param_rate_hz = rate_hz;
param_feedback = feedback;
param_mix_clean = mix_clean;
param_mix_delayed = mix_delayed;
param_delay_buf_size_ms = buf_size_ms;
param_type = mod_type;
param_ext_modulator = ext_mod;
init();
}
fx_variable_delay(float rate_hz, float depth, float feedback, float buf_size_ms, float mix_clean, float mix_delayed, OSC_TYPES mod_type, bool ext_mod, float initial_phase ) :
node_loop_ext_mod(NODE_IN, "external modulator", this),
node_modulated_out(NODE_OUT, "modulated output", this),
node_ctrl_depth(NODE_IN, NODE_FLOAT, "node_ctrl_depth", this, FX_VAR_DELAY_PARAM_ID_MOD_DEPTH),
node_ctrl_rate_hz(NODE_IN, NODE_FLOAT, "node_ctrl_rate_hz", this, FX_VAR_DELAY_PARAM_ID_MOD_FREQ),
node_ctrl_mix_clean(NODE_IN, NODE_FLOAT, "node_ctrl_mix_clean", this, FX_VAR_DELAY_PARAM_ID_MIX_CLEAN),
node_ctrl_mix_delayed(NODE_IN, NODE_FLOAT, "node_ctrl_mix_delayed", this, FX_VAR_DELAY_PARAM_ID_MIX_DELAYED),
node_ctrl_feedback(NODE_IN, NODE_FLOAT, "node_ctrl_feedback", this, FX_VAR_DELAY_PARAM_ID_FEEDBACK) {
// Set parameters
param_initial_phase_deg = initial_phase;
param_depth = depth;
param_rate_hz = rate_hz;
param_feedback = feedback;
param_mix_clean = mix_clean;
param_mix_delayed = mix_delayed;
param_delay_buf_size_ms = buf_size_ms;
param_type = mod_type;
param_ext_modulator = ext_mod;
init();
}
void enable() {
CHECK_LAST_ENABLED();
param_enabled = true;
parent_canvas->spi_transmit_param(FX_VARIABLE_DELAY, instance_id, T_BOOL, FX_VAR_DELAY_PARAM_ID_ENABLED, (void *) ¶m_enabled);
}
void bypass() {
CHECK_LAST_DISABLED();
param_enabled = false;
parent_canvas->spi_transmit_param(FX_VARIABLE_DELAY, instance_id, T_BOOL, FX_VAR_DELAY_PARAM_ID_ENABLED, (void *) ¶m_enabled);
}
void set_depth(float depth) {
CHECK_LAST(depth, param_depth);
// If this node is being controlled by a controller, don't allow a direct write to it
if (node_ctrl_depth.connected) {
return;
}
param_depth = depth;
parent_canvas->spi_transmit_param(FX_VARIABLE_DELAY, instance_id, T_FLOAT, FX_VAR_DELAY_PARAM_ID_MOD_DEPTH, ¶m_depth);
}
void set_rate_hz(float rate_hz) {
CHECK_LAST(rate_hz, param_rate_hz);
// If this node is being controlled by a controller, don't allow a direct write to it
if (node_ctrl_rate_hz.connected) {
return;
}
param_rate_hz = rate_hz;
parent_canvas->spi_transmit_param(FX_VARIABLE_DELAY, instance_id, T_FLOAT, FX_VAR_DELAY_PARAM_ID_MOD_FREQ, ¶m_rate_hz);
}
void set_feedback(float feedback) {
CHECK_LAST(feedback, param_feedback);
// If this node is being controlled by a controller, don't allow a direct write to it
if (node_ctrl_rate_hz.connected) {
return;
}
param_feedback = feedback;
parent_canvas->spi_transmit_param(FX_VARIABLE_DELAY, instance_id, T_FLOAT, FX_VAR_DELAY_PARAM_ID_FEEDBACK, ¶m_feedback);
}
void set_mix_clean(float mix_clean) {
CHECK_LAST(mix_clean, param_mix_clean);
// If this node is being controlled by a controller, don't allow a direct write to it
if (node_ctrl_mix_clean.connected) {
return;
}
param_mix_clean = mix_clean;
parent_canvas->spi_transmit_param(FX_VARIABLE_DELAY, instance_id, T_FLOAT, FX_VAR_DELAY_PARAM_ID_MIX_CLEAN, ¶m_mix_clean);
}
void set_mix_delayed(float mix_delayed) {
CHECK_LAST(mix_delayed, param_mix_delayed);
// If this node is being controlled by a controller, don't allow a direct write to it
if (node_ctrl_mix_delayed.connected) {
return;
}
param_mix_delayed= mix_delayed;
parent_canvas->spi_transmit_param(FX_VARIABLE_DELAY, instance_id, T_FLOAT, FX_VAR_DELAY_PARAM_ID_MIX_DELAYED, ¶m_mix_delayed);
}
void set_lfo_type(OSC_TYPES new_type) {
CHECK_LAST(new_type, param_type);
param_type = new_type;
parent_canvas->spi_transmit_param(FX_VARIABLE_DELAY, instance_id, T_INT16, FX_VAR_DELAY_PARAM_ID_MOD_TYPE, ¶m_type);
}
void print_params(void) {
// void print_parameter( void * val, char * name, PARAM_TYPES type)
Serial.println("Parameters:");
print_parameter( ¶m_enabled, "Enabled", T_BOOL );
print_parameter( ¶m_depth, "Depth", T_FLOAT );
print_parameter( ¶m_rate_hz, "Rate (Hz)", T_FLOAT );
print_parameter( ¶m_initial_phase_deg, "Initial phase (degrees)", T_FLOAT );
print_parameter( ¶m_mix_clean, "Clean signal mix", T_FLOAT );
print_parameter( ¶m_mix_delayed, "Delayed signal mix", T_FLOAT );
print_parameter( ¶m_feedback, "Feedback", T_FLOAT );
print_parameter( ¶m_ext_modulator, "External modulator", T_BOOL );
Serial.println("Control Routing:");
print_ctrl_node_status(&node_ctrl_depth);
print_ctrl_node_status(&node_ctrl_rate_hz);
print_ctrl_node_status(&node_ctrl_feedback);
print_ctrl_node_status(&node_ctrl_mix_clean);
Serial.println("Audio Routing:");
print_audio_node_status(&node_input);
print_audio_node_status(&node_output);
print_audio_node_status(&node_loop_ext_mod);
Serial.println();
}
};
#endif // DM_FX_VARIABLE_DELAY_H