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

DelayL.cpp

/***************************************************/
/*! \class DelayL
    \brief STK linear interpolating delay line class.

    This Delay subclass implements a fractional-
    length digital delay-line using first-order
    linear interpolation.  A fixed maximum length
    of 4095 and a delay of zero is set using the
    default constructor.  Alternatively, the
    delay and maximum length can be set during
    instantiation with an overloaded constructor.

    Linear interpolation is an efficient technique
    for achieving fractional delay lengths, though
    it does introduce high-frequency signal
    attenuation to varying degrees depending on the
    fractional delay setting.  The use of higher
    order Lagrange interpolators can typically
    improve (minimize) this attenuation characteristic.

    by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
*/
/***************************************************/

#include "DelayL.h"

00027 DelayL :: DelayL() : Delay()
{
  doNextOut_ = true;
}

00032 DelayL :: DelayL(StkFloat delay, unsigned long maxDelay)
{
  if ( delay < 0.0 || maxDelay < 1 ) {
    errorString_ << "DelayL::DelayL: delay must be >= 0.0, maxDelay must be > 0!";
    handleError( StkError::FUNCTION_ARGUMENT );
  }

  if ( delay > (StkFloat) maxDelay ) {
    errorString_ << "DelayL::DelayL: maxDelay must be > than delay argument!";
    handleError( StkError::FUNCTION_ARGUMENT );
  }

  // Writing before reading allows delays from 0 to length-1. 
  if ( maxDelay > inputs_.size()-1 ) {
    inputs_.resize( maxDelay+1 );
    this->clear();
  }

  inPoint_ = 0;
  this->setDelay(delay);
  doNextOut_ = true;
}

00055 DelayL :: ~DelayL()
{
}

00059 void DelayL :: setDelay(StkFloat delay)
{
  StkFloat outPointer;

  if ( delay > inputs_.size() - 1 ) { // The value is too big.
    errorString_ << "DelayL::setDelay: argument (" << delay << ") too big ... setting to maximum!";
    handleError( StkError::WARNING );

    // Force delay to maxLength
    outPointer = inPoint_ + 1.0;
    delay_ = inputs_.size() - 1;
  }
  else if (delay < 0 ) {
    errorString_ << "DelayL::setDelay: argument (" << delay << ") less than zero ... setting to zero!";
    handleError( StkError::WARNING );

    outPointer = inPoint_;
    delay_ = 0;
  }
  else {
    outPointer = inPoint_ - delay;  // read chases write
    delay_ = delay;
  }

  while (outPointer < 0)
    outPointer += inputs_.size(); // modulo maximum length

  outPoint_ = (long) outPointer;   // integer part
  if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
  alpha_ = outPointer - outPoint_; // fractional part
  omAlpha_ = (StkFloat) 1.0 - alpha_;
}

00092 StkFloat DelayL :: getDelay(void) const
{
  return delay_;
}

00097 StkFloat DelayL :: nextOut(void)
{
  if ( doNextOut_ ) {
    // First 1/2 of interpolation
    nextOutput_ = inputs_[outPoint_] * omAlpha_;
    // Second 1/2 of interpolation
    if (outPoint_+1 < inputs_.size())
      nextOutput_ += inputs_[outPoint_+1] * alpha_;
    else
      nextOutput_ += inputs_[0] * alpha_;
    doNextOut_ = false;
  }

  return nextOutput_;
}

StkFloat DelayL :: computeSample( StkFloat input )
{
  inputs_[inPoint_++] = input;

  // Increment input pointer modulo length.
  if (inPoint_ == inputs_.size())
    inPoint_ = 0;

  outputs_[0] = nextOut();
  doNextOut_ = true;

  // Increment output pointer modulo length.
  if (++outPoint_ == inputs_.size())
    outPoint_ = 0;

  return outputs_[0];
}


Generated by  Doxygen 1.6.0   Back to index