Logo Search packages:      
Sourcecode: abgate version File versions  Download package

gate.cpp

/* abGate - LV2 Noise Gate Plugin
 *
 * Copyright 2011 Antanas Bru┼żas
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <stdlib.h>
#include <lv2.h>
#include <cmath>

#include "gate_const.h"

#define CLOSED 1
#define ATTACK 2
#define OPENED 3
#define DECAY 4

static LV2_Descriptor *gateDescriptor = NULL;

00032 class Gate {
      public:
            Gate() {
                  state = CLOSED;
                  gate = 0;
                  holding = 0;
                  input_db = 0;
            }
            virtual ~Gate();

            bool bypass;
            float *switch_button, *threshold, *attack, *hold, *decay, *range, input_db, sample_rate, gate, range_coef, attack_coef, decay_coef, *output;
            const float *input;
            int state, holding;
};

static LV2_Handle instantiateGate(const _LV2_Descriptor *descriptor, double s_rate, const char *path, const LV2_Feature * const* features) {
      Gate *plugin_data = (Gate *)malloc(sizeof(Gate));
      plugin_data->sample_rate = s_rate;
      return (LV2_Handle)plugin_data;
}

static void connectPortGate(LV2_Handle instance, uint32_t port, void *data) {
      Gate *plugin = (Gate *)instance;

      switch (port) {
            case p_switch:
                  plugin->switch_button = (float*)data;
                  break;
            case p_threshold:
                  plugin->threshold = (float*)data;
                  break;
            case p_attack:
                  plugin->attack = (float*)data;
                  break;
            case p_hold:
                  plugin->hold = (float*)data;
                  break;
            case p_decay:
                  plugin->decay = (float*)data;
                  break;
            case p_gaterange:
                  plugin->range = (float*)data;
                  break;
            case p_input:
                  plugin->input = (const float*)data;
                  break;
            case p_output:
                  plugin->output = (float*)data;
                  break;
      }
}

static void runGate(LV2_Handle instance, uint32_t sample_count) {

      Gate *plugin_data = (Gate *)instance;

      float * const output = plugin_data->output;
      const float * const input = plugin_data->input;

      // Checking bypass state
      float switch_button = *(plugin_data->switch_button);
      switch_button = switch_button < 0 ? 0 : switch_button;
      switch_button = switch_button > 1 ? 1 : switch_button;

      bool bypass = switch_button > 0 ? true : false;
      if (bypass != false) {

            // Getting port values
            const float threshold = *(plugin_data->threshold);
            const float attack = *(plugin_data->attack);
            const float hold = *(plugin_data->hold);
            const float decay = *(plugin_data->decay);
            const float range = *(plugin_data->range);

            float sample_rate = plugin_data->sample_rate;
            int state = plugin_data->state;
            float gate = plugin_data->gate;
            int holding = plugin_data->holding;
            float input_db = plugin_data->input_db;

            float range_coef = range > -90 ? pow(10, range * 0.05) : 0;
            float attack_coef = 1000 / (attack * sample_rate);
            float decay_coef = 1000 / (decay * sample_rate);
            
            for (uint32_t i = 0; i < sample_count; ++i) {

                  // Counting input dB
                  input_db = 20 * log10(fabs(input[i]));
                  switch (state){
                        case CLOSED:
                              if (input_db >= threshold) { state = ATTACK; }
                              break;
                        case ATTACK:
                              // attacking :)
                              gate += attack_coef;
                              if (gate >= 1) {
                                    gate = 1;
                                    state = OPENED;
                                    holding = round(hold * sample_rate * 0.001);
                              }
                              break;
                        case OPENED:
                              if (holding <= 0) {
                                    if (input_db < threshold) { state = DECAY; }
                              }
                              else { holding--; }
                              break;
                        case DECAY:
                              gate -= decay_coef;
                              if (input_db >= threshold) { state = ATTACK; }
                              else if (gate <= 0) {
                                    gate = 0;
                                    state = CLOSED;
                              }
                              break;
                        default:
                              state = CLOSED;
                  }
                  output[i] = input[i] * (range_coef * (1 - gate) + gate);
            }     
            plugin_data->input_db = input_db;
                  plugin_data->gate = gate;
                  plugin_data->state = state;
                  plugin_data->holding = holding;     
      }
      else {
            // Bypassing
            for (uint32_t i = 0; i < sample_count; ++i) { output[i] = input[i]; }
      }
}

static void cleanupGate(LV2_Handle instance) {
      free(instance);
}

static void init() {

      gateDescriptor = (LV2_Descriptor *)malloc(sizeof(LV2_Descriptor));
      gateDescriptor->URI = p_uri;
      gateDescriptor->instantiate = instantiateGate;
      gateDescriptor->connect_port = connectPortGate;
      gateDescriptor->activate = NULL;
      gateDescriptor->run = runGate;
      gateDescriptor->deactivate = NULL;
      gateDescriptor->cleanup = cleanupGate;
      gateDescriptor->extension_data = NULL;
}

LV2_SYMBOL_EXPORT
const LV2_Descriptor *lv2_descriptor(uint32_t index) {

      if (!gateDescriptor) { init(); }

      switch (index) {
            case 0:
                  return gateDescriptor;
            default:
                  return NULL;
      }
}

Generated by  Doxygen 1.6.0   Back to index