annotate examples/10-Instruments/d-box/FeedbackOscillator.cpp @ 464:8fcfbfb32aa0 prerelease

Examples reorder with subdirectories. Added header to each project. Moved Doxygen to bottom of render.cpp.
author Robert Jack <robert.h.jack@gmail.com>
date Mon, 20 Jun 2016 16:20:38 +0100
parents
children
rev   line source
robert@464 1 /*
robert@464 2 * FeedbackOscillator.cpp
robert@464 3 *
robert@464 4 * Recursive phase-shift oscillator implemented
robert@464 5 * on the matrix
robert@464 6 *
robert@464 7 * Andrew McPherson 2014
robert@464 8 */
robert@464 9
robert@464 10 #include "FeedbackOscillator.h"
robert@464 11 #include <cstdlib>
robert@464 12 #include <cmath>
robert@464 13
robert@464 14 #define COEFF_B0 0
robert@464 15 #define COEFF_B1 1
robert@464 16 #define COEFF_A1 2
robert@464 17
robert@464 18 FeedbackOscillator::FeedbackOscillator()
robert@464 19 : wavetable1(0), wavetable2(0)
robert@464 20 {
robert@464 21
robert@464 22 }
robert@464 23
robert@464 24 FeedbackOscillator::~FeedbackOscillator() {
robert@464 25 if(wavetable1 != 0)
robert@464 26 free(wavetable1);
robert@464 27 if(wavetable2 != 0)
robert@464 28 free(wavetable2);
robert@464 29
robert@464 30 }
robert@464 31
robert@464 32 // Initialise the settings for the feedback oscillator
robert@464 33 void FeedbackOscillator::initialise(int maxTableSize, float hpfCutoffFrequency, float matrixSampleRate) {
robert@464 34 wavetableMaxLength = maxTableSize;
robert@464 35 if(wavetable1 != 0)
robert@464 36 free(wavetable1);
robert@464 37 if(wavetable2 != 0)
robert@464 38 free(wavetable2);
robert@464 39
robert@464 40 wavetable1 = (float *)malloc(maxTableSize * sizeof(float));
robert@464 41 wavetable2 = (float *)malloc(maxTableSize * sizeof(float));
robert@464 42
robert@464 43 float omega = tan(M_PI * hpfCutoffFrequency / matrixSampleRate);
robert@464 44 float n = 1.0f / (1.0f + omega);
robert@464 45
robert@464 46 coeffs[COEFF_A1] = (omega - 1.0f) * n;
robert@464 47 coeffs[COEFF_B0] = n;
robert@464 48 coeffs[COEFF_B1] = -n;
robert@464 49
robert@464 50 for(int n = 0; n < maxTableSize; n++)
robert@464 51 wavetable1[n] = wavetable2[n] = 0;
robert@464 52
robert@464 53 wavetableRead = wavetable1;
robert@464 54 wavetableWrite = wavetable2;
robert@464 55 wavetableWritePointer = 0;
robert@464 56 sampleCount = lastTriggerCount = 0;
robert@464 57 }
robert@464 58
robert@464 59 // Process one sample and store the output value
robert@464 60 // Returns true if the wavetable needs rendering
robert@464 61 int FeedbackOscillator::process(float input, float *output) {
robert@464 62 float outFloat = coeffs[COEFF_B0] * input + coeffs[COEFF_B1] * lastInput - coeffs[COEFF_A1] * lastOutput;
robert@464 63 int requestRenderLength = 0;
robert@464 64
robert@464 65 if(outFloat < -0.5)
robert@464 66 *output = 0;
robert@464 67 else if(outFloat > 0.5)
robert@464 68 *output = 1;
robert@464 69 else
robert@464 70 *output = outFloat + 0.5;
robert@464 71
robert@464 72 if(canTrigger && outFloat > 0 && lastOutput <= 0) {
robert@464 73 triggered = true;
robert@464 74 requestRenderLength = wavetableWritePointer; // How many samples stored thus far?
robert@464 75 if(requestRenderLength < 4)
robert@464 76 requestRenderLength = 0; // Ignore anything with fewer than 4 points
robert@464 77
robert@464 78 lastTriggerCount = sampleCount;
robert@464 79 canTrigger = false;
robert@464 80 wavetableWritePointer = 0;
robert@464 81
robert@464 82 // Swap buffers
robert@464 83 float *temp = wavetableWrite;
robert@464 84 wavetableWrite = wavetableRead;
robert@464 85 wavetableRead = temp;
robert@464 86 }
robert@464 87
robert@464 88 if(triggered) {
robert@464 89 wavetableWrite[wavetableWritePointer] = outFloat;
robert@464 90 if(++wavetableWritePointer >= wavetableMaxLength) {
robert@464 91 triggered = false;
robert@464 92 wavetableWritePointer = 0;
robert@464 93 }
robert@464 94 }
robert@464 95
robert@464 96 if(sampleCount - lastTriggerCount > 40)
robert@464 97 canTrigger = true;
robert@464 98
robert@464 99 sampleCount++;
robert@464 100
robert@464 101 lastOutput = outFloat;
robert@464 102 lastInput = input;
robert@464 103
robert@464 104 return requestRenderLength;
robert@464 105 }