Logo Search packages:      
Sourcecode: ecasound2.2 version File versions

audiofx_amplitude.cpp

// ------------------------------------------------------------------------
// audiofx_amplitude.cpp: Amplitude effects and dynamic processors.
// Copyright (C) 1999-2000,2003 Kai Vehmanen
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program 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 General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
// ------------------------------------------------------------------------

#include <cmath>

#include <kvu_message_item.h>

#include "samplebuffer_iterators.h"
#include "audiofx_amplitude.h"

#include "eca-logger.h"
#include "eca-error.h"

EFFECT_AMPLITUDE::~EFFECT_AMPLITUDE(void)
{
}

EFFECT_AMPLIFY::EFFECT_AMPLIFY (parameter_t multiplier_percent)
{
  set_parameter(1, multiplier_percent);
}

EFFECT_AMPLIFY::~EFFECT_AMPLIFY(void)
{
}

void EFFECT_AMPLIFY::set_parameter(int param, parameter_t value) {
  switch (param) {
  case 1: 
    gain = value / 100.0;
    break;
  }
}

00051 CHAIN_OPERATOR::parameter_t EFFECT_AMPLIFY::get_parameter(int param) const { 
  switch (param) {
  case 1: 
    return(gain * 100.0);
  }
  return(0.0);
}

00059 void EFFECT_AMPLIFY::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  OPERATOR::parameter_description(param, pd);
}

00064 void EFFECT_AMPLIFY::init(SAMPLE_BUFFER* sbuf) { i.init(sbuf); }

00066 void EFFECT_AMPLIFY::process(void) {
  i.begin();
  while(!i.end()) {
    *i.current() = *i.current() *  gain;
    i.next();
  }
}

EFFECT_AMPLIFY_CLIPCOUNT::EFFECT_AMPLIFY_CLIPCOUNT (parameter_t multiplier_percent, int max_clipped) {
  set_parameter(1, multiplier_percent);
  set_parameter(2, max_clipped);
  num_of_clipped = 0;
}

void EFFECT_AMPLIFY_CLIPCOUNT::set_parameter(int param, parameter_t value)
{
  switch (param) {
  case 1: 
    gain = value / 100.0;
    break;
  case 2:
    maxnum_of_clipped = (int)value;
    break;
  }
}

00092 CHAIN_OPERATOR::parameter_t EFFECT_AMPLIFY_CLIPCOUNT::get_parameter(int param) const
{
  switch (param) {
  case 1: 
    return(gain * 100.0);
  case 2:
    return(maxnum_of_clipped);
  }
  return(0.0);
}

00103 void EFFECT_AMPLIFY_CLIPCOUNT::init(SAMPLE_BUFFER* sbuf) { i.init(sbuf); }

00105 void EFFECT_AMPLIFY_CLIPCOUNT::process(void)
{
  i.begin();
  while(!i.end()) {
    *i.current() = *i.current() *  gain;
    if (*i.current() > SAMPLE_SPECS::impl_max_value ||
      *i.current() < SAMPLE_SPECS::impl_min_value) {
      num_of_clipped++;
    }
    else {
      num_of_clipped = 0;
    }
    i.next();
  }

  if (num_of_clipped > maxnum_of_clipped && maxnum_of_clipped != 0) {
    MESSAGE_ITEM otemp;
    otemp.setprecision(0);
    otemp << "(audiofx_amplitude) WARNING! Signal is clipping! ";
    otemp << num_of_clipped;
    otemp << " consecutive clipped samples.";
    ECA_LOG_MSG(ECA_LOGGER::info, otemp.to_string());
  }
}

00130 void EFFECT_AMPLIFY_CLIPCOUNT::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  OPERATOR::parameter_description(param, pd);
}

EFFECT_AMPLIFY_CHANNEL::EFFECT_AMPLIFY_CHANNEL (parameter_t multiplier_percent, int channel)
{
  set_parameter(1, multiplier_percent);
  set_parameter(2, channel);
}

