Skip to content

Commit dc78d5c

Browse files
committed
Removed Restrictions, Added Send Delay
1 parent 6704b9e commit dc78d5c

File tree

5 files changed

+83
-56
lines changed

5 files changed

+83
-56
lines changed

Plateau2/Plateau2.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Plateau2::Plateau2(const InstanceInfo& info)
3535
GetParam(kPan1)->InitPercentage("Pan 1", 0, -100, 100);
3636
GetParam(k1to2)->InitBool("Send Tank 1 to 2", false);
3737
GetParam(k1to2Level)->InitPercentage("Tank 1 to 2 Level");
38+
GetParam(k1to2Delay)->InitSeconds("Tank 1 to 2 Delay", 0., 0., 0.5, 0.01);
3839

3940

4041
GetParam(kEnable2)->InitBool("Tank 2 Enable", false);
@@ -63,6 +64,7 @@ Plateau2::Plateau2(const InstanceInfo& info)
6364
GetParam(kPan2)->InitPercentage("Pan 2", 0, -100, 100);
6465
GetParam(k2to1)->InitBool("Send Tank 2 to 1", false);
6566
GetParam(k2to1Level)->InitPercentage("Tank 1 to 2 Level");
67+
GetParam(k2to1Delay)->InitSeconds("Tank 2 to 1 Delay", 0., 0., 0.5, 0.01);
6668

6769

6870
GetParam(kDanger)->InitBool("DANGER! Allow Unsafe Feedback Settings", false);
@@ -78,6 +80,13 @@ Plateau2::Plateau2(const InstanceInfo& info)
7880
envelope2.setTime(0.004f);
7981
envelope2._value = 1.f;
8082

83+
uint16_t MaxSendDelay = std::ceil(GetSampleRate()/2);
84+
85+
send1To2LeftDelay = InterpDelay<double>(MaxSendDelay, 0);
86+
send1To2RightDelay = InterpDelay<double>(MaxSendDelay, 0);
87+
send2To1LeftDelay = InterpDelay<double>(MaxSendDelay, 0);
88+
send2To1RightDelay = InterpDelay<double>(MaxSendDelay, 0);
89+
8190
#if IPLUG_EDITOR // http://bit.ly/2S64BDd
8291
mMakeGraphicsFunc = [&]() {
8392
return MakeGraphics(*this, PLUG_WIDTH, PLUG_HEIGHT, PLUG_FPS, GetScaleForScreen(PLUG_WIDTH, PLUG_HEIGHT));
@@ -398,6 +407,13 @@ void Plateau2::OnParamChange(int index)
398407
case kPan1:
399408
panBalance1 = balanceFactors(GetParam(kPan1)->Value()/100);
400409
break;
410+
case k1to2Delay:
411+
{
412+
double delay1 = GetParam(k1to2Delay)->Value()*GetSampleRate();
413+
send1To2LeftDelay.setDelayTime(delay1);
414+
send1To2RightDelay.setDelayTime(delay1);
415+
break;
416+
}
401417

402418
case kPreDelay2:
403419
reverb2.setPreDelay(GetParam(index)->Value());
@@ -468,6 +484,13 @@ void Plateau2::OnParamChange(int index)
468484
case kPan2:
469485
panBalance2 = balanceFactors(GetParam(kPan2)->Value()/100);
470486
break;
487+
case k2to1Delay:
488+
{
489+
double delay2 = GetParam(k2to1Delay)->Value() * GetSampleRate();
490+
send2To1LeftDelay.setDelayTime(delay2);
491+
send2To1RightDelay.setDelayTime(delay2);
492+
break;
493+
}
471494

472495
case kDanger:
473496
if (GetParam(kDanger)->Value()) {
@@ -587,6 +610,14 @@ void Plateau2::ProcessBlock(sample** inputs, sample** outputs, int nFrames)
587610
{
588611
outputs[1][s] += std::get<1>(out) * wet1Param;
589612
}
613+
614+
if (tank2Enabled) {
615+
send1To2LeftDelay.input = std::get<0>(reverbOut1);
616+
send1To2RightDelay.input = std::get<1>(reverbOut1);
617+
send1To2LeftDelay.process();
618+
send1To2RightDelay.process();
619+
reverbOut1 = { send1To2LeftDelay.output, send1To2RightDelay.output };
620+
}
590621
}
591622

592623
//I can't find a way to make tank 2 work without just copying and pasting everything
@@ -651,6 +682,14 @@ void Plateau2::ProcessBlock(sample** inputs, sample** outputs, int nFrames)
651682
{
652683
outputs[1][s] += std::get<1>(out) * wet2Param;
653684
}
685+
686+
if (tank1Enabled) {
687+
send2To1LeftDelay.input = std::get<0>(reverbOut2);
688+
send2To1RightDelay.input = std::get<1>(reverbOut2);
689+
send2To1LeftDelay.process();
690+
send2To1RightDelay.process();
691+
reverbOut2 = { send2To1LeftDelay.output, send2To1RightDelay.output };
692+
}
654693
}
655694
}
656695
}

Plateau2/Plateau2.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ class Plateau2 final : public Plugin
111111
std::tuple<double, double> sourceBalance1 = { 0, 0 };
112112
std::tuple<double, double> panBalance1 = { 0, 0 };
113113
LinearEnvelope envelope1;
114-
InterpDelay<double> send1To2Delay;
114+
InterpDelay<double> send1To2LeftDelay;
115+
InterpDelay<double> send1To2RightDelay;
115116
bool clear1 = false;
116117
bool cleared1 = true;
117118
bool fadeOut1 = false;
@@ -123,7 +124,8 @@ class Plateau2 final : public Plugin
123124
std::tuple<double, double> sourceBalance2 = { 0, 0 };
124125
std::tuple<double, double> panBalance2 = { 0, 0 };
125126
LinearEnvelope envelope2;
126-
InterpDelay<double> send2To1Delay;
127+
InterpDelay<double> send2To1LeftDelay;
128+
InterpDelay<double> send2To1RightDelay;
127129
bool clear2 = false;
128130
bool cleared2 = true;
129131
bool fadeOut2 = false;

Plateau2/dsp/Dattorro.cpp

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@
22
#include <cassert>
33
#include <algorithm>
44

5-
Dattorro1997Tank::Dattorro1997Tank(const double initSampleRate,
6-
const double initMaxLfoDepth,
7-
const double initMaxTimeScale) :
8-
maxTimeScale(initMaxTimeScale)
5+
Dattorro1997Tank::Dattorro1997Tank()
96
{
10-
timePadding = initMaxLfoDepth;
11-
setSampleRate(initSampleRate);
7+
timePadding = 16;
128

139
leftOutDCBlock.setCutoffFreq(20.0);
1410
rightOutDCBlock.setCutoffFreq(20.0);
@@ -104,8 +100,8 @@ void Dattorro1997Tank::freeze(bool freezeFlag) {
104100

105101
void Dattorro1997Tank::setSampleRate(const double newSampleRate) {
106102
sampleRate = newSampleRate;
107-
sampleRate = sampleRate > maxSampleRate ? maxSampleRate : sampleRate;
108-
sampleRate = sampleRate < 1.f ? 1.f : sampleRate;
103+
assert(sampleRate >= 1.0f);
104+
109105
sampleRateScale = sampleRate / dattorroSampleRate;
110106

111107
fadeStep = 1.0 / sampleRate;
@@ -114,8 +110,8 @@ void Dattorro1997Tank::setSampleRate(const double newSampleRate) {
114110
rightOutDCBlock.setSampleRate(sampleRate);
115111

116112
rescaleTapTimes();
117-
setTimeScale(timeScale);
118113
initialiseDelaysAndApfs();
114+
setTimeScale(timeScale);
119115
clear();
120116
}
121117

@@ -211,7 +207,7 @@ void Dattorro1997Tank::initialiseDelaysAndApfs() {
211207
auto maxScaledOutputTap = *std::max_element(scaledOutputTaps.begin(),
212208
scaledOutputTaps.end());
213209
auto calcMaxTime = [&](double delayTime) -> long {
214-
return (long)(sampleRateScale * (delayTime * maxTimeScale +
210+
return (long)(sampleRateScale * (delayTime * 4 +
215211
maxScaledOutputTap + timePadding));
216212
};
217213

@@ -235,14 +231,15 @@ void Dattorro1997Tank::initialiseDelaysAndApfs() {
235231
}
236232

237233
void Dattorro1997Tank::tickApfModulation() {
238-
leftApf1.delay1.setDelayTime(lfo1.process() * lfoExcursion + scaledLeftApf1Time);
239-
leftApf1.delay2.setDelayTime(lfo1.process() * lfoExcursion + scaledLeftApf1Time);
240-
leftApf2.delay1.setDelayTime(lfo2.process() * lfoExcursion + scaledLeftApf2Time);
241-
leftApf2.delay2.setDelayTime(lfo2.process() * lfoExcursion + scaledLeftApf2Time);
242-
rightApf1.delay1.setDelayTime(lfo3.process() * lfoExcursion + scaledRightApf1Time);
243-
rightApf1.delay2.setDelayTime(lfo3.process() * lfoExcursion + scaledRightApf1Time);
244-
rightApf2.delay1.setDelayTime(lfo4.process() * lfoExcursion + scaledRightApf2Time);
245-
rightApf2.delay2.setDelayTime(lfo4.process() * lfoExcursion + scaledRightApf2Time);
234+
double scaleFactor = timeScale;
235+
leftApf1.delay1.setDelayTime(lfo1.process() * lfoExcursion * scaleFactor + scaledLeftApf1Time);
236+
leftApf1.delay2.setDelayTime(lfo1.process() * lfoExcursion * scaleFactor + scaledLeftApf1Time);
237+
leftApf2.delay1.setDelayTime(lfo2.process() * lfoExcursion * scaleFactor + scaledLeftApf2Time);
238+
leftApf2.delay2.setDelayTime(lfo2.process() * lfoExcursion * scaleFactor + scaledLeftApf2Time);
239+
rightApf1.delay1.setDelayTime(lfo3.process() * lfoExcursion * scaleFactor + scaledRightApf1Time);
240+
rightApf1.delay2.setDelayTime(lfo3.process() * lfoExcursion * scaleFactor + scaledRightApf1Time);
241+
rightApf2.delay1.setDelayTime(lfo4.process() * lfoExcursion * scaleFactor + scaledRightApf2Time);
242+
rightApf2.delay2.setDelayTime(lfo4.process() * lfoExcursion * scaleFactor + scaledRightApf2Time);
246243
}
247244

248245
void Dattorro1997Tank::rescaleApfAndDelayTimes() {
@@ -270,26 +267,9 @@ void Dattorro1997Tank::rescaleTapTimes() {
270267
}
271268
}
272269

273-
Dattorro::Dattorro(const double initMaxSampleRate,
274-
const double initMaxLfoDepth,
275-
const double initMaxTimeScale)
276-
: tank(initMaxSampleRate, initMaxLfoDepth, initMaxTimeScale)
270+
Dattorro::Dattorro()
271+
: tank()
277272
{
278-
sampleRate = initMaxSampleRate;
279-
dattorroScaleFactor = sampleRate / dattorroSampleRate;
280-
281-
preDelay = InterpDelay<double>(192010, 0);
282-
283-
inputLpf = OnePoleLPFilter(22000.0);
284-
inputHpf = OnePoleHPFilter(0.0);
285-
286-
inApf1 = AllpassFilter<double>(dattorroScale(8 * kInApf1Time), dattorroScale(kInApf1Time), inputDiffusion1);
287-
inApf2 = AllpassFilter<double>(dattorroScale(8 * kInApf2Time), dattorroScale(kInApf2Time), inputDiffusion1);
288-
inApf3 = AllpassFilter<double>(dattorroScale(8 * kInApf3Time), dattorroScale(kInApf3Time), inputDiffusion2);
289-
inApf4 = AllpassFilter<double>(dattorroScale(8 * kInApf4Time), dattorroScale(kInApf4Time), inputDiffusion2);
290-
291-
leftInputDCBlock.setCutoffFreq(20.0);
292-
rightInputDCBlock.setCutoffFreq(20.0);
293273
}
294274

295275
void Dattorro::process(double leftInput, double rightInput) {
@@ -327,8 +307,6 @@ void Dattorro::clear() {
327307
}
328308

329309
void Dattorro::setTimeScale(double timeScale) {
330-
constexpr double minTimeScale = 0.0001;
331-
timeScale = timeScale < minTimeScale ? minTimeScale : timeScale;
332310
tank.setTimeScale(timeScale);
333311
}
334312

@@ -341,6 +319,17 @@ void Dattorro::setSampleRate(double newSampleRate) {
341319
assert(newSampleRate > 0.);
342320

343321
sampleRate = newSampleRate;
322+
323+
preDelay = InterpDelay<double>(std::ceil(sampleRate*0.5), 0);
324+
325+
inputLpf = OnePoleLPFilter(22000.0);
326+
inputHpf = OnePoleHPFilter(0.0);
327+
328+
inApf1 = AllpassFilter<double>(dattorroScale(8 * kInApf1Time), dattorroScale(kInApf1Time), inputDiffusion1);
329+
inApf2 = AllpassFilter<double>(dattorroScale(8 * kInApf2Time), dattorroScale(kInApf2Time), inputDiffusion1);
330+
inApf3 = AllpassFilter<double>(dattorroScale(8 * kInApf3Time), dattorroScale(kInApf3Time), inputDiffusion2);
331+
inApf4 = AllpassFilter<double>(dattorroScale(8 * kInApf4Time), dattorroScale(kInApf4Time), inputDiffusion2);
332+
344333
tank.setSampleRate(sampleRate);
345334
dattorroScaleFactor = sampleRate / dattorroSampleRate;
346335
setPreDelay(preDelayTime);

Plateau2/dsp/Dattorro.hpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111

1212
class Dattorro1997Tank {
1313
public:
14-
Dattorro1997Tank(const double initMaxSampleRate = 44100.0,
15-
const double initMaxLfoDepth = 0.0,
16-
const double initMaxTimeScale = 1.0);
14+
Dattorro1997Tank();
1715

1816
void process(const double leftInput, const double rightIn,
1917
double* leftOut, double* rightOut);
@@ -107,11 +105,9 @@ class Dattorro1997Tank {
107105

108106
std::array<long, 7> scaledOutputTaps;
109107

110-
double maxSampleRate = 44100.;
111-
double sampleRate = maxSampleRate;
108+
double sampleRate;
112109
double sampleRateScale = sampleRate / dattorroSampleRate;
113110

114-
double maxTimeScale = 1.0;
115111
double timeScale = 1.0;
116112

117113
double modDepth = 0.0;
@@ -162,9 +158,7 @@ class Dattorro1997Tank {
162158

163159
class Dattorro {
164160
public:
165-
Dattorro(const double initMaxSampleRate = 44100.0,
166-
const double initMaxLfoDepth = 16.0,
167-
const double initMaxTimeScale = 1.0);
161+
Dattorro();
168162
void process(double leftInput, double rightInput);
169163
void clear();
170164

Plateau2/dsp/InterpDelay.hpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,15 @@ class InterpDelay {
8989
void setDelayTime(T newDelayTime) {
9090

9191
//Validate new time
92-
if (newDelayTime >= bufferLength) { //The delay time may not exceed the maximum buffer length
93-
newDelayTime = bufferLength - 1; //If it does then just max out the delay
94-
}
95-
if (newDelayTime < 0) { //Make sure delay time is greater than 0
96-
newDelayTime = 0;
97-
}
92+
//if (newDelayTime >= bufferLength) { //The delay time may not exceed the maximum buffer length
93+
// newDelayTime = bufferLength - 1; //If it does then just max out the delay
94+
//}
95+
//if (newDelayTime < 0) { //Make sure delay time is greater than 0
96+
// newDelayTime = 0;
97+
//}
98+
99+
assert(newDelayTime >= 0);
100+
assert(newDelayTime < bufferLength);
98101

99102
//Update delay time
100103
currentDelay = static_cast<int64_t>(newDelayTime);

0 commit comments

Comments
 (0)