Next  |  Prev  |  Up  |  Top  |  Index  |  JOS Index  |  JOS Pubs  |  JOS Home  |  Search

SimpString.cpp

/******************************************/  
/* 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);
}


Next  |  Prev  |  Up  |  Top  |  Index  |  JOS Index  |  JOS Pubs  |  JOS Home  |  Search

[How to cite and copy this work] 
``Physical Audio Signal Processing for Virtual Musical Instruments and Digital Audio Effects'', by Julius O. Smith III, (December 2005 Edition).
Copyright © 2006-07-01 by Julius O. Smith III
Center for Computer Research in Music and Acoustics (CCRMA),   Stanford University
CCRMA  [Automatic-links disclaimer]