📄 flute.cpp
字号:
/***************************************************//*! \class Flute \brief STK flute physical model class. This class implements a simple flute physical model, as discussed by Karjalainen, Smith, Waryznyk, etc. The jet model uses a polynomial, a la Cook. This is a digital waveguide model, making its use possibly subject to patents held by Stanford University, Yamaha, and others. Control Change Numbers: - Jet Delay = 2 - Noise Gain = 4 - Vibrato Frequency = 11 - Vibrato Gain = 1 - Breath Pressure = 128 by Perry R. Cook and Gary P. Scavone, 1995 - 2005.*//***************************************************/#include "Flute.h"#include "SKINI.msg"Flute :: Flute(StkFloat lowestFrequency){ length_ = (unsigned long) (Stk::sampleRate() / lowestFrequency + 1); boreDelay_.setMaximumDelay( length_ ); boreDelay_.setDelay( 100.0 ); length_ >>= 1; jetDelay_.setMaximumDelay( length_ ); jetDelay_.setDelay( 49.0 ); vibrato_.setFrequency( 5.925 ); this->clear(); filter_.setPole( 0.7 - ((StkFloat) 0.1 * 22050.0 / Stk::sampleRate() ) ); filter_.setGain( -1.0 ); dcBlock_.setBlockZero(); adsr_.setAllTimes( 0.005, 0.01, 0.8, 0.010); endReflection_ = 0.5; jetReflection_ = 0.5; noiseGain_ = 0.15; // Breath pressure random component. vibratoGain_ = 0.05; // Breath periodic vibrato component. jetRatio_ = 0.32; maxPressure_ = 0.0; lastFrequency_ = 220.0;}Flute :: ~Flute(){}void Flute :: clear(){ jetDelay_.clear(); boreDelay_.clear(); filter_.clear(); dcBlock_.clear();}void Flute :: setFrequency(StkFloat frequency){ lastFrequency_ = frequency; if ( frequency <= 0.0 ) {#if !defined(SYMBIAN) errorString_ << "Flute::setFrequency: parameter is less than or equal to zero!"; handleError( StkError::WARNING );#endif lastFrequency_ = 220.0; } // We're overblowing here. lastFrequency_ *= 0.66666; // delay = length - approximate filter delay. StkFloat delay = Stk::sampleRate() / lastFrequency_ - (StkFloat) 2.0; if ( delay <= 0.0 ) delay = 0.3; else if ( delay > length_ ) delay = length_; boreDelay_.setDelay(delay); jetDelay_.setDelay(delay * jetRatio_);}void Flute :: startBlowing(StkFloat amplitude, StkFloat rate){ adsr_.setAttackRate( rate ); maxPressure_ = amplitude / (StkFloat) 0.8; adsr_.keyOn();}void Flute :: stopBlowing(StkFloat rate){ adsr_.setReleaseRate( rate ); adsr_.keyOff();}void Flute :: noteOn(StkFloat frequency, StkFloat amplitude){ this->setFrequency( frequency ); this->startBlowing( 1.1 + (amplitude * 0.20), amplitude * 0.02 ); outputGain_ = amplitude + 0.001;#if defined(_STK_DEBUG_) errorString_ << "Flute::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << "."; handleError( StkError::DEBUG_WARNING );#endif}void Flute :: noteOff(StkFloat amplitude){ this->stopBlowing( amplitude * 0.02 );#if defined(_STK_DEBUG_) errorString_ << "Flute::NoteOff: amplitude = " << amplitude << "."; handleError( StkError::DEBUG_WARNING );#endif}void Flute :: setJetReflection(StkFloat coefficient){ jetReflection_ = coefficient;}void Flute :: setEndReflection(StkFloat coefficient){ endReflection_ = coefficient;} void Flute :: setJetDelay(StkFloat aRatio){ // Delay = length - approximate filter delay. StkFloat temp = Stk::sampleRate() / lastFrequency_ - (StkFloat) 2.0; jetRatio_ = aRatio; jetDelay_.setDelay(temp * aRatio); // Scaled by ratio.}StkFloat Flute :: computeSample(){ StkFloat pressureDiff; StkFloat breathPressure; // Calculate the breath pressure (envelope + noise + vibrato) breathPressure = maxPressure_ * adsr_.tick(); breathPressure += breathPressure * ( noiseGain_ * noise_.tick() + vibratoGain_ * vibrato_.tick() ); //breathPressure += breathPressure * vibratoGain_ * vibrato_.tick(); StkFloat temp = filter_.tick( boreDelay_.lastOut() ); temp = dcBlock_.tick( temp ); // Block DC on reflection. pressureDiff = breathPressure - (jetReflection_ * temp); pressureDiff = jetDelay_.tick( pressureDiff ); pressureDiff = jetTable_.tick( pressureDiff ) + (endReflection_ * temp); lastOutput_ = (StkFloat) 0.3 * boreDelay_.tick( pressureDiff ); lastOutput_ *= outputGain_; return lastOutput_;}void Flute :: controlChange(int number, StkFloat value){ StkFloat norm = value * ONE_OVER_128; if ( norm < 0 ) { norm = 0.0;#if !defined(SYMBIAN) errorString_ << "Flute::controlChange: control value less than zero ... setting to zero!"; handleError( StkError::WARNING );#endif } else if ( norm > 1.0 ) { norm = 1.0;#if !defined(SYMBIAN) errorString_ << "Flute::controlChange: control value greater than 128.0 ... setting to 128.0!"; handleError( StkError::WARNING );#endif } if (number == __SK_JetDelay_) // 2 this->setJetDelay( (StkFloat) (0.08 + (0.48 * norm)) ); else if (number == __SK_NoiseLevel_) // 4 noiseGain_ = ( norm * 0.4); else if (number == __SK_ModFrequency_) // 11 vibrato_.setFrequency( norm * 12.0); else if (number == __SK_ModWheel_) // 1 vibratoGain_ = ( norm * 0.4 ); else if (number == __SK_AfterTouch_Cont_) // 128 adsr_.setTarget( norm ); else {#if !defined(SYMBIAN) errorString_ << "Flute::controlChange: undefined control number (" << number << ")!"; handleError( StkError::WARNING );#endif }#if defined(_STK_DEBUG_)#if !defined(SYMBIAN) errorString_ << "Flute::controlChange: number = " << number << ", value = " << value << "."; handleError( StkError::DEBUG_WARNING );#endif#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -