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

audiofx_timebased.cpp

// ------------------------------------------------------------------------
// audiofx_timebased.cpp: Routines for time-based effects.
// Copyright (C) 1999-2004 Kai Vehmanen
//
// Attributes:
//     eca-style-version: 2
//
// 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 <assert.h>
#include <string>

#include <kvu_dbc.h>
#include <kvu_utils.h>

#include "eca-logger.h"

#include "samplebuffer_iterators.h"
#include "sample-ops_impl.h"
#include "audiofx_timebased.h"


EFFECT_DELAY::EFFECT_DELAY (CHAIN_OPERATOR::parameter_t delay_time, int surround_mode, 
                      int num_of_delays, CHAIN_OPERATOR::parameter_t mix_percent,
                      CHAIN_OPERATOR::parameter_t feedback_percent) 
{
  laskuri = 0.0;

  set_parameter(1, delay_time);
  set_parameter(2, surround_mode);
  set_parameter(3, num_of_delays);
  set_parameter(4, mix_percent);
  set_parameter(5, feedback_percent);
}

00049 void EFFECT_DELAY::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  switch (param) {
  case 1:
    pd->default_value = 100.0f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = false;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = false;
    pd->integer = false;
    pd->logarithmic = false;
    pd->output = false;
    break;
  case 2:
    pd->default_value = 0.0f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = true;
    pd->upper_bound = 1.0f;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = true;
    pd->integer = true;
    pd->logarithmic = false;
    pd->output = false;
    break;
  case 3:
    pd->default_value = 1.0f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = false;
    // pd->upper_bound = 0.0f;
    pd->bounded_below = true;
    pd->lower_bound = 1.0f;
    pd->toggled = false;
    pd->integer = true;
    pd->logarithmic = false;
    pd->output = false;
    break;
  case 4:
    pd->default_value = 50.0f;
    pd->description = get_parameter_name(param);
    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;
  case 5:
    pd->default_value = 100.0f;
    pd->description = get_parameter_name(param);
    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: {}
  }
}

00115 CHAIN_OPERATOR::parameter_t EFFECT_DELAY::get_parameter(int param) const
{
  switch (param) {
  case 1: 
    return dtime_msec;
  case 2:
    return surround;
  case 3:
    return dnum;
  case 4:
    return mix * 100.0;
  case 5:
    return feedback * 100.0;
  }
  return 0.0;
}

void EFFECT_DELAY::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
{
  switch (param) {
  case 1:
    {
      dtime_msec = value;
      dtime = dtime_msec * (CHAIN_OPERATOR::parameter_t)samples_per_second() / 1000;
      std::vector<std::vector<SINGLE_BUFFER> >::iterator p = buffer.begin();
      while(p != buffer.end()) {
      std::vector<SINGLE_BUFFER>::iterator q = p->begin();
      while(q != p->end()) {
        if (q->size() > dtime) {
          q->resize(static_cast<unsigned int>(dtime));
          laskuri = dtime;
        }
        ++q;
      }
      ++p;
      }
      break;
    }

  case 2: 
    surround = value;
    break;

  case 3: 
    {
      if (value != 0.0) dnum = static_cast<long int>(value);
      else dnum = 1.0;
      std::vector<std::vector<SINGLE_BUFFER> >::iterator p = buffer.begin();
      while(p != buffer.end()) {
      p->resize(static_cast<unsigned int>(dnum));
      ++p;
      }
      laskuri = 0;
      break;
    }

  case 4:
    mix = value / 100.0;
    break;

  case 5:
    if (value == 0 || value > 100) {
      feedback = 1.0;
    } else {
    feedback = value / 100.0;
    }
    break;
  }
}

00185 void EFFECT_DELAY::init(SAMPLE_BUFFER* insample)
{
  l.init(insample);
  r.init(insample);

  EFFECT_BASE::init(insample);

  set_parameter(1, dtime_msec);

  buffer.resize(2, std::vector<SINGLE_BUFFER> (static_cast<unsigned int>(dnum)));
}

