Program Listing for File dm_fx_instrument_synth.h¶
↰ Return to documentation for file (src/effects/dm_fx_instrument_synth.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_INSTRUMENT_SYNTH_H
#define DM_FX_INSTRUMENT_SYNTH_H
class fx_instrument_synth: public fx_effect {
private:
// Parameters
float param_freq_ratio;
OSC_TYPES param_fm_osc_type;
float param_fm_mod_freq_ratio;
float param_fm_mod_depth;
OSC_TYPES param_osc_type;
float param_attack_ms;
float param_filt_resonance;
float param_filt_response;
OSC_TYPES last_type;
OSC_TYPES last_type_fm_mod;
// Control nodes
fx_control_node node_ctrl_attack_ms;
fx_control_node node_ctrl_freq_ratio;
fx_control_node node_ctrl_dm_mod_freq_ratio;
fx_control_node node_ctrl_dm_mod_depth;
fx_control_node node_ctrl_filt_resonance;
fx_control_node node_ctrl_filt_response;
void init(void) {
// Set class
type = FX_INSTRUMENT_SYNTH;
// Set name
strcpy(effect_name, "instrument synth");
// Assign programmable node names
output = &node_output;
// Initialize parameter stack
int indx = 1;
param_stack[indx] = ¶m_osc_type;
param_stack_types[indx++] = T_INT16;
param_stack[indx] = ¶m_fm_osc_type;
param_stack_types[indx++] = T_INT16;
param_stack[indx] = ¶m_freq_ratio;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_fm_mod_freq_ratio;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_fm_mod_depth;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_attack_ms;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_filt_resonance;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_filt_response;
param_stack_types[indx++] = T_FLOAT;
total_params = indx;
// Add addiitonal notes to the control stack
control_node_stack[total_control_nodes++] = &node_ctrl_freq_ratio;
control_node_stack[total_control_nodes++] = &node_ctrl_attack_ms;
control_node_stack[total_control_nodes++] = &node_ctrl_dm_mod_freq_ratio;
control_node_stack[total_control_nodes++] = &node_ctrl_dm_mod_depth;
control_node_stack[total_control_nodes++] = &node_ctrl_filt_resonance;
control_node_stack[total_control_nodes++] = &node_ctrl_filt_response;
freq_ratio = &node_ctrl_freq_ratio;
attack_ms = &node_ctrl_attack_ms;
fm_mod_freq_ratio = &node_ctrl_dm_mod_freq_ratio;
fm_mod_depth = &node_ctrl_dm_mod_depth;
resonance = &node_ctrl_filt_resonance;
response = &node_ctrl_filt_response;
}
public:
fx_audio_node * output;
fx_control_node * attack_ms;
fx_control_node * freq_ratio;
fx_control_node * fm_mod_freq_ratio;
fx_control_node * fm_mod_depth;
fx_control_node * resonance;
fx_control_node * response;
fx_instrument_synth( OSC_TYPES osc_type, float attack_ms, float filter_resonance, float filter_response) :
node_ctrl_freq_ratio(NODE_IN, NODE_FLOAT, "node_ctrl_freq_ratio", this, FX_INSTRUMENT_SYNTH_PARAM_ID_FREQ_RATIO),
node_ctrl_dm_mod_freq_ratio(NODE_IN, NODE_FLOAT, "node_ctrl_dm_mod_freq_ratio", this, FX_INSTRUMENT_SYNTH_PARAM_ID_FM_MOD_RATIO),
node_ctrl_dm_mod_depth(NODE_IN, NODE_FLOAT, "node_ctrl_dm_mod_depth", this, FX_INSTRUMENT_SYNTH_PARAM_ID_FM_MOD_DEPTH),
node_ctrl_attack_ms(NODE_IN, NODE_FLOAT, "node_ctrl_attack_ms", this, FX_INSTRUMENT_SYNTH_PARAM_ID_ATTACK_MS),
node_ctrl_filt_resonance(NODE_IN, NODE_FLOAT, "node_ctrl_filt_resonance", this, FX_INSTRUMENT_SYNTH_PARAM_ID_FILT_RESONANCE),
node_ctrl_filt_response(NODE_IN, NODE_FLOAT, "param_filt_response", this, FX_INSTRUMENT_SYNTH_PARAM_ID_FILT_RESPONSE) {
param_osc_type = osc_type;
param_attack_ms = attack_ms;
param_filt_resonance = filter_resonance;
param_filt_response = filter_response;
param_fm_osc_type = OSC_NONE;
param_fm_mod_depth = 0.0;
param_fm_mod_freq_ratio = 1.0;
param_freq_ratio = 1.0;
init();
}
fx_instrument_synth( OSC_TYPES osc_type, OSC_TYPES fm_mod_osc_type, float fm_mod_depth, float freq_ratio, float freq_ratio_fm_mod, float attack_ms, float filter_resonance, float filter_response) :
node_ctrl_freq_ratio(NODE_IN, NODE_FLOAT, "node_ctrl_freq_ratio", this, FX_INSTRUMENT_SYNTH_PARAM_ID_FREQ_RATIO),
node_ctrl_dm_mod_freq_ratio(NODE_IN, NODE_FLOAT, "node_ctrl_dm_mod_freq_ratio", this, FX_INSTRUMENT_SYNTH_PARAM_ID_FM_MOD_RATIO),
node_ctrl_dm_mod_depth(NODE_IN, NODE_FLOAT, "node_ctrl_dm_mod_depth", this, FX_INSTRUMENT_SYNTH_PARAM_ID_FM_MOD_DEPTH),
node_ctrl_attack_ms(NODE_IN, NODE_FLOAT, "node_ctrl_attack_ms", this, FX_INSTRUMENT_SYNTH_PARAM_ID_ATTACK_MS),
node_ctrl_filt_resonance(NODE_IN, NODE_FLOAT, "node_ctrl_filt_resonance", this, FX_INSTRUMENT_SYNTH_PARAM_ID_FILT_RESONANCE),
node_ctrl_filt_response(NODE_IN, NODE_FLOAT, "node_ctrl_filt_response", this, FX_INSTRUMENT_SYNTH_PARAM_ID_FILT_RESPONSE) {
param_osc_type = osc_type;
param_attack_ms = attack_ms;
param_filt_resonance = filter_resonance;
param_filt_response = filter_response;
param_fm_osc_type = fm_mod_osc_type;
param_fm_mod_depth = fm_mod_depth;
param_fm_mod_freq_ratio = freq_ratio_fm_mod;
param_freq_ratio = freq_ratio;
init();
}
void enable() {
CHECK_LAST_ENABLED();
param_enabled = true;
parent_canvas->spi_transmit_param(FX_INSTRUMENT_SYNTH, instance_id, T_BOOL, FX_INSTRUMENT_SYNTH_PARAM_ID_ENABLED, (void *) ¶m_enabled);
}
void bypass() {
CHECK_LAST_DISABLED();
param_enabled = false;
parent_canvas->spi_transmit_param(FX_INSTRUMENT_SYNTH, instance_id, T_BOOL, FX_INSTRUMENT_SYNTH_PARAM_ID_ENABLED, (void *) ¶m_enabled);
}
void set_freq_ratio(float ratio) {
CHECK_LAST(ratio, param_freq_ratio);
if (node_ctrl_freq_ratio.connected) {
return;
}
param_freq_ratio = ratio;
parent_canvas->spi_transmit_param(FX_INSTRUMENT_SYNTH, instance_id, T_FLOAT, FX_INSTRUMENT_SYNTH_PARAM_ID_FREQ_RATIO, ¶m_freq_ratio);
}
void set_fm_mod_ratio(float fm_mod_ratio) {
CHECK_LAST(fm_mod_ratio, param_fm_mod_freq_ratio);
if (node_ctrl_dm_mod_freq_ratio.connected) {
return;
}
param_fm_mod_freq_ratio = fm_mod_ratio;
parent_canvas->spi_transmit_param(FX_INSTRUMENT_SYNTH, instance_id, T_FLOAT, FX_INSTRUMENT_SYNTH_PARAM_ID_FM_MOD_RATIO, ¶m_fm_mod_freq_ratio);
}
void set_fm_mod_depth(float depth) {
CHECK_LAST(depth, param_fm_mod_depth);
if (node_ctrl_dm_mod_depth.connected) {
return;
}
param_fm_mod_depth = depth;
parent_canvas->spi_transmit_param(FX_INSTRUMENT_SYNTH, instance_id, T_FLOAT, FX_INSTRUMENT_SYNTH_PARAM_ID_FM_MOD_DEPTH, ¶m_fm_mod_depth);
}
void set_attack_ms(float attack_ms) {
CHECK_LAST(attack_ms, param_attack_ms);
if (node_ctrl_attack_ms.connected) {
return;
}
param_attack_ms = attack_ms;
parent_canvas->spi_transmit_param(FX_INSTRUMENT_SYNTH, instance_id, T_FLOAT, FX_INSTRUMENT_SYNTH_PARAM_ID_ATTACK_MS, ¶m_attack_ms);
}
void set_filter_resonance(float resonance) {
CHECK_LAST(resonance, param_filt_resonance);
if (node_ctrl_filt_resonance.connected) {
return;
}
param_filt_resonance = resonance;
parent_canvas->spi_transmit_param(FX_INSTRUMENT_SYNTH, instance_id, T_FLOAT, FX_INSTRUMENT_SYNTH_PARAM_ID_FILT_RESONANCE, ¶m_filt_resonance);
}
void set_filter_response(float response) {
CHECK_LAST(response, param_filt_response);
if (node_ctrl_filt_response.connected) {
return;
}
param_filt_response = response;
parent_canvas->spi_transmit_param(FX_INSTRUMENT_SYNTH, instance_id, T_FLOAT, FX_INSTRUMENT_SYNTH_PARAM_ID_FILT_RESPONSE, ¶m_filt_response);
}
void set_oscillator_type(OSC_TYPES new_type) {
CHECK_LAST(new_type, param_osc_type);
param_osc_type = new_type;
parent_canvas->spi_transmit_param(FX_INSTRUMENT_SYNTH, instance_id, T_INT16, FX_INSTRUMENT_SYNTH_PARAM_ID_OSC_TYPE, ¶m_osc_type);
}
void set_oscillator_type_fm_mod(OSC_TYPES new_type) {
CHECK_LAST(new_type, param_fm_osc_type);
param_fm_osc_type = new_type;
parent_canvas->spi_transmit_param(FX_INSTRUMENT_SYNTH, instance_id, T_INT16, FX_INSTRUMENT_SYNTH_PARAM_ID_OSC_FM_TYPE, ¶m_fm_osc_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_osc_type, "OSC type (enumeration index)", T_INT16 );
print_parameter( ¶m_fm_osc_type, "FM mod OSC type (enumeration index)", T_INT16 );
print_parameter( ¶m_freq_ratio, "Synth frequency ratio", T_FLOAT);
print_parameter( ¶m_fm_mod_freq_ratio, "FM mod frequency ratio", T_FLOAT );
print_parameter( ¶m_fm_mod_depth, "FM mod depth", T_FLOAT );
print_parameter( ¶m_attack_ms, "Attack (ms)", T_FLOAT );
print_parameter( ¶m_filt_resonance, "Filter resonance", T_FLOAT );
print_parameter( ¶m_filt_response, "Filter response", T_FLOAT );
Serial.println("Control Routing:");
print_ctrl_node_status(&node_ctrl_attack_ms);
print_ctrl_node_status(&node_ctrl_freq_ratio);
print_ctrl_node_status(&node_ctrl_dm_mod_freq_ratio);
print_ctrl_node_status(&node_ctrl_dm_mod_depth);
print_ctrl_node_status(&node_ctrl_filt_resonance);
print_ctrl_node_status(&node_ctrl_filt_response);
Serial.println("Audio Routing:");
print_audio_node_status(&node_output);
Serial.println();
}
};
#endif // DM_FX_INSTRUMENT_SYNTH_H