1 /** 2 * Copyright 2017 Cut Through Recordings 3 * License: MIT License 4 * Author(s): Ethan Reker 5 */ 6 module ddsp.osc.cfoscillator; 7 8 import ddsp.effect.effect; 9 10 import std.math; 11 12 /** 13 * Coupled-Form Oscillator (Gordon-Smith Oscillator) 14 */ 15 class CFOscillator : AudioEffect 16 { 17 public: 18 nothrow: 19 @nogc: 20 21 this() 22 { 23 init = false; 24 } 25 26 void setFrequency(float frequency) nothrow @nogc 27 { 28 fo = frequency; 29 30 theta = 2 * PI * fo / _sampleRate; 31 epsilon = 2 * sin(theta / 2); 32 33 if(!init) 34 { 35 yn1 = sin(-1 * theta); 36 yq1 = cos(-1 * theta); 37 init = true; 38 } 39 } 40 41 override float getNextSample(const float input) nothrow @nogc 42 { 43 yq = yq1-epsilon * yn1; 44 yn = epsilon * yq + yn1; 45 46 yq1 = yq; 47 yn1 = yn; 48 49 return yn; 50 } 51 52 override void reset() nothrow @nogc 53 { 54 init = false; 55 setFrequency(fo); 56 } 57 58 private: 59 60 float yq; 61 float yq1; 62 float yn; 63 float yn1; 64 float epsilon; 65 float theta; 66 float fo; 67 68 bool init; 69 } 70 71 unittest 72 { 73 import dplug.core.nogc; 74 import ddsp.effect.effect; 75 76 CFOscillator osc = mallocNew!CFOscillator; 77 osc.setSampleRate(44100); 78 osc.setFrequency(1000); 79 80 testEffect(osc, "Coupled-Form Oscillator", 20000, false); 81 }