CSL  5.2
WaveShaper.cpp
Go to the documentation of this file.
1 //
2 // WaveShaper.h -- CSL wave-shaping oscillator class
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5 
6 #include "WaveShaper.h" // my superclass
7 
8 using namespace csl;
9 
10 // Trivial constructors
11 
13  initWaveTable();
14 }
15 
16 // Size is optional and defaults to 8192 bytes.
17 WaveShaper::WaveShaper(float frequency, unsigned size) : Sine(frequency), mTableSize(size) {
18  initWaveTable();
19 }
20 
21 // initialize and fill in the default wavetable (a stringht line)
22 
24  mTransferFunction.set_size(1, mTableSize);
26  sample * sampPtr = mTransferFunction.monoBuffer(0);
27  sample val = -1.0;
28  sample incr = 2.0 / mTableSize;
29  for (unsigned i = 0; i < mTableSize; i++) {
30  *sampPtr++ = val;
31  val += incr;
32  }
33  // use this for a clipping wave shape
34 //#define clipit
35 #ifdef clipit
36  for (unsigned i = 0; i < mTableSize/4; i++)
37  *sampPtr++ = -0.5;
38  for (unsigned i = mTableSize/4; i < 3*mTableSize/4; i++) {
39  *sampPtr++ = val;
40  val += incr;
41  }
42  for (unsigned i = 3*mTableSize/4; i < mTableSize; i++)
43  *sampPtr++ = 0.5;
44 #endif
45 }
46 
47 // The mono_next_buffer method does all the work
48 
49 status WaveShaper::mono_next_buffer(Buffer & inputBuffer, Buffer & outputBuffer, unsigned inBufNum, unsigned outBufNum) {
50  // get the sine wave
51  Sine::mono_next_buffer(inputBuffer, outputBuffer, inBufNum, outBufNum);
52  // get the pointers to the output buffer to write into
53  sample * buffer = outputBuffer._monoBuffers[outBufNum];
54  unsigned numFrames = outputBuffer._numFrames;
55  // get the pointer to the transfer function
56  sample * function = mTransferFunction.mBuffers[0];
57  unsigned fcnLength = mTransferFunction.mNumFrames;
58  unsigned fcnLengthHalf = fcnLength / 2;
59 
60  sample samp;
61 
62  // now do the wave-shaping table look-up
63  for (unsigned i = 0; i < numFrames; i++) {
64  samp = *buffer; // get a sample (assumed to be in the range +- 1.0)
65  unsigned index = (samp + 1.0) * fcnLengthHalf; // convert to a table index
66  if (index < 0) index = 0; // make sure it's in the right range
67  if (index >= fcnLength) index = fcnLength - 1;
68  samp = function[index]; // scale the sample
69  *buffer++ = samp; // store it in the buffer
70  }
71  return cslOk;
72 }
73