void EFFECT_AMPLIFY_CHANNEL::set_parameter(int param, parameter_t value)
{
  switch (param) {
    case 1: 
      gain = value / 100.0;
      break;
      
    case 2: 
      if (value > 0) {
      channel_rep = static_cast<int>(value);
      channel_rep--;
      break;
      }
  }
}

00157 CHAIN_OPERATOR::parameter_t EFFECT_AMPLIFY_CHANNEL::get_parameter(int param) const
{ 
  switch (param) {
  case 1: 
    return(gain * 100.0);

  case 2: 
    return(static_cast<parameter_t>(channel_rep + 1));
  }
  return(0.0);
}

00169 void EFFECT_AMPLIFY_CHANNEL::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  OPERATOR::parameter_description(param, pd);

  switch (param) {
  case 2: 
    {
      pd->default_value = 1.0f;
      pd->bounded_above = false;
      pd->bounded_below = true;
      pd->lower_bound = 1.0f;
      pd->integer = true;
    }
  }
}

00185 void EFFECT_AMPLIFY_CHANNEL::init(SAMPLE_BUFFER *insample)
{
  EFFECT_BASE::init(insample);
  i.init(insample);
}

00191 void EFFECT_AMPLIFY_CHANNEL::process(void)
{
  if (channel_rep >= 0 && channel_rep < channels()) {
    i.begin(channel_rep);
    while(!i.end()) {
      *i.current() = *i.current() * gain;
      i.next();
    }
  }
}

EFFECT_LIMITER::EFFECT_LIMITER (parameter_t limiting_percent)
{
  set_parameter(1, limiting_percent);
}

EFFECT_LIMITER::~EFFECT_LIMITER(void)
{
}

void EFFECT_LIMITER::set_parameter(int param, parameter_t value) {
  switch (param) {
  case 1:
    limit_rep = value / 100.0;
    break;
  }
}

00219 CHAIN_OPERATOR::parameter_t EFFECT_LIMITER::get_parameter(int param) const { 
  switch (param) {
  case 1: 
    return(limit_rep * 100.0);
  }
  return(0.0);
}

00227 void EFFECT_LIMITER::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  OPERATOR::parameter_description(param, pd);
}

00232 void EFFECT_LIMITER::init(SAMPLE_BUFFER* sbuf) { i.init(sbuf); }

00234 void EFFECT_LIMITER::process(void) {
  i.begin();
  while(!i.end()) {
    if (*i.current() < 0) {
      if ((-(*i.current())) > limit_rep) 
      *i.current() = -limit_rep;
    }
    else {
      if (*i.current() > limit_rep)
      *i.current() = limit_rep;
     
    }
    i.next();
  }
}

EFFECT_COMPRESS::EFFECT_COMPRESS (parameter_t compress_rate, parameter_t thold) {
  set_parameter(1, compress_rate);
  set_parameter(2, thold);

  first_time = true;
}

EFFECT_COMPRESS::EFFECT_COMPRESS (const EFFECT_COMPRESS& x) {
  crate = x.crate;
  threshold = x.threshold;
  delta = x.delta;
  ratio = x.ratio;
  first_time = x.first_time;

  lastin = x.lastin;
  lastout = x.lastout;
}

void EFFECT_COMPRESS::set_parameter(int param, parameter_t value) {
  switch (param) {
  case 1: 
    crate = pow(2.0, value / 6.0);
    break;
  case 2: 
    threshold = value / 100.0;
    break;
  }
}

00279 CHAIN_OPERATOR::parameter_t EFFECT_COMPRESS::get_parameter(int param) const { 
  switch (param) {
  case 1: 
    return((log (crate)) / (log (2.0f)) * 6.0);
  case 2: 
    return(threshold * 100.0);
  }
  return(0.0);
}

00289 void EFFECT_COMPRESS::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  switch (param) {
  case 1:
    pd->default_value = 1.0f;
    pd->description = "compression-rate-dB";
    pd->bounded_above = true;
    pd->upper_bound = 99.0f;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = false;
    pd->integer = false;
    pd->logarithmic = true;
    pd->output = false;
    break;
  case 2:
    pd->default_value = 30.0f;
    pd->description = "threshold-%";
    pd->bounded_above = true;
    pd->upper_bound = 100.0f;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = false;
    pd->integer = false;
    pd->logarithmic = false;
    pd->output = false;
    break;
  default: {}
  }
}

