Program Listing for File dm_fx_envelope_tracker.h¶
↰ Return to documentation for file (src/effects/dm_fx_envelope_tracker.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_ENVELOPE_TRACKER_H
#define DM_FX_ENVELOPE_TRACKER_H
class fx_envelope_tracker:public fx_effect {
private:
// Parameters
float param_decay_ms;
float param_attack_ms;
bool param_triggered;
ENV_TRACKER_TYPE param_type;
float param_scale;
float param_offset;
// Control nodes
fx_control_node node_ctrl_attack_ms;
fx_control_node node_ctrl_decay_ms;
fx_control_node node_ctrl_envelope;
fx_control_node node_ctrl_scale;
fx_control_node node_ctrl_offset;
void init(void) {
// Set class
type = FX_ENVELOPE_TRACKER;
// Set name
strcpy(effect_name, "envelope tracker");
// Initialize parameter stack
int indx = 1;
param_stack[indx] = ¶m_attack_ms;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_decay_ms;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_scale;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_offset;
param_stack_types[indx++] = T_FLOAT;
param_stack[indx] = ¶m_type;
param_stack_types[indx++] = T_INT16;
param_stack[indx] = ¶m_triggered;
param_stack_types[indx++] = T_BOOL;
total_params = indx;
// Initialize node stacks
control_node_stack[total_control_nodes++] = &node_ctrl_attack_ms;
control_node_stack[total_control_nodes++] = &node_ctrl_decay_ms;
control_node_stack[total_control_nodes++] = &node_ctrl_scale;
control_node_stack[total_control_nodes++] = &node_ctrl_offset;
control_node_stack[total_control_nodes++] = &node_ctrl_envelope;
// Assign node variables to locations
input = &node_input;
attack_speed_ms = &node_ctrl_attack_ms;
decay_speed_ms = &node_ctrl_decay_ms;
envelope = &node_ctrl_envelope;
scale = &node_ctrl_scale;
offset = &node_ctrl_offset;
}
public:
// Audio node names that users will be using
fx_audio_node * input;
// Control node names that users will be using
fx_control_node * decay_speed_ms;
fx_control_node * attack_speed_ms;
fx_control_node * envelope;
fx_control_node * scale;
fx_control_node * offset;
fx_envelope_tracker(float attack_speed_ms, float decay_speed_ms, bool triggered) :
node_ctrl_attack_ms(NODE_IN, NODE_FLOAT, "node_ctrl_attack_speed", this, FX_ENV_TRACKER_PARAM_ID_ATTACK_MS),
node_ctrl_decay_ms(NODE_IN, NODE_FLOAT, "node_ctrl_decay_speed", this, FX_ENV_TRACKER_PARAM_ID_DECAY_MS),
node_ctrl_scale(NODE_IN, NODE_FLOAT, "node_ctrl_scale", this, FX_ENV_TRACKER_PARAM_ID_SCALE),
node_ctrl_offset(NODE_IN, NODE_FLOAT, "node_ctrl_offset", this, FX_ENV_TRACKER_PARAM_ID_OFFSET),
node_ctrl_envelope(NODE_OUT, NODE_FLOAT, "node_ctrl_envelope", this, FX_ENV_TRACKER_PARAM_ID_VALUE) {
param_attack_ms = attack_speed_ms;
param_decay_ms = decay_speed_ms;
param_triggered = triggered;
param_scale = 1.0;
param_offset = 0.0;
init();
}
fx_envelope_tracker(float attack_speed_ms, float decay_speed_ms, bool triggered, float ctrl_scale, float ctrl_offset) :
node_ctrl_attack_ms(NODE_IN, NODE_FLOAT, "node_ctrl_attack_speed", this, FX_ENV_TRACKER_PARAM_ID_ATTACK_MS),
node_ctrl_decay_ms(NODE_IN, NODE_FLOAT, "node_ctrl_decay_speed", this, FX_ENV_TRACKER_PARAM_ID_DECAY_MS),
node_ctrl_scale(NODE_IN, NODE_FLOAT, "node_ctrl_scale", this, FX_ENV_TRACKER_PARAM_ID_SCALE),
node_ctrl_offset(NODE_IN, NODE_FLOAT, "node_ctrl_offset", this, FX_ENV_TRACKER_PARAM_ID_OFFSET),
node_ctrl_envelope(NODE_OUT, NODE_FLOAT, "node_ctrl_envelope", this, FX_ENV_TRACKER_PARAM_ID_VALUE) {
param_attack_ms = attack_speed_ms;
param_decay_ms = decay_speed_ms;
param_triggered = triggered;
param_scale = ctrl_scale;
param_offset = ctrl_offset;
init();
}
void set_attack_speed_ms(float attack_speed_ms) {
CHECK_LAST(attack_speed_ms, param_attack_ms);
// If this node is being controlled by a controller, don't allow a direct write to it
if (node_ctrl_attack_ms.connected) {
return;
}
param_attack_ms = attack_speed_ms;
parent_canvas->spi_transmit_param(FX_ENVELOPE_TRACKER, instance_id, T_FLOAT, FX_ENV_TRACKER_PARAM_ID_ATTACK_MS, ¶m_attack_ms);
}
void set_decay_speed_ms(float decay_speed_ms) {
CHECK_LAST(decay_speed_ms, param_decay_ms);
// If this node is being controlled by a controller, don't allow a direct write to it
if (node_ctrl_decay_ms.connected) {
return;
}
param_decay_ms = decay_speed_ms;
parent_canvas->spi_transmit_param(FX_ENVELOPE_TRACKER, instance_id, T_FLOAT, FX_ENV_TRACKER_PARAM_ID_DECAY_MS, ¶m_decay_ms);
}
void set_env_scale(float scale) {
CHECK_LAST(scale, param_scale);
// If this node is being controlled by a controller, don't allow a direct write to it
if (node_ctrl_scale.connected) {
return;
}
param_scale = scale;
parent_canvas->spi_transmit_param(FX_ENVELOPE_TRACKER, instance_id, T_FLOAT, FX_ENV_TRACKER_PARAM_ID_SCALE, ¶m_scale);
}
void set_env_offset(float offset) {
CHECK_LAST(offset, param_offset);
// If this node is being controlled by a controller, don't allow a direct write to it
if (node_ctrl_offset.connected) {
return;
}
param_offset = offset;
parent_canvas->spi_transmit_param(FX_ENVELOPE_TRACKER, instance_id, T_FLOAT, FX_ENV_TRACKER_PARAM_ID_OFFSET, ¶m_offset);
}
void print_params(void) {
// void print_parameter( void * val, char * name, PARAM_TYPES type)
Serial.println("Parameters:");
print_parameter( ¶m_attack_ms, "Attack speed (ms) ", T_FLOAT );
print_parameter( ¶m_decay_ms, "Decay speed (ms) ", T_FLOAT );
print_parameter( ¶m_scale, "Envelope scale ", T_FLOAT );
print_parameter( ¶m_offset, "Envelope offset ", T_FLOAT );
print_parameter( ¶m_triggered, "Triggered ", T_BOOL );
Serial.println("Control Routing:");
print_ctrl_node_status(&node_ctrl_attack_ms);
print_ctrl_node_status(&node_ctrl_decay_ms);
print_ctrl_node_status(&node_ctrl_scale);
print_ctrl_node_status(&node_ctrl_offset);
print_ctrl_node_status(&node_ctrl_envelope);
Serial.println("Audio Routing:");
print_audio_node_status(&node_input);
Serial.println();
}
};
#endif // DM_FX_ENVELOPE_TRACKER_H