CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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
12 WaveShaper::WaveShaper() : Sine() {
13 initWaveTable();
14 }
15
16 // Size is optional and defaults to 8192 bytes.
17
18 WaveShaper::WaveShaper(float frequency, unsigned sel, unsigned size)
19 : Sine(frequency), mTableSize(size) {
20 initWaveTable(sel);
21 }
22
23 // initialize and fill in the default wavetable (a straight line)
24
25 void WaveShaper::initWaveTable(unsigned sel) {
26 mTransferFunction.setSize(1, mTableSize);
27 mTransferFunction.allocateBuffers();
28 sample * sampPtr = mTransferFunction.monoBuffer(0);
29 sample val = -1.0;
30 sample incr = 2.0 / mTableSize;
31 switch (sel) {
32 case 0: // straight table
33 for (unsigned i = 0; i < mTableSize; i++) {
34 *sampPtr++ = val;
35 val += incr;
36 }
37 break;
38 case 1: // use this for a clipping wave shape
39 for (unsigned i = 0; i < mTableSize/6; i++)
40 *sampPtr++ = -0.8333;
41 for (unsigned i = mTableSize/6; i < 5*mTableSize/6; i++) {
42 *sampPtr++ = val;
43 val += incr;
44 }
45 for (unsigned i = 5*mTableSize/6; i < mTableSize; i++)
46 *sampPtr++ = 0.8333;
47 break;
48 case 2: // cube table
49 for (unsigned i = 0; i < mTableSize; i++) {
50 *sampPtr++ = val * val * val;
51 val += incr;
52 }
53 break;
54 case 3: // other table
55 for (unsigned i = 0; i < mTableSize/4; i++)
56 *sampPtr++ = -0.5;
57 for (unsigned i = mTableSize/4; i < 3*mTableSize/4; i++) {
58 *sampPtr++ = val;
59 val += incr;
60 }
61 for (unsigned i = 3*mTableSize/4; i < mTableSize; i++)
62 *sampPtr++ = 0.5;
63 break;
64 }
65 }
66
67 // The mono_next_buffer method does all the work
68
69 void WaveShaper::nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException) {
70 // get the sine wave
71 Sine::nextBuffer(outputBuffer, outBufNum);
72 // get the pointer to the output buffer to write into
73 sample * buffer = outputBuffer.buffer(outBufNum);
74 unsigned numFrames = outputBuffer.mNumFrames;
75 // get the pointer to the transfer function
76 sample * function = mTransferFunction.buffer(0);
77 unsigned fcnLength = mTransferFunction.mNumFrames;
78 unsigned fcnLengthHalf = fcnLength / 2;
79 sample samp;
80
81 // now do the wave-shaping table look-up
82 for (unsigned i = 0; i < numFrames; i++) {
83 samp = *buffer; // get a sample (assumed to be in the range +- 1.0)
84 unsigned index = (samp + 1.0) * fcnLengthHalf; // convert to a table index
85 if (index < 0) index = 0; // make sure it's in the right range
86 if (index >= fcnLength) index = fcnLength - 1;
87
88 samp = function[index]; // scale the sample
89 *buffer++ = samp; // store it in the buffer
90 }
91 }
92