Program Listing for File dm_fx_spectralizer.h

Return to documentation for file (src/effects/dm_fx_spectralizer.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_SPECTRALIZER_H
#define DM_FX_SPECTRALIZER_H


class fx_pitch_shift_fd: public fx_effect {

  private:

    // Ring modulator parameters
    float param_freq_shift_1;
    float param_freq_shift_2;
    float param_vol_1;
    float param_vol_2;
    float param_vol_clean;


    // Control nodes
    fx_control_node node_ctrl_freq_shift_1;
    fx_control_node node_ctrl_freq_shift_2;
    fx_control_node node_ctrl_vol_1;
    fx_control_node node_ctrl_vol_2;
    fx_control_node node_ctrl_vol_clean;

 public:

    fx_audio_node * input;

    fx_audio_node * output;



    fx_control_node * freq_shift_1;

    fx_control_node * freq_shift_2;

    fx_control_node * vol_1;

    fx_control_node * vol_2;

    fx_control_node * vol_clean;

    fx_pitch_shift_fd(float freq, float volume, float volume_clean) :
        node_ctrl_freq_shift_1(NODE_IN, NODE_FLOAT, "node_ctrl_freq_shift_1", this, FX_SPECTRALIZER_PARAM_ID_FREQ_SHIFT_1),
        node_ctrl_freq_shift_2(NODE_IN, NODE_FLOAT, "node_ctrl_freq_shift_2", this, FX_SPECTRALIZER_PARAM_ID_FREQ_SHIFT_2),
        node_ctrl_vol_1(NODE_IN, NODE_FLOAT, "node_ctrl_vol_1", this, FX_SPECTRALIZER_PARAM_ID_VOL_1),
        node_ctrl_vol_2(NODE_IN, NODE_FLOAT, "node_ctrl_vol_2", this, FX_SPECTRALIZER_PARAM_ID_VOL_2),
        node_ctrl_vol_clean(NODE_IN, NODE_FLOAT, "node_ctrl_vol_clean", this, FX_SPECTRALIZER_PARAM_ID_VOL_CLEAN)
     {

      // Set class
      type = FX_SPECTRALIZER;

      // Set name
      strcpy(effect_name, "pitch shift (frequency domain)");

      // Set parameters
      param_freq_shift_1 = freq;
      param_freq_shift_2 = 0.0;
      param_vol_1 = volume;
      param_vol_2 = 0.0;
      param_vol_clean = volume_clean;

      // Assign programmable node names
      input = &node_input;
      output = &node_output;

      // Defaults
      param_enabled = true;

      // Initialize parameter stack
      param_stack[total_params] = &param_freq_shift_1;
      param_stack_types[total_params++] = T_FLOAT;
      param_stack[total_params] = &param_freq_shift_2;
      param_stack_types[total_params++] = T_FLOAT;
      param_stack[total_params] = &param_vol_1;
      param_stack_types[total_params++] = T_FLOAT;
      param_stack[total_params] = &param_vol_2;
      param_stack_types[total_params++] = T_FLOAT;
      param_stack[total_params] = &param_vol_clean;
      param_stack_types[total_params++] = T_FLOAT;

      // Add addiitonal notes to the control stack
      control_node_stack[total_control_nodes++] = &node_ctrl_freq_shift_1;
      control_node_stack[total_control_nodes++] = &node_ctrl_freq_shift_2;
      control_node_stack[total_control_nodes++] = &node_ctrl_vol_1;
      control_node_stack[total_control_nodes++] = &node_ctrl_vol_2;
      control_node_stack[total_control_nodes++] = &node_ctrl_vol_clean;

      freq_shift_1 = &node_ctrl_freq_shift_1;
      freq_shift_2 = &node_ctrl_freq_shift_2;
      vol_1 = &node_ctrl_vol_1;
      vol_2 = &node_ctrl_vol_2;
      vol_clean = &node_ctrl_vol_clean;

    }

    fx_pitch_shift_fd(float freq_1, float volume_1, float freq_2, float volume_2, float volume_clean) :
        node_ctrl_freq_shift_1(NODE_IN, NODE_FLOAT, "node_ctrl_freq_shift_1", this, FX_SPECTRALIZER_PARAM_ID_FREQ_SHIFT_1),
        node_ctrl_freq_shift_2(NODE_IN, NODE_FLOAT, "node_ctrl_freq_shift_2", this, FX_SPECTRALIZER_PARAM_ID_FREQ_SHIFT_2),
        node_ctrl_vol_1(NODE_IN, NODE_FLOAT, "node_ctrl_vol_1", this, FX_SPECTRALIZER_PARAM_ID_VOL_1),
        node_ctrl_vol_2(NODE_IN, NODE_FLOAT, "node_ctrl_vol_2", this, FX_SPECTRALIZER_PARAM_ID_VOL_2),
        node_ctrl_vol_clean(NODE_IN, NODE_FLOAT, "node_ctrl_vol_clean", this, FX_SPECTRALIZER_PARAM_ID_VOL_CLEAN)

     {

      // Set class
      type = FX_SPECTRALIZER;

      // Set name
      strcpy(effect_name, "pitch shift (frequency domain)");

      // Set parameters
      param_freq_shift_1 = freq_1;
      param_freq_shift_2 = freq_2;
      param_vol_1 = volume_1;
      param_vol_2 = volume_2;
      param_vol_clean = volume_clean;

      // Assign programmable node names
      input = &node_input;
      output = &node_output;

      // Defaults
      param_enabled = true;

      // Initialize parameter stack
      param_stack[total_params] = &param_freq_shift_1;
      param_stack_types[total_params++] = T_FLOAT;
      param_stack[total_params] = &param_freq_shift_2;
      param_stack_types[total_params++] = T_FLOAT;
      param_stack[total_params] = &param_vol_1;
      param_stack_types[total_params++] = T_FLOAT;
      param_stack[total_params] = &param_vol_2;
      param_stack_types[total_params++] = T_FLOAT;
      param_stack[total_params] = &param_vol_clean;
      param_stack_types[total_params++] = T_FLOAT;

      // Add addiitonal notes to the control stack
      control_node_stack[total_control_nodes++] = &node_ctrl_freq_shift_1;
      control_node_stack[total_control_nodes++] = &node_ctrl_freq_shift_2;
      control_node_stack[total_control_nodes++] = &node_ctrl_vol_1;
      control_node_stack[total_control_nodes++] = &node_ctrl_vol_2;
      control_node_stack[total_control_nodes++] = &node_ctrl_vol_clean;

      freq_shift_1 = &node_ctrl_freq_shift_1;
      freq_shift_2 = &node_ctrl_freq_shift_2;
      vol_1 = &node_ctrl_vol_1;
      vol_2 = &node_ctrl_vol_2;
      vol_clean = &node_ctrl_vol_clean;

    }

    void enable() {
      CHECK_LAST_ENABLED();
      param_enabled = true;
      parent_canvas->spi_transmit_param(FX_SPECTRALIZER, instance_id, T_BOOL, FX_PITCH_SHIFT_PARAM_ID_ENABLED, (void *) &param_enabled);
    }

    void bypass() {
      CHECK_LAST_DISABLED();
      param_enabled = false;
      parent_canvas->spi_transmit_param(FX_SPECTRALIZER, instance_id, T_BOOL, FX_PITCH_SHIFT_PARAM_ID_ENABLED, (void *) &param_enabled);
    }

    void set_freq_shift_1(float new_freq_shift) {

      CHECK_LAST(new_freq_shift, param_freq_shift_1);

      // If this node is being controlled by a controller, don't allow a direct write to it
      if (node_ctrl_freq_shift_1.connected) {
        return;
      }

      param_freq_shift_1 = new_freq_shift;
      parent_canvas->spi_transmit_param(FX_SPECTRALIZER, instance_id, T_FLOAT, FX_SPECTRALIZER_PARAM_ID_FREQ_SHIFT_1, (void *) &param_freq_shift_1);
    }

    void set_freq_shift_2(float new_freq_shift) {

      CHECK_LAST(new_freq_shift, param_freq_shift_2);

      // If this node is being controlled by a controller, don't allow a direct write to it
      if (node_ctrl_freq_shift_2.connected) {
        return;
      }

      param_freq_shift_2 = new_freq_shift;
      parent_canvas->spi_transmit_param(FX_SPECTRALIZER, instance_id, T_FLOAT, FX_SPECTRALIZER_PARAM_ID_FREQ_SHIFT_2, (void *) &param_freq_shift_2);
    }

    void set_vol_1(float new_vol_1) {

      CHECK_LAST(new_vol_1, param_vol_1);

      // If this node is being controlled by a controller, don't allow a direct write to it
      if (node_ctrl_vol_1.connected) {
        return;
      }

      param_vol_1 = new_vol_1;
      parent_canvas->spi_transmit_param(FX_SPECTRALIZER, instance_id, T_FLOAT, FX_SPECTRALIZER_PARAM_ID_VOL_1, (void *) &param_vol_1);
    }

    void set_vol_2(float new_vol_2) {

      CHECK_LAST(new_vol_2, param_vol_2);

      // If this node is being controlled by a controller, don't allow a direct write to it
      if (node_ctrl_vol_2.connected) {
        return;
      }

      param_vol_2 = new_vol_2;
      parent_canvas->spi_transmit_param(FX_SPECTRALIZER, instance_id, T_FLOAT, FX_SPECTRALIZER_PARAM_ID_VOL_2, (void *) &param_vol_2);
    }

    void set_vol_clean(float new_vol_clean) {

      CHECK_LAST(new_vol_clean, param_vol_clean);

      // If this node is being controlled by a controller, don't allow a direct write to it
      if (node_ctrl_vol_clean.connected) {
        return;
      }

      param_vol_clean = new_vol_clean;
      parent_canvas->spi_transmit_param(FX_SPECTRALIZER, instance_id, T_FLOAT, FX_SPECTRALIZER_PARAM_ID_VOL_CLEAN, (void *) &param_vol_clean);
    }

    void  print_params(void) {

      Serial.println("Parameters:");
      print_parameter( &param_enabled, "Enabled", T_BOOL );

      print_parameter( &param_freq_shift_1, "Pitch shift #1", T_FLOAT );
      print_parameter( &param_vol_1, "Volume #1", T_FLOAT );
      print_parameter( &param_freq_shift_2, "Pitch shift #2", T_FLOAT );
      print_parameter( &param_vol_2, "Volume #2", T_FLOAT );
      print_parameter( &param_vol_clean, "Clean mix/volume", T_FLOAT );

      Serial.println("Control Routing:");
      print_ctrl_node_status(&node_ctrl_freq_shift_1);
      print_ctrl_node_status(&node_ctrl_vol_1);
      print_ctrl_node_status(&node_ctrl_freq_shift_2);
      print_ctrl_node_status(&node_ctrl_vol_2);
      print_ctrl_node_status(&node_ctrl_vol_clean);

      Serial.println("Audio Routing:");
      print_audio_node_status(&node_input);
      print_audio_node_status(&node_output);

    }
};

#endif  // DM_FX_SPECTRALIZER_H