00320 void EFFECT_COMPRESS::init(SAMPLE_BUFFER *insample)
{
  i.init(insample);

  set_channels(insample->number_of_channels());
  set_samples_per_second(samples_per_second());

  lastin.resize(insample->number_of_channels());
  lastout.resize(insample->number_of_channels());
} 

00331 void EFFECT_COMPRESS::process(void)
{
  i.begin();
  while(!i.end()) {
    if (first_time) {
      first_time = false;
      lastin[i.channel()] = lastout[i.channel()] = *i.current();
    }
    else {
      if (fabs(*i.current()) > threshold) {
      delta = *i.current() - lastin[i.channel()];
      delta /= crate;
      new_value = lastin[i.channel()] + delta;
      ratio = new_value / lastin[i.channel()];
      new_value = lastout[i.channel()] * ratio;

      if (new_value > SAMPLE_SPECS::impl_max_value) new_value = SAMPLE_SPECS::impl_max_value;
      else if (new_value < SAMPLE_SPECS::impl_min_value) new_value = SAMPLE_SPECS::impl_min_value;

      lastin[i.channel()] = *i.current();
      *i.current() = lastout[i.channel()] = new_value;
      }
      else {
      lastin[i.channel()] = lastout[i.channel()] = *i.current();
      }
    }
    i.next();
  }
}

EFFECT_NOISEGATE::EFFECT_NOISEGATE (parameter_t thlevel_percent, 
                            parameter_t thtime, 
                            parameter_t a, 
                            parameter_t h, 
                            parameter_t r)
{
  // map_parameters();

  set_parameter(1, thlevel_percent);
  set_parameter(2, thtime);
  set_parameter(3, a);
  set_parameter(4, h);
  set_parameter(5, r);
}

void EFFECT_NOISEGATE::set_parameter(int param, parameter_t value) {
  switch (param) {
  case 1: 
    th_level = SAMPLE_SPECS::max_amplitude * (value / 100.0);
    break;
  case 2: 
    th_time = (value * (parameter_t)samples_per_second() / 1000.0);
    break;
  case 3: 
    atime = (value * (parameter_t)samples_per_second() / 1000.0);
    break;
  case 4: 
    htime = (value * (parameter_t)samples_per_second() / 1000.0);
    break;
  case 5: 
    rtime = (value * (parameter_t)samples_per_second() / 1000.0);
    break;
  }
}

00396 CHAIN_OPERATOR::parameter_t EFFECT_NOISEGATE::get_parameter(int param) const
{ 
  switch (param) {
  case 1: 
    return(th_level * 100.0 / (parameter_t)SAMPLE_SPECS::max_amplitude);
  case 2: 
    return(th_time * 1000.0 / (parameter_t)samples_per_second());
  case 3: 
    return(atime * 1000.0 / (parameter_t)samples_per_second());
  case 4: 
    return(htime * 1000.0 / (parameter_t)samples_per_second());
  case 5: 
    return(rtime * 1000.0 / (parameter_t)samples_per_second());
  }
  return(0.0);
}

00413 void EFFECT_NOISEGATE::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  OPERATOR::parameter_description(param, pd);
}

00418 void EFFECT_NOISEGATE::init(SAMPLE_BUFFER *insample)
{
  i.init(insample);

  set_channels(insample->number_of_channels());
  set_samples_per_second(samples_per_second());

  th_time_lask.resize(insample->number_of_channels());
  attack_lask.resize(insample->number_of_channels());
  hold_lask.resize(insample->number_of_channels());
  release_lask.resize(insample->number_of_channels());
  gain.resize(insample->number_of_channels());

  ng_status.resize(insample->number_of_channels(), int(ng_waiting));
}

