CSL  6.0
KarplusString.cpp
Go to the documentation of this file.
1 //
2 // KarplusString.h -- CSL "physical model" string class
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5 
6 #include "KarplusString.h"
7 
8 using namespace csl;
9 
10 // Method implementations
11 
12 // Trivial constructors
13 
15  mIndex = 0;
16  mEnergy = 0;
17 }
18 
19 KarplusString::KarplusString(float frequency) : Scalable(), Phased(frequency) {
20  mIndex = 0;
21  mDelayLength = (int) (CGestalt::frameRate() / frequency);
22  mFrequency = frequency;
23  this->initDelayLine();
24 }
25 
26 /// Reset time to 0.0 to restart envelope
27 
29  WhiteNoise noise;
30  noise.nextBuffer(mDelayLine, 0); // write noise into the delay line
31  // estimate decay time for freq
32  mEnergy = 600 * (5 - (freqToKey(mFrequency) / 25));
33 }
34 
36  logMsg("a KarplusString: %d Hz", 400);
38 }
39 
40 /// initialize and fill (with noise) the delay line
41 
43  mDelayLine.setSize(1, mDelayLength); // set up and allocate space for the delay line
45  mEnergy = 0;
46  mIndex = 0;
47 }
48 
49 void KarplusString::setFrequency(float frequency) {
50  Phased::setFrequency(frequency);
51  mEnergy = 0;
52  mFrequency = frequency;
53  mDelayLength = (int) (CGestalt::frameRate() / frequency);
54  this->initDelayLine();
55 }
56 
57 /// The mono_next_buffer method does all the work
58 
59 void KarplusString::nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (CException) {
60 
61  sample samp, lastSample;
62  unsigned numFrames = outputBuffer.mNumFrames;
63  sample *outPtr = outputBuffer.buffer(outBufNum); // get the pointer to the output buffer to write into
64  sample *delayPtr = mDelayLine.buffer(0); // get the pointer to the delay line storage
65  if ( ! mEnergy)
66  return;
68 #ifdef CSL_DEBUG
69  logMsg("Karplus Strong String nextBuffer");
70 #endif
72 
73  for (unsigned i = 0; i < numFrames; i++) { // now do the KS recirculating noise filter
74  samp = delayPtr[mIndex]; // get the current sample in the delay line
75  if (mIndex > 0) // get the previous sample
76  lastSample = delayPtr[mIndex - 1];
77  else
78  lastSample = delayPtr[mDelayLength - 1];
79  samp += lastSample; // average the last 2 samples (cheap LPF)
80  samp *= 0.5;
81  UPDATE_SCALABLE_CONTROLS; // update the dynamic scale/offset
82  *outPtr++ = samp * scaleValue + offsetValue; // write to output
83  delayPtr[mIndex] = samp; // write into the delay line
84  mIndex++; // increment and wrap the index
85  if (mIndex >= mDelayLength)
86  mIndex = 0;
87  }
88  if (mEnergy)
89  mEnergy--;
90 }
#define UPDATE_SCALABLE_CONTROLS
Definition: CSL_Core.h:444
void logMsg(const char *format,...)
These are the public logging messages.
Definition: CGestalt.cpp:292
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
unsigned mIndex
current index in the delay line
Definition: KarplusString.h:47
Phased – a mix-in for objects with phase accumulators (local float) and frequency controls (an input...
Definition: CSL_Core.h:497
void initDelayLine()
function to initialize the delay line
White noise – equal power per frequency.
Definition: Noise.h:45
void setSize(unsigned numChannels, unsigned numFrames)
Definition: CSL_Core.cpp:75
void dump()
print debugging info.
void setFrequency(float frequency)
Scalable – mix-in class with scale and offset control inputs (may be constants or generators)...
Definition: CSL_Core.h:403
unsigned mDelayLength
allocated size of the delay line
Definition: KarplusString.h:48
void trigger()
reset internal buffers to re-pluck the string.
float sample
(could be changed to int, or double)
Definition: CSL_Types.h:191
static unsigned frameRate()
default frame rate
Definition: CGestalt.cpp:51
unsigned freqToKey(float frequency)
freqToKey – converts from frequency in Hz to MIDI key #
Definition: CGestalt.cpp:490
unsigned mEnergy
energy left in buffer
Definition: KarplusString.h:49
#define LOAD_SCALABLE_CONTROLS
Load the scale/offset-related values at the start.
Definition: CSL_Core.h:436
void setFrequency(UnitGenerator &frequency)
Setter accessors.
Definition: CSL_Core.cpp:981
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
void allocateBuffers()
fcn to malloc storage buffers
Definition: CSL_Core.cpp:122
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
The mono_next_buffer method does all the work.
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
Destructor.
Definition: Noise.cpp:56
Buffer mDelayLine
the delay line (just a buffer, not a RingBuffer)
Definition: KarplusString.h:41
virtual void dump()
pretty-print the receiver's input/controls map
Definition: CSL_Core.cpp:926
Base class of CSL exceptions (written upper-case). Has a string message.
#define DECLARE_SCALABLE_CONTROLS
Macros for all the Scalable UnitGenerators (note that these don't end with ";")
Definition: CSL_Core.h:429