1 /** 2 * Copyright 2017 Cut Through Recordings 3 * License: MIT License 4 * Author(s): Ethan Reker 5 */ 6 module ddsp.effect.moddelay; 7 8 import ddsp.effect.effect; 9 import ddsp.osc.wtoscillator; 10 import ddsp.effect.digitaldelay; 11 import ddsp.util.memory; 12 13 import std.math; 14 15 /// General purpose class for Modulated Delay effects. This class is used with 16 /// contraints on depth, offset, mix, and feedback to create other effects. (Flanger, Chorus, Tremolo, etc) 17 class ModDelay : AudioEffect 18 { 19 public: 20 nothrow: 21 @nogc: 22 23 this() 24 { 25 lfo = calloc!WTOscillator.init(); 26 delay = calloc!DigitalDelay.init(); 27 } 28 29 override void setSampleRate(float sampleRate) 30 { 31 _sampleRate = sampleRate; 32 lfo.setSampleRate(sampleRate); 33 delay.setSampleRate(sampleRate); 34 } 35 36 float calcDelayOffset(float lfoValue) 37 { 38 float startDelay = _min_delay + _delay_offset; 39 float lfoOffset = _mod_depth * ((lfoValue + 1) / 2 * (_max_delay - _min_delay)) + _min_delay; 40 return lfoOffset + startDelay; 41 } 42 43 /// Must be set before processing audio 44 void setDelayRange(float minDelay, float maxDelay) 45 { 46 _min_delay = minDelay; 47 _max_delay = maxDelay; 48 } 49 50 void setParams(float rate, float depth, float mix, float feedback, int offset, int modType = 0) 51 { 52 _mod_rate = rate; 53 _mod_depth = depth; 54 _delay_offset = offset; 55 _feedback = feedback; 56 _mix = mix; 57 58 //Frequency, sin, not bandlimited 59 lfo.setParams(rate, modType, true); 60 delay.setParams(0, feedback, mix); 61 } 62 63 override float getNextSample(const float input) 64 { 65 float fYn = 0.0; 66 float fYqn = 0.0; 67 lfo.doOscillate(&fYn, &fYqn); 68 69 float delaySamples = calcDelayOffset(fYn); 70 delay.setParams(delaySamples, _feedback, _mix); 71 72 float output = delay.getNextSample(input); 73 74 return output; 75 } 76 77 override void reset() 78 { 79 lfo.reset(); 80 delay.reset(); 81 } 82 private: 83 float _mod_rate; 84 float _mod_depth; 85 float _mix; 86 float _feedback; 87 float _delay_offset; 88 89 float _max_delay; 90 float _min_delay; 91 92 WTOscillator lfo; 93 DigitalDelay delay; 94 } 95 96 class Flanger : AudioEffect 97 { 98 public: 99 nothrow: 100 @nogc: 101 102 this() 103 { 104 _modDelay = calloc!ModDelay.init(); 105 } 106 107 override void setSampleRate(float sampleRate) 108 { 109 _sampleRate = sampleRate; 110 _modDelay.setSampleRate(_sampleRate); 111 _modDelay.setDelayRange(0, 7); 112 } 113 114 void setParams(float modRate, float modDepth, int oscType = 0) 115 { 116 _modDelay.setParams(modRate, modDepth, 0.5, 0.5, 0, oscType); 117 } 118 119 override float getNextSample(const float input) 120 { 121 return _modDelay.getNextSample(input); 122 } 123 124 override void reset() 125 { 126 _modDelay.reset(); 127 } 128 129 private: 130 ModDelay _modDelay; 131 } 132 133 class Vibrato : AudioEffect 134 { 135 public: 136 nothrow: 137 @nogc: 138 139 this() 140 { 141 _modDelay = calloc!ModDelay.init(); 142 } 143 144 override void setSampleRate(float sampleRate) 145 { 146 _sampleRate = sampleRate; 147 _modDelay.setSampleRate(_sampleRate); 148 _modDelay.setDelayRange(0, 7); 149 } 150 151 void setParams(float modRate, float modDepth, int oscType = 0) 152 { 153 _modDelay.setParams(modRate, modDepth, 1.0, 0.0, 0, oscType); 154 } 155 156 override float getNextSample(const float input) 157 { 158 return _modDelay.getNextSample(input); 159 } 160 161 override void reset() 162 { 163 _modDelay.reset(); 164 } 165 166 private: 167 ModDelay _modDelay; 168 } 169 170 class Chorus : AudioEffect 171 { 172 public: 173 nothrow: 174 @nogc: 175 176 this() 177 { 178 _modDelay = calloc!ModDelay.init(); 179 } 180 181 override void setSampleRate(float sampleRate) 182 { 183 _sampleRate = sampleRate; 184 _modDelay.setSampleRate(_sampleRate); 185 _modDelay.setDelayRange(5, 30); 186 } 187 188 void setParams(float modRate, float modDepth, int oscType = 0) 189 { 190 _modDelay.setParams(modRate, modDepth, 0.5, 0.0, 0, oscType); 191 } 192 193 override float getNextSample(const float input) 194 { 195 return _modDelay.getNextSample(input); 196 } 197 198 override void reset() 199 { 200 _modDelay.reset(); 201 } 202 203 private: 204 ModDelay _modDelay; 205 }