00434 void EFFECT_NOISEGATE::process(void)
{
  i.begin();
  while(!i.end()) {
    bool below = fabs(*i.current()) <= th_level;

    switch(ng_status[i.channel()]) 
      {
      case ng_waiting: 
      // ---
      // phase 1 - waiting
      // ---
      {
        if (below) {
          th_time_lask[i.channel()]++;
          if (th_time_lask[i.channel()] >= th_time) {
            th_time_lask[i.channel()] = 0.0;
            ng_status[i.channel()] = ng_attacking;
            ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from waiting to attacking");
          }
        }
        else {
          th_time_lask[i.channel()] = 0;
        }
        break;
      }

      case ng_attacking: 
      // ---
      // phase 2 - attack
      // ---
      {
        if (below) {
          attack_lask[i.channel()]++;
          gain[i.channel()] = (1.0 - (attack_lask[i.channel()] / atime));
          if (attack_lask[i.channel()] >= atime) {
            attack_lask[i.channel()] = 0.0;
            ng_status[i.channel()] = ng_active;
            gain[i.channel()] = 0.0;
            ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from attack to active");
          }
          *i.current() = *i.current() * gain[i.channel()];
        }
        else {
          attack_lask[i.channel()] = 0;
          ng_status[i.channel()] = ng_waiting;
          ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from attack to waiting");
        }
        break;
      }

      case ng_active: 
      // ---
      // phase 3 - active
      // ---
      {
        if (below == false) {
          ng_status[i.channel()] = ng_holding;
          ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from active to holding");
        }
        *i.current() = *i.current() * 0.0;
        break;
      }

      case ng_holding: 
      // ---
      // phase 4 - holding
      // ---
      {
        if (!below) {
          hold_lask[i.channel()]++;
          if (hold_lask[i.channel()] >= htime) {
            hold_lask[i.channel()] = 0.0;
            ng_status[i.channel()] = ng_releasing;
            ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from holding to release");
          }
        }
        *i.current() = *i.current() * 0.0;
        break;
      }

      case ng_releasing: 
      // ---
      // phase 5 - releasing
      // ---
      {
        release_lask[i.channel()]++;
        gain[i.channel()] = release_lask[i.channel()] / rtime;
        if (release_lask[i.channel()] >= rtime) {
          release_lask[i.channel()] = 0.0;
          ng_status[i.channel()] = ng_waiting;
          ECA_LOG_MSG(ECA_LOGGER::user_objects,"(audiofx) noisegate - from releasing to waiting");
        }
        *i.current() = *i.current() * gain[i.channel()];
        break;
      }
      }

    i.next();
  }
}

EFFECT_NORMAL_PAN::EFFECT_NORMAL_PAN (parameter_t right_percent)
{
  set_parameter(1, right_percent);
}

void EFFECT_NORMAL_PAN::set_parameter(int param, parameter_t value)
{
  switch (param) {
  case 1: 
    right_percent_rep = value;
    if (value == 50.0) {
      l_gain = r_gain = 1.0;
    }
    else if (value < 50.0) {
      l_gain = 1.0;
      r_gain = value / 50.0;
    }
    else if (value > 50.0) {
      r_gain = 1.0;
      l_gain = (100.0 - value) / 50.0;
    }
    break;
  }
}

00561 CHAIN_OPERATOR::parameter_t EFFECT_NORMAL_PAN::get_parameter(int param) const
{
  switch (param) {
  case 1: 
    return(right_percent_rep);
  }
  return(0.0);
}

00570 void EFFECT_NORMAL_PAN::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  OPERATOR::parameter_description(param, pd);

  switch (param) {
  case 1: 
    {
      pd->default_value = 50.0f;
      pd->bounded_above = true;
      pd->upper_bound = 100.0f;
      pd->bounded_below = true;
      pd->lower_bound = 0.0f;
    }
  }
}

00586 void EFFECT_NORMAL_PAN::init(SAMPLE_BUFFER *insample) { i.init(insample); }

00588 void EFFECT_NORMAL_PAN::process(void)
{
  i.begin(0);
  while(!i.end()) {
    *i.current() = *i.current() * l_gain;
    i.next();
  }

  i.begin(1);
  while(!i.end()) {
    *i.current() = *i.current() * r_gain;
    i.next();
  }
}

Generated by  Doxygen 1.6.0   Back to index