Version 4.2.0

This commit is contained in:
Gary Scavone
2009-03-24 23:02:14 -04:00
committed by Stephen Sinclair
parent cf06b7598b
commit a6381b9d38
281 changed files with 17152 additions and 12000 deletions

View File

@@ -17,211 +17,223 @@
- String Sustain = 11
- String Stretch = 1
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
*/
/***************************************************/
#include "StifKarp.h"
#include "SKINI.msg"
#include <string.h>
#include <math.h>
StifKarp :: StifKarp(MY_FLOAT lowestFrequency)
StifKarp :: StifKarp(StkFloat lowestFrequency)
{
length = (long) (Stk::sampleRate() / lowestFrequency + 1);
delayLine = new DelayA(0.5 * length, length);
combDelay = new DelayL( 0.2 * length, length);
length_ = (unsigned long) (Stk::sampleRate() / lowestFrequency + 1);
delayLine_.setMaximumDelay( length_ );
delayLine_.setDelay( 0.5 * length_ );
combDelay_.setMaximumDelay( length_ );
combDelay_.setDelay( 0.2 * length_ );
filter = new OneZero();
noise = new Noise();
biQuad[0] = new BiQuad();
biQuad[1] = new BiQuad();
biQuad[2] = new BiQuad();
biQuad[3] = new BiQuad();
pluckAmplitude_ = 0.3;
pickupPosition_ = 0.4;
lastFrequency_ = lowestFrequency * 2.0;
lastLength_ = length_ * 0.5;
stretching_ = 0.9999;
baseLoopGain_ = 0.995;
loopGain_ = 0.999;
pluckAmplitude = 0.3;
pickupPosition = (MY_FLOAT) 0.4;
lastFrequency = lowestFrequency * 2.0;
lastLength = length * 0.5;
stretching = 0.9999;
baseLoopGain = 0.995;
loopGain = 0.999;
clear();
this->clear();
}
StifKarp :: ~StifKarp()
{
delete delayLine;
delete combDelay;
delete filter;
delete noise;
delete biQuad[0];
delete biQuad[1];
delete biQuad[2];
delete biQuad[3];
}
void StifKarp :: clear()
{
delayLine->clear();
combDelay->clear();
filter->clear();
delayLine_.clear();
combDelay_.clear();
filter_.clear();
}
void StifKarp :: setFrequency(MY_FLOAT frequency)
void StifKarp :: setFrequency(StkFloat frequency)
{
lastFrequency = frequency;
lastFrequency_ = frequency;
if ( frequency <= 0.0 ) {
std::cerr << "StifKarp: setFrequency parameter is less than or equal to zero!" << std::endl;
lastFrequency = 220.0;
errorString_ << "StifKarp::setFrequency: parameter is less than or equal to zero!";
handleError( StkError::WARNING );
lastFrequency_ = 220.0;
}
lastLength = Stk::sampleRate() / lastFrequency;
MY_FLOAT delay = lastLength - 0.5;
if (delay <= 0.0) delay = 0.3;
else if (delay > length) delay = length;
delayLine->setDelay( delay );
lastLength_ = Stk::sampleRate() / lastFrequency_;
StkFloat delay = lastLength_ - 0.5;
if (delay <= 0.0)
delay = 0.3;
else if (delay > length_)
delay = length_;
delayLine_.setDelay( delay );
loopGain = baseLoopGain + (frequency * (MY_FLOAT) 0.000005);
if (loopGain >= 1.0) loopGain = (MY_FLOAT) 0.99999;
loopGain_ = baseLoopGain_ + (frequency * 0.000005);
if (loopGain_ >= 1.0) loopGain_ = 0.99999;
setStretch(stretching);
setStretch(stretching_);
combDelay->setDelay((MY_FLOAT) 0.5 * pickupPosition * lastLength);
combDelay_.setDelay( 0.5 * pickupPosition_ * lastLength_ );
}
void StifKarp :: setStretch(MY_FLOAT stretch)
void StifKarp :: setStretch(StkFloat stretch)
{
stretching = stretch;
MY_FLOAT coefficient;
MY_FLOAT freq = lastFrequency * 2.0;
MY_FLOAT dFreq = ( (0.5 * Stk::sampleRate()) - freq ) * 0.25;
MY_FLOAT temp = 0.5 + (stretch * 0.5);
stretching_ = stretch;
StkFloat coefficient;
StkFloat freq = lastFrequency_ * 2.0;
StkFloat dFreq = ( (0.5 * Stk::sampleRate()) - freq ) * 0.25;
StkFloat temp = 0.5 + (stretch * 0.5);
if (temp > 0.9999) temp = 0.9999;
for (int i=0; i<4; i++) {
coefficient = temp * temp;
biQuad[i]->setA2( coefficient );
biQuad[i]->setB0( coefficient );
biQuad[i]->setB2( 1.0 );
biquad_[i].setA2( coefficient );
biquad_[i].setB0( coefficient );
biquad_[i].setB2( 1.0 );
coefficient = -2.0 * temp * cos(TWO_PI * freq / Stk::sampleRate());
biQuad[i]->setA1( coefficient );
biQuad[i]->setB1( coefficient );
biquad_[i].setA1( coefficient );
biquad_[i].setB1( coefficient );
freq += dFreq;
}
}
void StifKarp :: setPickupPosition(MY_FLOAT position) {
pickupPosition = position;
void StifKarp :: setPickupPosition(StkFloat position) {
pickupPosition_ = position;
if ( position < 0.0 ) {
std::cerr << "StifKarp: setPickupPosition parameter is less than zero!" << std::endl;
pickupPosition = 0.0;
errorString_ << "StifKarp::setPickupPosition: parameter is less than zero ... setting to 0.0!";
handleError( StkError::WARNING );
pickupPosition_ = 0.0;
}
else if ( position > 1.0 ) {
std::cerr << "StifKarp: setPickupPosition parameter is greater than 1.0!" << std::endl;
pickupPosition = 1.0;
errorString_ << "StifKarp::setPickupPosition: parameter is greater than 1.0 ... setting to 1.0!";
handleError( StkError::WARNING );
pickupPosition_ = 1.0;
}
// Set the pick position, which puts zeroes at position * length.
combDelay->setDelay(0.5 * pickupPosition * lastLength);
combDelay_.setDelay( 0.5 * pickupPosition_ * lastLength_ );
}
void StifKarp :: setBaseLoopGain(MY_FLOAT aGain)
void StifKarp :: setBaseLoopGain(StkFloat aGain)
{
baseLoopGain = aGain;
loopGain = baseLoopGain + (lastFrequency * 0.000005);
if ( loopGain > 0.99999 ) loopGain = (MY_FLOAT) 0.99999;
baseLoopGain_ = aGain;
loopGain_ = baseLoopGain_ + (lastFrequency_ * 0.000005);
if ( loopGain_ > 0.99999 ) loopGain_ = (StkFloat) 0.99999;
}
void StifKarp :: pluck(MY_FLOAT amplitude)
void StifKarp :: pluck(StkFloat amplitude)
{
MY_FLOAT gain = amplitude;
StkFloat gain = amplitude;
if ( gain > 1.0 ) {
std::cerr << "StifKarp: pluck amplitude greater than 1.0!" << std::endl;
errorString_ << "StifKarp::pluck: amplitude is greater than 1.0 ... setting to 1.0!";
handleError( StkError::WARNING );
gain = 1.0;
}
else if ( gain < 0.0 ) {
std::cerr << "StifKarp: pluck amplitude less than zero!" << std::endl;
errorString_ << "StifKarp::pluck: amplitude is less than zero ... setting to 0.0!";
handleError( StkError::WARNING );
gain = 0.0;
}
pluckAmplitude = amplitude;
for (long i=0; i<length; i++) {
pluckAmplitude_ = amplitude;
for (unsigned long i=0; i<length_; i++) {
// Fill delay with noise additively with current contents.
delayLine->tick((delayLine->lastOut() * 0.6) + 0.4 * noise->tick() * pluckAmplitude);
//delayLine->tick( combDelay->tick((delayLine->lastOut() * 0.6) + 0.4 * noise->tick() * pluckAmplitude));
delayLine_.tick( (delayLine_.lastOut() * 0.6) + 0.4 * noise_.tick() * pluckAmplitude_ );
//delayLine_.tick( combDelay_.tick((delayLine_.lastOut() * 0.6) + 0.4 * noise->tick() * pluckAmplitude_) );
}
}
void StifKarp :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude)
void StifKarp :: noteOn(StkFloat frequency, StkFloat amplitude)
{
this->setFrequency(frequency);
this->pluck(amplitude);
this->setFrequency( frequency );
this->pluck( amplitude );
#if defined(_STK_DEBUG_)
std::cerr << "StifKarp: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << std::endl;
errorString_ << "StifKarp::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
handleError( StkError::DEBUG_WARNING );
#endif
}
void StifKarp :: noteOff(MY_FLOAT amplitude)
void StifKarp :: noteOff(StkFloat amplitude)
{
MY_FLOAT gain = amplitude;
StkFloat gain = amplitude;
if ( gain > 1.0 ) {
std::cerr << "StifKarp: noteOff amplitude greater than 1.0!" << std::endl;
errorString_ << "StifKarp::noteOff: amplitude is greater than 1.0 ... setting to 1.0!";
handleError( StkError::WARNING );
gain = 1.0;
}
else if ( gain < 0.0 ) {
std::cerr << "StifKarp: noteOff amplitude less than zero!" << std::endl;
errorString_ << "StifKarp::noteOff: amplitude is < 0.0 ... setting to 0.0!";
handleError( StkError::WARNING );
gain = 0.0;
}
loopGain = (1.0 - gain) * 0.5;
loopGain_ = (1.0 - gain) * 0.5;
#if defined(_STK_DEBUG_)
std::cerr << "StifPluck: NoteOff amplitude = " << amplitude << std::endl;
errorString_ << "StifKarp::NoteOff: amplitude = " << amplitude << ".";
handleError( StkError::DEBUG_WARNING );
#endif
}
MY_FLOAT StifKarp :: tick()
StkFloat StifKarp :: tick()
{
MY_FLOAT temp = delayLine->lastOut() * loopGain;
StkFloat temp = delayLine_.lastOut() * loopGain_;
// Calculate allpass stretching.
for (int i=0; i<4; i++)
temp = biQuad[i]->tick(temp);
temp = biquad_[i].tick(temp);
// Moving average filter.
temp = filter->tick(temp);
temp = filter_.tick(temp);
lastOutput = delayLine->tick(temp);
lastOutput = lastOutput - combDelay->tick(lastOutput);
return lastOutput;
lastOutput_ = delayLine_.tick(temp);
lastOutput_ = lastOutput_ - combDelay_.tick( lastOutput_ );
return lastOutput_;
}
void StifKarp :: controlChange(int number, MY_FLOAT value)
StkFloat *StifKarp :: tick(StkFloat *vector, unsigned int vectorSize)
{
MY_FLOAT norm = value * ONE_OVER_128;
return Instrmnt::tick( vector, vectorSize );
}
StkFrames& StifKarp :: tick( StkFrames& frames, unsigned int channel )
{
return Instrmnt::tick( frames, channel );
}
void StifKarp :: controlChange(int number, StkFloat value)
{
StkFloat norm = value * ONE_OVER_128;
if ( norm < 0 ) {
norm = 0.0;
std::cerr << "StifKarp: Control value less than zero!" << std::endl;
errorString_ << "StifKarp::controlChange: control value less than zero ... setting to zero!";
handleError( StkError::WARNING );
}
else if ( norm > 1.0 ) {
norm = 1.0;
std::cerr << "StifKarp: Control value greater than 128.0!" << std::endl;
errorString_ << "StifKarp::controlChange: control value greater than 128.0 ... setting to 128.0!";
handleError( StkError::WARNING );
}
if (number == __SK_PickPosition_) // 4
setPickupPosition( norm );
this->setPickupPosition( norm );
else if (number == __SK_StringDamping_) // 11
setBaseLoopGain( 0.97 + (norm * 0.03) );
this->setBaseLoopGain( 0.97 + (norm * 0.03) );
else if (number == __SK_StringDetune_) // 1
setStretch( 0.9 + (0.1 * (1.0 - norm)) );
else
std::cerr << "StifKarp: Undefined Control Number (" << number << ")!!" << std::endl;
this->setStretch( 0.9 + (0.1 * (1.0 - norm)) );
else {
errorString_ << "StifKarp::controlChange: undefined control number (" << number << ")!";
handleError( StkError::WARNING );
}
#if defined(_STK_DEBUG_)
std::cerr << "StifKarp: controlChange number = " << number << ", value = " << value << std::endl;
errorString_ << "StifKarp::controlChange: number = " << number << ", value = " << value << ".";
handleError( StkError::DEBUG_WARNING );
#endif
}