📄 delay.cpp
字号:
/***************************************************//*! \class Delay \brief STK non-interpolating delay line class. This protected Filter subclass implements a non-interpolating digital delay-line. 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. A non-interpolating delay line is typically used in fixed delay-length applications, such as for reverberation. by Perry R. Cook and Gary P. Scavone, 1995 - 2005.*//***************************************************/#include "Delay.h"#include "Debug.h"//#define DEBUG#undef DEBUGDelay :: Delay() : Filter(){ // Default maximum delay length set to 4095.#if !defined(SYMBIAN) inputs_.resize( 4096 );#else inputs_.resize( 512 );#endif this->clear(); inPoint_ = 0; outPoint_ = 0; delay_ = 0; dcnt = 0;}Delay :: Delay(unsigned long delay, unsigned long maxDelay){ // Writing before reading allows delays from 0 to length-1. // If we want to allow a delay of maxDelay, we need a // delay-line of length = maxDelay+1. if ( maxDelay < 1 ) {#if !defined(SYMBIAN) errorString_ << "Delay::Delay: maxDelay must be > 0!\n"; handleError( StkError::FUNCTION_ARGUMENT );#endif } if ( delay > maxDelay ) {#if !defined(SYMBIAN) errorString_ << "Delay::Delay: maxDelay must be > than delay argument!\n"; handleError( StkError::FUNCTION_ARGUMENT );#endif } if ( maxDelay > inputs_.size()-1 ) { inputs_.resize( maxDelay+1 ); this->clear(); } inPoint_ = 0; this->setDelay( delay ); dcnt=0;}Delay :: ~Delay(){}void Delay :: clear(void){ for (unsigned int i=0; i<inputs_.size(); i++) inputs_[i] = 0.0; outputs_[0] = 0.0;}void Delay :: setMaximumDelay(unsigned long delay){ if ( delay < inputs_.size() ) return; if ( delay < 0 ) {#if !defined(SYMBIAN) errorString_ << "Delay::setMaximumDelay: argument (" << delay << ") less than zero!\n"; handleError( StkError::WARNING );#endif return; } else if (delay < delay_ ) {#if !defined(SYMBIAN) errorString_ << "Delay::setMaximumDelay: argument (" << delay << ") less than current delay setting (" << delay_ << ")!\n"; handleError( StkError::WARNING );#endif return; } inputs_.resize( delay + 1 );}void Delay :: setDelay(unsigned long delay){#ifdef DEBUG CStaticDebug::WriteIntN(delay);#endif if ( delay > inputs_.size() - 1 ) { // The value is too big.#if !defined(SYMBIAN) errorString_ << "Delay::setDelay: argument (" << delay << ") too big ... setting to maximum!\n"; handleError( StkError::WARNING );#endif#ifdef DEBUG
CStaticDebug::WriteInfoN( _L("Delay::setDelay -> Maxed") );
#endif
// Force delay to maximum length. outPoint_ = inPoint_ + 1; if ( outPoint_ == inputs_.size() ) outPoint_ = 0; delay_ = inputs_.size() - 1; } else if ( delay < 0 ) {#if !defined(SYMBIAN) errorString_ << "Delay::setDelay: argument (" << delay << ") less than zero ... setting to zero!\n"; handleError( StkError::WARNING );#endif#ifdef DEBUG
CStaticDebug::WriteInfoN( _L("Delay::setDelay -> minned") );
#endif
outPoint_ = inPoint_; delay_ = 0; } else { // read chases write#ifdef DEBUG
CStaticDebug::WriteInfoN( _L("Delay::setDelay -> OK'd") );
#endif
if ( inPoint_ >= delay ) outPoint_ = inPoint_ - delay; else outPoint_ = inputs_.size() + inPoint_ - delay; delay_ = delay; }}unsigned long Delay :: getDelay(void) const{ return (unsigned long) delay_;}StkFloat Delay :: energy(void) // SYMBIAN const removed: const{ unsigned long i; StkFloat e = 0; // SYMBIAN register removed if (inPoint_ >= outPoint_) { for (i=outPoint_; i<inPoint_; i++) { StkFloat t = inputs_[i]; // SYMBIAN register removed e += t*t; } } else { for (i=outPoint_; i<inputs_.size(); i++) { StkFloat t = inputs_[i]; // SYMBIAN register removed e += t*t; } for (i=0; i<inPoint_; i++) { StkFloat t = inputs_[i]; // SYMBIAN register removed e += t*t; } } return e;}StkFloat Delay :: contentsAt(unsigned long tapDelay){ unsigned long i = tapDelay; if (i < 1) {#if !defined(SYMBIAN) errorString_ << "Delay::contentsAt: argument (" << tapDelay << ") too small!"; handleError( StkError::WARNING );#endif return 0.0; } else if (i > delay_) {#if !defined(SYMBIAN) errorString_ << "Delay::contentsAt: argument (" << tapDelay << ") too big!"; handleError( StkError::WARNING );#endif return 0.0; } long tap = inPoint_ - i; if (tap < 0) // Check for wraparound. tap += inputs_.size(); return inputs_[tap];}StkFloat Delay :: lastOut(void) // SYMBIAN const removed: const{ return Filter::lastOut();}StkFloat Delay :: nextOut(void){ return inputs_[outPoint_];}StkFloat Delay :: computeSample( StkFloat input ){ // Read out next value#ifdef DEBUG if(dcnt < 5) { CStaticDebug::WriteInt(outPoint_); CStaticDebug::WriteIntN(inPoint_); CStaticDebug::WriteIntN(inputs_.size()); dcnt ++; }#endif // Write input inputs_[inPoint_++] = input; // Check for end condition if (inPoint_ == inputs_.size()) inPoint_ = 0; outputs_[0] = inputs_[outPoint_++]; if (outPoint_ == inputs_.size()) outPoint_ = 0; return outputs_[0];}StkFloat Delay :: tick( StkFloat input ){ return computeSample( input );}StkFrames& Delay :: tick( StkFrames& frames, unsigned int channel ){ return Filter::tick( frames, channel );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -