1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-05 06:39:26 +02:00
2010-01-24 09:19:39 +00:00

133 lines
3.5 KiB
C++

/***************************************************/
/*! \class PluckTwo
\brief STK enhanced plucked string model class.
This class implements an enhanced two-string,
plucked physical model, a la Jaffe-Smith,
Smith, and others.
PluckTwo is an abstract class, with no excitation
specified. Therefore, it can't be directly
instantiated.
This is a digital waveguide model, making its
use possibly subject to patents held by
Stanford University, Yamaha, and others.
by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
*/
/***************************************************/
#include "PluckTwo.h"
using namespace Nyq;
PluckTwo :: PluckTwo(StkFloat lowestFrequency)
{
length_ = (unsigned long) (Stk::sampleRate() / lowestFrequency + 1);
lastLength_ = length_ * 0.5;
delayLine_.setMaximumDelay( length_ );
delayLine_.setDelay( lastLength_ );
delayLine2_.setMaximumDelay( length_ );
delayLine2_.setDelay( lastLength_ );
combDelay_.setMaximumDelay( length_ );
combDelay_.setDelay( lastLength_ );
baseLoopGain_ = 0.995;
loopGain_ = 0.999;
pluckAmplitude_ = 0.3;
pluckPosition_ = 0.4;
detuning_ = 0.995;
lastFrequency_ = lowestFrequency * 2.0;
}
PluckTwo :: ~PluckTwo()
{
}
void PluckTwo :: clear()
{
delayLine_.clear();
delayLine2_.clear();
combDelay_.clear();
filter_.clear();
filter2_.clear();
}
void PluckTwo :: setFrequency(StkFloat frequency)
{
lastFrequency_ = frequency;
if ( lastFrequency_ <= 0.0 ) {
errorString_ << "Clarinet::setFrequency: parameter is less than or equal to zero!";
handleError( StkError::WARNING );
lastFrequency_ = 220.0;
}
// Delay = length - approximate filter delay.
lastLength_ = Stk::sampleRate() / lastFrequency_;
StkFloat delay = (lastLength_ / detuning_) - 0.5;
if ( delay <= 0.0 ) delay = 0.3;
else if ( delay > length_ ) delay = length_;
delayLine_.setDelay( delay );
delay = (lastLength_ * detuning_) - 0.5;
if ( delay <= 0.0 ) delay = 0.3;
else if ( delay > length_ ) delay = length_;
delayLine2_.setDelay( delay );
loopGain_ = baseLoopGain_ + (frequency * 0.000005);
if ( loopGain_ > 1.0 ) loopGain_ = 0.99999;
}
void PluckTwo :: setDetune(StkFloat detune)
{
detuning_ = detune;
if ( detuning_ <= 0.0 ) {
errorString_ << "Clarinet::setDeturn: parameter is less than or equal to zero!";
handleError( StkError::WARNING );
detuning_ = 0.1;
}
delayLine_.setDelay(( lastLength_ / detuning_) - 0.5);
delayLine2_.setDelay( (lastLength_ * detuning_) - 0.5);
}
void PluckTwo :: setFreqAndDetune(StkFloat frequency, StkFloat detune)
{
detuning_ = detune;
this->setFrequency( frequency );
}
void PluckTwo :: setPluckPosition(StkFloat position)
{
pluckPosition_ = position;
if ( position < 0.0 ) {
errorString_ << "PluckTwo::setPluckPosition: parameter is less than zero ... setting to 0.0!";
handleError( StkError::WARNING );
pluckPosition_ = 0.0;
}
else if ( position > 1.0 ) {
errorString_ << "PluckTwo::setPluckPosition: parameter is greater than one ... setting to 1.0!";
handleError( StkError::WARNING );
pluckPosition_ = 1.0;
}
}
void PluckTwo :: setBaseLoopGain(StkFloat aGain)
{
baseLoopGain_ = aGain;
loopGain_ = baseLoopGain_ + (lastFrequency_ * 0.000005);
if ( loopGain_ > 0.99999 ) loopGain_ = 0.99999;
}
void PluckTwo :: noteOff(StkFloat amplitude)
{
loopGain_ = (1.0 - amplitude) * 0.5;
#if defined(_STK_DEBUG_)
errorString_ << "PluckTwo::NoteOff: amplitude = " << amplitude << ".";
handleError( StkError::DEBUG_WARNING );
#endif
}