00197 void EFFECT_DELAY::process(void)
{
  l.begin(SAMPLE_SPECS::ch_left);
  r.begin(SAMPLE_SPECS::ch_right);

  while(!l.end() && !r.end()) {
    SAMPLE_SPECS::sample_t temp2_left = 0.0;
    SAMPLE_SPECS::sample_t temp2_right = 0.0;

    // Initializing the feedback factor to one. (x*1 = x)
    SAMPLE_SPECS::sample_t feedfact = 1;

    for(int nm2 = 0; nm2 < dnum; nm2++) {
      SAMPLE_SPECS::sample_t temp_left = 0.0;
      SAMPLE_SPECS::sample_t temp_right = 0.0;

      // Preparing the factor...
      feedfact *= feedback;

      if (laskuri >= dtime * (nm2 + 1)) {
 
      switch ((int)surround) {
      case 0: 
        {
          // ---
          // surround
          temp_left = buffer[SAMPLE_SPECS::ch_left][nm2].front();
          temp_right = buffer[SAMPLE_SPECS::ch_right][nm2].front();
          break;
        }

      case 1: 
        {
          // ---
          // surround
          temp_left = buffer[SAMPLE_SPECS::ch_right][nm2].front();
          temp_right = buffer[SAMPLE_SPECS::ch_left][nm2].front();
          break;
        }
      case 2: 
        {
          if (nm2 % 2 == 0) {
            temp_left = (buffer[SAMPLE_SPECS::ch_left][nm2].front()
                     + 
                     buffer[SAMPLE_SPECS::ch_right][nm2].front()) / 2.0;
            temp_right = 0.0;
          }
          else {
            temp_right = (buffer[SAMPLE_SPECS::ch_left][nm2].front()
                     + 
                     buffer[SAMPLE_SPECS::ch_right][nm2].front()) / 2.0;
            temp_left = 0.0;
          }
          break;
      }
      } // switch

      // Applying the reduction.
      temp_left *= feedfact;
      temp_right *= feedfact;

      buffer[SAMPLE_SPECS::ch_left][nm2].pop_front();
      buffer[SAMPLE_SPECS::ch_right][nm2].pop_front();
      }
      buffer[SAMPLE_SPECS::ch_left][nm2].push_back(*l.current());
      buffer[SAMPLE_SPECS::ch_right][nm2].push_back(*r.current());

      temp2_left += temp_left / dnum;
      temp2_right += temp_right / dnum;

    }
    *l.current() = (*l.current() * (1.0 - mix)) + (temp2_left * mix);
    *r.current() = (*r.current() * (1.0 - mix)) + (temp2_right * mix);

    l.next();
    r.next();

    if (laskuri < dtime * dnum) laskuri++;
  }
}

EFFECT_MULTITAP_DELAY::EFFECT_MULTITAP_DELAY (CHAIN_OPERATOR::parameter_t delay_time, 
                                    int num_of_delays, 
                                    CHAIN_OPERATOR::parameter_t mix_percent)
  : 
  delay_index(0),
  filled (0),
  buffer (0)
{
  set_parameter(1, delay_time);
  set_parameter(2, num_of_delays);
  set_parameter(3, mix_percent);
}

00291 void EFFECT_MULTITAP_DELAY::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  switch (param) {
  case 1:
    pd->default_value = 100.0f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = false;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = false;
    pd->integer = false;
    pd->logarithmic = false;
    pd->output = false;
    break;
  case 2:
    pd->default_value = 1.0f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = false;
    // pd->upper_bound = 0.0f;
    pd->bounded_below = true;
    pd->lower_bound = 1.0f;
    pd->toggled = false;
    pd->integer = true;
    pd->logarithmic = false;
    pd->output = false;
    break;
  case 3:
    pd->default_value = 50.0f;
    pd->description = get_parameter_name(param);
    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: {}
  }
}

00333 CHAIN_OPERATOR::parameter_t EFFECT_MULTITAP_DELAY::get_parameter(int param) const
{
  switch (param) {
  case 1: 
    return dtime_msec;
  case 2:
    return dnum;
  case 3:
    return mix * 100.0;
  }
  return 0.0;
}

void EFFECT_MULTITAP_DELAY::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
{
  switch (param) {
  case 1:
    {
      dtime_msec = value;
      dtime = static_cast<long int>(dtime_msec * (CHAIN_OPERATOR::parameter_t)samples_per_second() / 1000);
      DBC_CHECK(buffer.size() == filled.size());
      for(int n = 0; n < static_cast<int>(buffer.size()); n++) {
      if ((dtime * dnum) > static_cast<int>(buffer[n].size())) {
        buffer[n].resize(dtime * dnum);
      }
      delay_index[n] = dtime * dnum - 1;
      for(int m = 0; m < static_cast<int>(filled[n].size()); m++) {
        filled[n][m] = false;
      }
      }
      break;
    }

  case 2: 
    {
      if (value != 0.0) dnum = static_cast<long int>(value);
      else dnum = 1;
      DBC_CHECK(buffer.size() == filled.size());
      for(int n = 0; n < static_cast<int>(buffer.size()); n++) {
      if ((dtime * dnum) > static_cast<int>(buffer[n].size())) {
        buffer[n].resize(dtime * dnum);
      }
      for(int m = 0; m < static_cast<int>(filled[n].size()); m++) {
        filled[n][m] = false;
      }
      delay_index[n] = dtime * dnum - 1;
      }
      break;
    }

  case 3:
    mix = value / 100.0;
    break;
  }
}

00389 void EFFECT_MULTITAP_DELAY::init(SAMPLE_BUFFER* insample)
{
  i.init(insample);

  EFFECT_BASE::init(insample);

  set_parameter(1, dtime_msec);

  delay_index.resize(channels(), dtime * dnum - 1);
  filled.resize(channels(), std::vector<bool> (dnum, false));
  buffer.resize(channels(), std::vector<SAMPLE_SPECS::sample_t> (dtime *
                                                 dnum));
}

00403 void EFFECT_MULTITAP_DELAY::process(void)
{
  long int len = dtime * dnum;

  i.begin();
  while(!i.end()) {
    for(int n = 0; n < channels(); n++) {
      SAMPLE_SPECS::sample_t temp1 = 0.0;
      for(int nm2 = 0; nm2 < dnum; nm2++) {
      if (filled[n][nm2] == true) {
        DBC_CHECK((delay_index[n] + nm2 * dtime) % len >= 0);
        DBC_CHECK((delay_index[n] + nm2 * dtime) % len < len);
        temp1 += buffer[n][(delay_index[n] + nm2 * dtime) % len];
      }
      }
      buffer[n][delay_index[n]] = *i.current(n);
      *i.current(n) = (*i.current(n) * (1.0 - mix)) + (temp1 * mix / dnum);
    
      --(delay_index[n]);
      for(int nm2 = 0; nm2 < dnum; nm2++) {
      if (delay_index[n] < len - dtime * nm2) filled[n][nm2] = true;
      }
      if (delay_index[n] == -1) delay_index[n] = len - 1;
    }
    i.next();
  }
}

EFFECT_FAKE_STEREO::EFFECT_FAKE_STEREO (CHAIN_OPERATOR::parameter_t delay_time)
{
   set_parameter(1, delay_time);
}

00436 void EFFECT_FAKE_STEREO::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  switch (param) {
  case 1:
    pd->default_value = 20.0f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = false;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = false;
    pd->integer = false;
    pd->logarithmic = false;
    pd->output = false;
    break;
  default: {}
  }
}

00454 CHAIN_OPERATOR::parameter_t EFFECT_FAKE_STEREO::get_parameter(int param) const
{
  switch (param) {
  case 1: 
    return dtime_msec;
  }
  return 0.0;
}

void EFFECT_FAKE_STEREO::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
{
  switch (param) {
  case 1:
    dtime_msec = value;
    dtime = dtime_msec * (CHAIN_OPERATOR::parameter_t)samples_per_second() / 1000;
    std::vector<std::deque<SAMPLE_SPECS::sample_t> >::iterator p = buffer.begin();
    while(p != buffer.end()) {
      if (p->size() > dtime) {
      p->resize(static_cast<unsigned int>(dtime));
      }
      ++p;
    }
    break;
  }
}

00480 void EFFECT_FAKE_STEREO::init(SAMPLE_BUFFER* insample)
{
  l.init(insample);
  r.init(insample);

  EFFECT_BASE::init(insample);

  set_parameter(1, dtime_msec);
  buffer.resize(2);
}

00491 void EFFECT_FAKE_STEREO::process(void)
{
  l.begin(SAMPLE_SPECS::ch_left);
  r.begin(SAMPLE_SPECS::ch_right);
  while(!l.end() && !r.end()) {
    SAMPLE_SPECS::sample_t temp_left = 0;
    SAMPLE_SPECS::sample_t temp_right = 0;
    if (buffer[SAMPLE_SPECS::ch_left].size() >= dtime) {
      temp_left = buffer[SAMPLE_SPECS::ch_left].front();
      temp_right = buffer[SAMPLE_SPECS::ch_right].front();

      temp_right = (temp_left + temp_right) / 2.0;
      temp_left = (*l.current() + *r.current()) / 2.0;

      buffer[SAMPLE_SPECS::ch_left].pop_front();
      buffer[SAMPLE_SPECS::ch_right].pop_front();
    }
    else {
      temp_left = (*l.current() + *r.current()) / 2.0;
      temp_right = 0.0;
    }
    buffer[SAMPLE_SPECS::ch_left].push_back(*l.current());
    buffer[SAMPLE_SPECS::ch_right].push_back(*r.current());

    *l.current() = temp_left;
    *r.current() = temp_right;

    l.next();
    r.next();
  }
}

EFFECT_REVERB::EFFECT_REVERB (CHAIN_OPERATOR::parameter_t delay_time, int surround_mode, 
                        CHAIN_OPERATOR::parameter_t feedback_percent) 
{
  set_parameter(1, delay_time);
  set_parameter(2, surround_mode);
  set_parameter(3, feedback_percent);
}

00531 void EFFECT_REVERB::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  switch (param) {
  case 1:
    pd->default_value = 20.0f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = false;
    // pd->upper_bound = 0.0f;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = false;
    pd->integer = false;
    pd->logarithmic = false;
    pd->output = false;
    break;
  case 2:
    pd->default_value = 0.0f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = true;
    pd->upper_bound = 1.0f;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = true;
    pd->integer = true;
    pd->logarithmic = false;
    pd->output = false;
    break;
  case 3:
    pd->default_value = 50.0f;
    pd->description = get_parameter_name(param);
    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: {}
  }
}

00574 CHAIN_OPERATOR::parameter_t EFFECT_REVERB::get_parameter(int param) const 
{
  switch (param) {
  case 1: 
    return dtime_msec;
  case 2:
    return surround;
  case 3:
    return feedback * 100.0;
  }
  return 0.0;
}

void EFFECT_REVERB::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
{
  switch (param) {
  case 1: 
    {
      dtime_msec = value;
      dtime = dtime_msec * (CHAIN_OPERATOR::parameter_t)samples_per_second() / 1000;
      std::vector<std::deque<SAMPLE_SPECS::sample_t> >::iterator p = buffer.begin();
      while(p != buffer.end()) {
      if (p->size() > dtime) {
        p->resize(static_cast<unsigned int>(dtime));
      }
      ++p;
      }
      break;
    }

  case 2: 
    surround = value;
    break;

  case 3: 
    feedback = value / 100.0;
    break;
  }
}

00614 void EFFECT_REVERB::init(SAMPLE_BUFFER* insample)
{
  l.init(insample);
  r.init(insample);

  EFFECT_BASE::init(insample);

  set_parameter(1, dtime_msec);

  buffer.resize(2);
}

00626 void EFFECT_REVERB::process(void)
{
  l.begin(SAMPLE_SPECS::ch_left);
  r.begin(SAMPLE_SPECS::ch_right);
  while(!l.end() && !r.end()) {
    SAMPLE_SPECS::sample_t temp_left = 0.0;
    SAMPLE_SPECS::sample_t temp_right = 0.0;
    if (buffer[SAMPLE_SPECS::ch_left].size() >= dtime) {
      temp_left = buffer[SAMPLE_SPECS::ch_left].front();
      temp_right = buffer[SAMPLE_SPECS::ch_right].front();
      
      if (surround == 0) {
      *l.current() = (*l.current() * (1 - feedback)) + (temp_left *  feedback);
      *r.current() = (*r.current() * (1 - feedback)) + (temp_right * feedback);
      }
      else {
      *l.current() = (*l.current() * (1 - feedback)) + (temp_right *  feedback);
      *r.current() = (*r.current() * (1 - feedback)) + (temp_left * feedback);
      }
      buffer[SAMPLE_SPECS::ch_left].pop_front();
      buffer[SAMPLE_SPECS::ch_right].pop_front();
    }
    else {
      *l.current() = (*l.current() * (1 - feedback));
      *r.current() = (*r.current() * (1 - feedback));
    }
    *l.current() = ecaops_flush_to_zero(*l.current());
    *r.current() = ecaops_flush_to_zero(*r.current());
    buffer[SAMPLE_SPECS::ch_left].push_back(*l.current());
    buffer[SAMPLE_SPECS::ch_right].push_back(*r.current());
    l.next();
    r.next();
  }
}

EFFECT_MODULATING_DELAY::EFFECT_MODULATING_DELAY(CHAIN_OPERATOR::parameter_t delay_time, 
                                     long int vartime_in_samples,
                                     CHAIN_OPERATOR::parameter_t feedback_percent,
                                     CHAIN_OPERATOR::parameter_t lfo_freq)
{
  set_parameter(1, delay_time);
  set_parameter(2, vartime_in_samples);
  set_parameter(3, feedback_percent);
  set_parameter(4, lfo_freq);
}

00672 void EFFECT_MODULATING_DELAY::parameter_description(int param, struct PARAM_DESCRIPTION *pd) const
{
  switch (param) {
  case 1:
    pd->default_value = 2.0f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = false;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = false;
    pd->integer = false;
    pd->logarithmic = false;
    pd->output = false;
    break;
  case 2:
    pd->default_value = 20.0f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = false;
    // pd->upper_bound = 0.0f;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = false;
    pd->integer = true;
    pd->logarithmic = false;
    pd->output = false;
    break;
  case 3:
    pd->default_value = 50.0f;
    pd->description = get_parameter_name(param);
    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;
  case 4:
    pd->default_value = 0.4f;
    pd->description = get_parameter_name(param);
    pd->bounded_above = false;
    // pd->upper_bound = 0.0f;
    pd->bounded_below = true;
    pd->lower_bound = 0.0f;
    pd->toggled = false;
    pd->integer = false;
    pd->logarithmic = false;
    pd->output = false;
    break;
  default: {}
  }
}

00726 CHAIN_OPERATOR::parameter_t EFFECT_MODULATING_DELAY::get_parameter(int param) const
{
  switch (param) {
  case 1: 
    return dtime_msec;

  case 2: 
    return vartime;

  case 3: 
    return feedback * 100.0;

  case 4: 
    return lfo.get_parameter(1);
  }
  return 0.0;
}

void EFFECT_MODULATING_DELAY::set_parameter(int param, CHAIN_OPERATOR::parameter_t value)
{
  switch (param) {
  case 1:
    {
      dtime_msec = value;
      dtime = static_cast<long int>(dtime_msec * (CHAIN_OPERATOR::parameter_t)samples_per_second() / 1000);
      if (dtime < 1) { 
      dtime = 1;
      }
      DBC_CHECK(buffer.size() == delay_index.size());
      DBC_CHECK(buffer.size() == filled.size());
      for(int n = 0; n < static_cast<int>(buffer.size()); n++) {
      if (dtime * 2 > static_cast<long int>(buffer[n].size())) {
        buffer[n].resize(dtime * 2);
      }
      delay_index[n] = 0;
      filled[n] = false;
      }
      break;
    }

  case 2: 
    vartime = value;
    break;

  case 3: 
    feedback = value / 100.0;
    break;

  case 4:
    lfo.set_parameter(1, value);
    break;
  }
}

00780 void EFFECT_MODULATING_DELAY::init(SAMPLE_BUFFER* insample)
{
  i.init(insample);
  lfo.init();
  advance_len_rep = insample->length_in_samples();

  set_parameter(1, dtime_msec);

  EFFECT_BASE::init(insample);

  filled.resize(channels(), false);
  delay_index.resize(channels(), 2 * dtime);
  buffer.resize(channels(), std::vector<SAMPLE_SPECS::sample_t> (2 * dtime));
}

00795 void EFFECT_MODULATING_DELAY::process(void)
{
  lfo.seek_position_in_samples_advance(advance_len_rep);
}

void EFFECT_MODULATING_DELAY::set_samples_per_second(SAMPLE_SPECS::sample_rate_t v)
{
  EFFECT_TIME_BASED::set_samples_per_second(v);
  lfo.set_samples_per_second(v);
}

00806 void EFFECT_FLANGER::process(void)
{
  EFFECT_MODULATING_DELAY::process();

  i.begin();
  while(!i.end()) {
    SAMPLE_SPECS::sample_t temp1 = 0.0;
    parameter_t p = vartime * lfo.value();
    if (filled[i.channel()] == true) {
      DBC_CHECK((dtime + delay_index[i.channel()] + static_cast<long int>(p)) % (dtime * 2) >= 0);
      DBC_CHECK((dtime + delay_index[i.channel()] + static_cast<long int>(p)) % (dtime * 2) < static_cast<long int>(buffer[i.channel()].size()));
      temp1 = buffer[i.channel()][(dtime + delay_index[i.channel()] + static_cast<long int>(p)) % (dtime * 2)];
    }
    *i.current() = ecaops_flush_to_zero((*i.current() * (1.0 - feedback)) + (temp1 * feedback));
    buffer[i.channel()][delay_index[i.channel()]] = *i.current();

    ++(delay_index[i.channel()]);
    if (delay_index[i.channel()] == 2 * dtime) {
      delay_index[i.channel()] = 0;
      filled[i.channel()] = true;
    }
    i.next();
  }
}

00831 void EFFECT_CHORUS::process(void)
{
  EFFECT_MODULATING_DELAY::process();

  i.begin();
  while(!i.end()) {
    SAMPLE_SPECS::sample_t temp1 = 0.0;
    parameter_t p = vartime * lfo.value();
    if (filled[i.channel()] == true) {
      DBC_CHECK((dtime + delay_index[i.channel()] + static_cast<long int>(p)) % (dtime * 2) >= 0);
      DBC_CHECK((dtime + delay_index[i.channel()] + static_cast<long int>(p)) % (dtime * 2) < static_cast<long int>(buffer[i.channel()].size()));
      temp1 = buffer[i.channel()][(dtime + delay_index[i.channel()] + static_cast<long int>(p)) % (dtime * 2)];
    }
    buffer[i.channel()][delay_index[i.channel()]] = *i.current();
    *i.current() = (*i.current() * (1.0 - feedback)) + (temp1 * feedback);

    ++(delay_index[i.channel()]);
    if (delay_index[i.channel()] == 2 * dtime) {
      delay_index[i.channel()] = 0;
      filled[i.channel()] = true;
    }
    i.next();
  }
}

00856 void EFFECT_PHASER::process(void)
{
  EFFECT_MODULATING_DELAY::process();

  i.begin();
  while(!i.end()) {
    SAMPLE_SPECS::sample_t temp1 = 0.0;
    parameter_t p = vartime * lfo.value();
    if (filled[i.channel()] == true) {
      DBC_CHECK((dtime + delay_index[i.channel()] + static_cast<long int>(p)) % (dtime * 2) >= 0);
      DBC_CHECK((dtime + delay_index[i.channel()] + static_cast<long int>(p)) % (dtime * 2) < static_cast<long int>(buffer[i.channel()].size()));
      temp1 = buffer[i.channel()][(dtime + delay_index[i.channel()] + static_cast<long int>(p)) % (dtime * 2)];
      //          cerr << "b: "
      //             << (delay_index[i.channel()] + static_cast<long int>(p)) % dtime
      //             << "," << p << ".\n";
    }
    *i.current() = ecaops_flush_to_zero(*i.current() * (1.0 - feedback) + (-1.0 * temp1 * feedback));
    buffer[i.channel()][delay_index[i.channel()]] = *i.current();

    ++(delay_index[i.channel()]);
    if (delay_index[i.channel()] == 2 * dtime) {
      delay_index[i.channel()] = 0;
      filled[i.channel()] = true;
    }
    i.next();
  }
}

Generated by  Doxygen 1.6.0   Back to index