/******************************************/ /* Simplified string model */ /* Compatible with STK version 4.2.1. */ /* Julius Smith, 2000-2005 */ /******************************************/ #include "SimpString.h" #include <iostream> using namespace std; SimpString :: SimpString(StkFloat lowestFreq) { length = (long) (SRATE / lowestFreq + 1); lastLength = length; lastFreq = lowestFreq; loopGain = (StkFloat) 0.999; delayLine = new DelayA(length,length); combDelay = new Delay(length,length); pluckAmp = (StkFloat) 0.3; pluckPos = (StkFloat) 0.25; combDelay->setDelay((int) (pluckPos * lastLength + 0.5)); loopFilter = new Filter; StkFloat bCoeffs[3] = {0.25,0.5,0.25}; std::vector<StkFloat> b(bCoeffs, bCoeffs+3); loopFilter->setNumerator(b); } SimpString :: ~SimpString() { delete delayLine; delete combDelay; delete loopFilter; } void SimpString :: clear() { delayLine->clear(); combDelay->clear(); loopFilter->clear(); } void SimpString :: setFreq(StkFloat frequency) { StkFloat loopFilterDelay = 0.5; /* just a guess */ lastFreq = frequency; lastLength = ((StkFloat) SRATE / lastFreq); /* length - delays */ delayLine->setDelay(lastLength - loopFilterDelay); } void SimpString :: setPluckPos(StkFloat position) { /* Set Pick Position */ pluckPos = position; combDelay->setDelay((int) (pluckPos * lastLength + 0.5)); } void SimpString :: noteOff(StkFloat amp) { loopGain = (StkFloat) (1.0 - amp) * 0.5; // Accelerate decay #if defined(_debug_) printf("SimpString : NoteOff: Amp=%lf\n",amp); #endif } void SimpString :: pluck(StkFloat amplitude) { pluckAmp = amplitude; /* actual excitation is by tick(input) */ } void SimpString :: pluck(StkFloat amplitude, StkFloat position) { pluckPos = ((position<0) ? 0.0 : ((position>1) ? 1.0 : position)); combDelay->setDelay((int) (pluckPos * lastLength + 0.5)); this->pluck(amplitude); } void SimpString :: noteOn(StkFloat freq, StkFloat amp) { this->setFreq(freq); this->pluck(amp); #if defined(_debug_) printf("SimpString : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); #endif } void SimpString :: noteOn(StkFloat freq, StkFloat amp, StkFloat position) { this->setFreq(freq); this->pluck(amp,position); #if defined(_debug_) printf("SimpString : NoteOn: Freq=%lf Amp=%lf Pos=%lf\n", freq,amp,position); #endif } StkFloat SimpString :: computeSample(StkFloat stringInput) { /* pluck-position comb filtering: */ stringInput -= combDelay->tick(stringInput); lastOutput_ = delayLine->tick(loopFilter->tick( stringInput + (delayLine->lastOut() * loopGain))); return lastOutput_; } StkFloat SimpString :: tick(StkFloat stringInput) { return computeSample(stringInput); } StkFloat SimpString :: tick(void) { return this->tick(0); } StkFloat SimpString :: computeSample(void) { return this->tick(0); }