1 /***************************************************/ 2 /*! \class FormSwep 3 \brief STK sweepable formant filter class. 4 5 This class implements a formant (resonance) which can be "swept" 6 over time from one frequency setting to another. It provides 7 methods for controlling the sweep rate and target frequency. 8 9 by Perry R. Cook and Gary P. Scavone, 1995--2021. 10 */ 11 /***************************************************/ 12 13 #include "FormSwep.h" 14 #include <cmath> 15 16 namespace stk { 17 18 FormSwep :: FormSwep( void ) 19 { 20 frequency_ = 0.0; 21 radius_ = 0.0; 22 targetGain_ = 1.0; 23 targetFrequency_ = 0.0; 24 targetRadius_ = 0.0; 25 deltaGain_ = 0.0; 26 deltaFrequency_ = 0.0; 27 deltaRadius_ = 0.0; 28 sweepState_ = 0.0; 29 sweepRate_ = 0.002; 30 dirty_ = false; 31 32 b_.resize( 3, 0.0 ); 33 a_.resize( 3, 0.0 ); 34 a_[0] = 1.0; 35 inputs_.resize( 3, 1, 0.0 ); 36 outputs_.resize( 3, 1, 0.0 ); 37 38 Stk::addSampleRateAlert( this ); 39 } 40 41 FormSwep :: ~FormSwep() 42 { 43 Stk::removeSampleRateAlert( this ); 44 } 45 46 void FormSwep :: sampleRateChanged( StkFloat newRate, StkFloat oldRate ) 47 { 48 if ( !ignoreSampleRateChange_ ) { 49 oStream_ << "FormSwep::sampleRateChanged: you may need to recompute filter coefficients!"; 50 handleError( StkError::WARNING ); 51 } 52 } 53 54 void FormSwep :: setResonance( StkFloat frequency, StkFloat radius ) 55 { 56 #if defined(_STK_DEBUG_) 57 if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) { 58 oStream_ << "FormSwep::setResonance: frequency argument (" << frequency << ") is out of range!"; 59 handleError( StkError::WARNING ); return; 60 } 61 if ( radius < 0.0 || radius >= 1.0 ) { 62 oStream_ << "FormSwep::setResonance: radius argument (" << radius << ") is out of range!"; 63 handleError( StkError::WARNING ); return; 64 } 65 #endif 66 67 radius_ = radius; 68 frequency_ = frequency; 69 70 a_[2] = radius * radius; 71 a_[1] = -2.0 * radius * cos( TWO_PI * frequency / Stk::sampleRate() ); 72 73 // Use zeros at +- 1 and normalize the filter peak gain. 74 b_[0] = 0.5 - 0.5 * a_[2]; 75 b_[1] = 0.0; 76 b_[2] = -b_[0]; 77 } 78 79 void FormSwep :: setStates( StkFloat frequency, StkFloat radius, StkFloat gain ) 80 { 81 dirty_ = false; 82 83 if ( frequency_ != frequency || radius_ != radius ) 84 this->setResonance( frequency, radius ); 85 86 gain_ = gain; 87 targetFrequency_ = frequency; 88 targetRadius_ = radius; 89 targetGain_ = gain; 90 } 91 92 void FormSwep :: setTargets( StkFloat frequency, StkFloat radius, StkFloat gain ) 93 { 94 if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) { 95 oStream_ << "FormSwep::setTargets: frequency argument (" << frequency << ") is out of range!"; 96 handleError( StkError::WARNING ); return; 97 } 98 if ( radius < 0.0 || radius >= 1.0 ) { 99 oStream_ << "FormSwep::setTargets: radius argument (" << radius << ") is out of range!"; 100 handleError( StkError::WARNING ); return; 101 } 102 103 dirty_ = true; 104 startFrequency_ = frequency_; 105 startRadius_ = radius_; 106 startGain_ = gain_; 107 targetFrequency_ = frequency; 108 targetRadius_ = radius; 109 targetGain_ = gain; 110 deltaFrequency_ = frequency - frequency_; 111 deltaRadius_ = radius - radius_; 112 deltaGain_ = gain - gain_; 113 sweepState_ = 0.0; 114 } 115 116 void FormSwep :: setSweepRate( StkFloat rate ) 117 { 118 if ( rate < 0.0 || rate > 1.0 ) { 119 oStream_ << "FormSwep::setSweepRate: argument (" << rate << ") is out of range!"; 120 handleError( StkError::WARNING ); return; 121 } 122 123 sweepRate_ = rate; 124 } 125 126 void FormSwep :: setSweepTime( StkFloat time ) 127 { 128 if ( time <= 0.0 ) { 129 oStream_ << "FormSwep::setSweepTime: argument (" << time << ") must be > 0.0!"; 130 handleError( StkError::WARNING ); return; 131 } 132 133 this->setSweepRate( 1.0 / ( time * Stk::sampleRate() ) ); 134 } 135 136 } // stk namespace 137