annotate projects/d-box/FeedbackOscillator.cpp @ 269:ac8eb07afcf5

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