aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/WinVST/Righteous4/Righteous4Proc.cpp
diff options
context:
space:
mode:
authorChris Johnson <jinx6568@sover.net>2018-06-03 21:19:24 -0400
committerChris Johnson <jinx6568@sover.net>2018-06-03 21:19:24 -0400
commit3a3c2dde62b7c28950898c469c376ad32ac63f39 (patch)
treeffb5f43117d42b7c65d33d01969d931ff5c8d527 /plugins/WinVST/Righteous4/Righteous4Proc.cpp
parent4e96c7400c70a1e7bc67e2241727bcc74315c574 (diff)
downloadairwindows-lv2-port-3a3c2dde62b7c28950898c469c376ad32ac63f39.tar.gz
airwindows-lv2-port-3a3c2dde62b7c28950898c469c376ad32ac63f39.tar.bz2
airwindows-lv2-port-3a3c2dde62b7c28950898c469c376ad32ac63f39.zip
Righteous4 && Channel4
Diffstat (limited to 'plugins/WinVST/Righteous4/Righteous4Proc.cpp')
-rwxr-xr-xplugins/WinVST/Righteous4/Righteous4Proc.cpp1040
1 files changed, 1040 insertions, 0 deletions
diff --git a/plugins/WinVST/Righteous4/Righteous4Proc.cpp b/plugins/WinVST/Righteous4/Righteous4Proc.cpp
new file mode 100755
index 0000000..7ed44cf
--- /dev/null
+++ b/plugins/WinVST/Righteous4/Righteous4Proc.cpp
@@ -0,0 +1,1040 @@
+/* ========================================
+ * Righteous4 - Righteous4.h
+ * Copyright (c) 2016 airwindows, All rights reserved
+ * ======================================== */
+
+#ifndef __Righteous4_H
+#include "Righteous4.h"
+#endif
+
+void Righteous4::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames)
+{
+ float* in1 = inputs[0];
+ float* in2 = inputs[1];
+ float* out1 = outputs[0];
+ float* out2 = outputs[1];
+ long double fpOld = 0.618033988749894848204586; //golden ratio!
+ long double fpNew = 1.0 - fpOld;
+ double overallscale = 1.0;
+ overallscale /= 44100.0;
+ overallscale *= getSampleRate();
+ double IIRscaleback = 0.0002597;//scaleback of harmonic avg
+ IIRscaleback /= overallscale;
+ IIRscaleback = 1.0 - IIRscaleback;
+ double target = (A*24.0)-28.0;
+ target += 17; //gives us scaled distortion factor based on test conditions
+ target = pow(10.0,target/20.0); //we will multiply and divide by this
+ //ShortBuss section
+ if (target == 0) target = 1; //insanity check
+ int bitDepth = (VstInt32)( B * 2.999 )+1; // +1 for Reaper bug workaround
+ double fusswithscale = 149940.0; //corrected
+ double cutofffreq = 20; //was 46/2.0
+ double midAmount = (cutofffreq)/fusswithscale;
+ midAmount /= overallscale;
+ double midaltAmount = 1.0 - midAmount;
+ double gwAfactor = 0.718;
+ gwAfactor -= (overallscale*0.05); //0.2 at 176K, 0.1 at 88.2K, 0.05 at 44.1K
+ //reduce slightly to not less than 0.5 to increase effect
+ double gwBfactor = 1.0 - gwAfactor;
+ double softness = 0.2135;
+ double hardness = 1.0 - softness;
+ double refclip = pow(10.0,-0.0058888);
+
+ while (--sampleFrames >= 0)
+ {
+ long double inputSampleL = *in1;
+ long double inputSampleR = *in2;
+ if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) {
+ static int noisesource = 0;
+ //this declares a variable before anything else is compiled. It won't keep assigning
+ //it to 0 for every sample, it's as if the declaration doesn't exist in this context,
+ //but it lets me add this denormalization fix in a single place rather than updating
+ //it in three different locations. The variable isn't thread-safe but this is only
+ //a random seed and we can share it with whatever.
+ noisesource = noisesource % 1700021; noisesource++;
+ int residue = noisesource * noisesource;
+ residue = residue % 170003; residue *= residue;
+ residue = residue % 17011; residue *= residue;
+ residue = residue % 1709; residue *= residue;
+ residue = residue % 173; residue *= residue;
+ residue = residue % 17;
+ double applyresidue = residue;
+ applyresidue *= 0.00000001;
+ applyresidue *= 0.00000001;
+ inputSampleL = applyresidue;
+ }
+ if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) {
+ static int noisesource = 0;
+ noisesource = noisesource % 1700021; noisesource++;
+ int residue = noisesource * noisesource;
+ residue = residue % 170003; residue *= residue;
+ residue = residue % 17011; residue *= residue;
+ residue = residue % 1709; residue *= residue;
+ residue = residue % 173; residue *= residue;
+ residue = residue % 17;
+ double applyresidue = residue;
+ applyresidue *= 0.00000001;
+ applyresidue *= 0.00000001;
+ inputSampleR = applyresidue;
+ //this denormalization routine produces a white noise at -300 dB which the noise
+ //shaping will interact with to produce a bipolar output, but the noise is actually
+ //all positive. That should stop any variables from going denormal, and the routine
+ //only kicks in if digital black is input. As a final touch, if you save to 24-bit
+ //the silence will return to being digital black again.
+ }
+ double drySampleL = inputSampleL;
+ double drySampleR = inputSampleR;
+ //begin the whole distortion dealiebop
+ inputSampleL /= target;
+ inputSampleR /= target;
+
+ //running shortbuss on direct sample
+ IIRsampleL *= IIRscaleback;
+ double secondharmonicL = sin((2.0 * inputSampleL * inputSampleL) * IIRsampleL);
+ IIRsampleR *= IIRscaleback;
+ double secondharmonicR = sin((2.0 * inputSampleR * inputSampleR) * IIRsampleR);
+ //secondharmonic is calculated before IIRsample is updated, to delay reaction
+
+ long double bridgerectifier = inputSampleL;
+ if (bridgerectifier > 1.2533141373155) bridgerectifier = 1.2533141373155;
+ if (bridgerectifier < -1.2533141373155) bridgerectifier = -1.2533141373155;
+ //clip to 1.2533141373155 to reach maximum output
+ bridgerectifier = sin(bridgerectifier * fabs(bridgerectifier)) / ((bridgerectifier == 0.0) ?1:fabs(bridgerectifier));
+ if (inputSampleL > bridgerectifier) IIRsampleL += ((inputSampleL - bridgerectifier)*0.0009);
+ if (inputSampleL < -bridgerectifier) IIRsampleL += ((inputSampleL + bridgerectifier)*0.0009);
+ //manipulate IIRSampleL
+ inputSampleL = bridgerectifier;
+ //apply the distortion transform for reals. Has been converted back to -1/1
+
+ bridgerectifier = inputSampleR;
+ if (bridgerectifier > 1.2533141373155) bridgerectifier = 1.2533141373155;
+ if (bridgerectifier < -1.2533141373155) bridgerectifier = -1.2533141373155;
+ //clip to 1.2533141373155 to reach maximum output
+ bridgerectifier = sin(bridgerectifier * fabs(bridgerectifier)) / ((bridgerectifier == 0.0) ?1:fabs(bridgerectifier));
+ if (inputSampleR > bridgerectifier) IIRsampleR += ((inputSampleR - bridgerectifier)*0.0009);
+ if (inputSampleR < -bridgerectifier) IIRsampleR += ((inputSampleR + bridgerectifier)*0.0009);
+ //manipulate IIRSampleR
+ inputSampleR = bridgerectifier;
+ //apply the distortion transform for reals. Has been converted back to -1/1
+
+
+ //apply resonant highpass L
+ double tempSample = inputSampleL;
+ leftSampleA = (leftSampleA * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleA; double correction = leftSampleA;
+ leftSampleB = (leftSampleB * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleB; correction += leftSampleB;
+ leftSampleC = (leftSampleC * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleC; correction += leftSampleC;
+ leftSampleD = (leftSampleD * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleD; correction += leftSampleD;
+ leftSampleE = (leftSampleE * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleE; correction += leftSampleE;
+ leftSampleF = (leftSampleF * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleF; correction += leftSampleF;
+ leftSampleG = (leftSampleG * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleG; correction += leftSampleG;
+ leftSampleH = (leftSampleH * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleH; correction += leftSampleH;
+ leftSampleI = (leftSampleI * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleI; correction += leftSampleI;
+ leftSampleJ = (leftSampleJ * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleJ; correction += leftSampleJ;
+ leftSampleK = (leftSampleK * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleK; correction += leftSampleK;
+ leftSampleL = (leftSampleL * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleL; correction += leftSampleL;
+ leftSampleM = (leftSampleM * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleM; correction += leftSampleM;
+ leftSampleN = (leftSampleN * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleN; correction += leftSampleN;
+ leftSampleO = (leftSampleO * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleO; correction += leftSampleO;
+ leftSampleP = (leftSampleP * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleP; correction += leftSampleP;
+ leftSampleQ = (leftSampleQ * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleQ; correction += leftSampleQ;
+ leftSampleR = (leftSampleR * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleR; correction += leftSampleR;
+ leftSampleS = (leftSampleS * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleS; correction += leftSampleS;
+ leftSampleT = (leftSampleT * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleT; correction += leftSampleT;
+ leftSampleU = (leftSampleU * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleU; correction += leftSampleU;
+ leftSampleV = (leftSampleV * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleV; correction += leftSampleV;
+ leftSampleW = (leftSampleW * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleW; correction += leftSampleW;
+ leftSampleX = (leftSampleX * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleX; correction += leftSampleX;
+ leftSampleY = (leftSampleY * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleY; correction += leftSampleY;
+ leftSampleZ = (leftSampleZ * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleZ; correction += leftSampleZ;
+ correction *= fabs(secondharmonicL);
+ //scale it directly by second harmonic: DC block is now adding harmonics too
+ correction -= secondharmonicL*fpOld;
+ //apply the shortbuss processing to output DCblock by subtracting it
+ //we are not a peak limiter! not using it to clip or nothin'
+ //adding it inversely, it's the same as adding to inputsample only we are accumulating 'stuff' in 'correction'
+ inputSampleL -= correction;
+ if (inputSampleL < 0) inputSampleL = (inputSampleL * fpNew) - (sin(-inputSampleL)*fpOld);
+ //lastly, class A clipping on the negative to combat the one-sidedness
+ //uses bloom/antibloom to dial in previous unconstrained behavior
+ //end the whole distortion dealiebop
+ inputSampleL *= target;
+ //begin simplified Groove Wear, outside the scaling
+ //varies depending on what sample rate you're at:
+ //high sample rate makes it more airy
+ gwBL = gwAL; gwAL = tempSample = (inputSampleL-gwPrevL);
+ tempSample *= gwAfactor;
+ tempSample += (gwBL * gwBfactor);
+ correction = (inputSampleL-gwPrevL) - tempSample;
+ gwPrevL = inputSampleL;
+ inputSampleL -= correction;
+ //simplified Groove Wear L
+
+ //apply resonant highpass R
+ tempSample = inputSampleR;
+ rightSampleA = (rightSampleA * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleA; correction = rightSampleA;
+ rightSampleB = (rightSampleB * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleB; correction += rightSampleB;
+ rightSampleC = (rightSampleC * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleC; correction += rightSampleC;
+ rightSampleD = (rightSampleD * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleD; correction += rightSampleD;
+ rightSampleE = (rightSampleE * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleE; correction += rightSampleE;
+ rightSampleF = (rightSampleF * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleF; correction += rightSampleF;
+ rightSampleG = (rightSampleG * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleG; correction += rightSampleG;
+ rightSampleH = (rightSampleH * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleH; correction += rightSampleH;
+ rightSampleI = (rightSampleI * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleI; correction += rightSampleI;
+ rightSampleJ = (rightSampleJ * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleJ; correction += rightSampleJ;
+ rightSampleK = (rightSampleK * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleK; correction += rightSampleK;
+ rightSampleL = (rightSampleL * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleL; correction += rightSampleL;
+ rightSampleM = (rightSampleM * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleM; correction += rightSampleM;
+ rightSampleN = (rightSampleN * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleN; correction += rightSampleN;
+ rightSampleO = (rightSampleO * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleO; correction += rightSampleO;
+ rightSampleP = (rightSampleP * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleP; correction += rightSampleP;
+ rightSampleQ = (rightSampleQ * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleQ; correction += rightSampleQ;
+ rightSampleR = (rightSampleR * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleR; correction += rightSampleR;
+ rightSampleS = (rightSampleS * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleS; correction += rightSampleS;
+ rightSampleT = (rightSampleT * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleT; correction += rightSampleT;
+ rightSampleU = (rightSampleU * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleU; correction += rightSampleU;
+ rightSampleV = (rightSampleV * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleV; correction += rightSampleV;
+ rightSampleW = (rightSampleW * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleW; correction += rightSampleW;
+ rightSampleX = (rightSampleX * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleX; correction += rightSampleX;
+ rightSampleY = (rightSampleY * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleY; correction += rightSampleY;
+ rightSampleZ = (rightSampleZ * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleZ; correction += rightSampleZ;
+ correction *= fabs(secondharmonicR);
+ //scale it directly by second harmonic: DC block is now adding harmonics too
+ correction -= secondharmonicR*fpOld;
+ //apply the shortbuss processing to output DCblock by subtracting it
+ //we are not a peak limiter! not using it to clip or nothin'
+ //adding it inversely, it's the same as adding to inputsample only we are accumulating 'stuff' in 'correction'
+ inputSampleR -= correction;
+ if (inputSampleR < 0) inputSampleR = (inputSampleR * fpNew) - (sin(-inputSampleR)*fpOld);
+ //lastly, class A clipping on the negative to combat the one-sidedness
+ //uses bloom/antibloom to dial in previous unconstrained behavior
+ //end the whole distortion dealiebop
+ inputSampleR *= target;
+ //begin simplified Groove Wear, outside the scaling
+ //varies depending on what sample rate you're at:
+ //high sample rate makes it more airy
+ gwBR = gwAR; gwAR = tempSample = (inputSampleR-gwPrevR);
+ tempSample *= gwAfactor;
+ tempSample += (gwBR * gwBfactor);
+ correction = (inputSampleR-gwPrevR) - tempSample;
+ gwPrevR = inputSampleR;
+ inputSampleR -= correction;
+ //simplified Groove Wear R
+
+ //begin simplified ADClip L
+ drySampleL = inputSampleL;
+ if (lastSampleL >= refclip)
+ {
+ if (inputSampleL < refclip)
+ {
+ lastSampleL = ((refclip*hardness) + (inputSampleL * softness));
+ }
+ else lastSampleL = refclip;
+ }
+
+ if (lastSampleL <= -refclip)
+ {
+ if (inputSampleL > -refclip)
+ {
+ lastSampleL = ((-refclip*hardness) + (inputSampleL * softness));
+ }
+ else lastSampleL = -refclip;
+ }
+
+ if (inputSampleL > refclip)
+ {
+ if (lastSampleL < refclip)
+ {
+ inputSampleL = ((refclip*hardness) + (lastSampleL * softness));
+ }
+ else inputSampleL = refclip;
+ }
+
+ if (inputSampleL < -refclip)
+ {
+ if (lastSampleL > -refclip)
+ {
+ inputSampleL = ((-refclip*hardness) + (lastSampleL * softness));
+ }
+ else inputSampleL = -refclip;
+ }
+ lastSampleL = drySampleL;
+
+ //begin simplified ADClip R
+ drySampleR = inputSampleR;
+ if (lastSampleR >= refclip)
+ {
+ if (inputSampleR < refclip)
+ {
+ lastSampleR = ((refclip*hardness) + (inputSampleR * softness));
+ }
+ else lastSampleR = refclip;
+ }
+
+ if (lastSampleR <= -refclip)
+ {
+ if (inputSampleR > -refclip)
+ {
+ lastSampleR = ((-refclip*hardness) + (inputSampleR * softness));
+ }
+ else lastSampleR = -refclip;
+ }
+
+ if (inputSampleR > refclip)
+ {
+ if (lastSampleR < refclip)
+ {
+ inputSampleR = ((refclip*hardness) + (lastSampleR * softness));
+ }
+ else inputSampleR = refclip;
+ }
+
+ if (inputSampleR < -refclip)
+ {
+ if (lastSampleR > -refclip)
+ {
+ inputSampleR = ((-refclip*hardness) + (lastSampleR * softness));
+ }
+ else inputSampleR = -refclip;
+ }
+ lastSampleR = drySampleR;
+
+ //output dither section
+ if (bitDepth == 3) {
+ //noise shaping to 32-bit floating point
+ float fpTemp = inputSampleL;
+ fpNShapeL += (inputSampleL-fpTemp);
+ inputSampleL += fpNShapeL;
+ fpTemp = inputSampleR;
+ fpNShapeR += (inputSampleR-fpTemp);
+ inputSampleR += fpNShapeR;
+ //for deeper space and warmth, we try a non-oscillating noise shaping
+ //that is kind of ruthless: it will forever retain the rounding errors
+ //except we'll dial it back a hair at the end of every buffer processed
+ //end noise shaping on 32 bit output
+ } else {
+ //entire Naturalize section used when not on 32 bit out
+
+ inputSampleL -= noiseShapingL;
+ inputSampleR -= noiseShapingR;
+
+ if (bitDepth == 2) {
+ inputSampleL *= 8388608.0; //go to dither at 24 bit
+ inputSampleR *= 8388608.0; //go to dither at 24 bit
+ }
+ if (bitDepth == 1) {
+ inputSampleL *= 32768.0; //go to dither at 16 bit
+ inputSampleR *= 32768.0; //go to dither at 16 bit
+ }
+
+ //begin L
+ double benfordize = floor(inputSampleL);
+ while (benfordize >= 1.0) {benfordize /= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ int hotbinA = floor(benfordize);
+ //hotbin becomes the Benford bin value for this number floored
+ double totalA = 0;
+ if ((hotbinA > 0) && (hotbinA < 10))
+ {
+ bynL[hotbinA] += 1;
+ totalA += (301-bynL[1]);
+ totalA += (176-bynL[2]);
+ totalA += (125-bynL[3]);
+ totalA += (97-bynL[4]);
+ totalA += (79-bynL[5]);
+ totalA += (67-bynL[6]);
+ totalA += (58-bynL[7]);
+ totalA += (51-bynL[8]);
+ totalA += (46-bynL[9]);
+ bynL[hotbinA] -= 1;
+ } else {hotbinA = 10;}
+ //produce total number- smaller is closer to Benford real
+
+ benfordize = ceil(inputSampleL);
+ while (benfordize >= 1.0) {benfordize /= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ int hotbinB = floor(benfordize);
+ //hotbin becomes the Benford bin value for this number ceiled
+ double totalB = 0;
+ if ((hotbinB > 0) && (hotbinB < 10))
+ {
+ bynL[hotbinB] += 1;
+ totalB += (301-bynL[1]);
+ totalB += (176-bynL[2]);
+ totalB += (125-bynL[3]);
+ totalB += (97-bynL[4]);
+ totalB += (79-bynL[5]);
+ totalB += (67-bynL[6]);
+ totalB += (58-bynL[7]);
+ totalB += (51-bynL[8]);
+ totalB += (46-bynL[9]);
+ bynL[hotbinB] -= 1;
+ } else {hotbinB = 10;}
+ //produce total number- smaller is closer to Benford real
+
+ if (totalA < totalB)
+ {
+ bynL[hotbinA] += 1;
+ inputSampleL = floor(inputSampleL);
+ }
+ else
+ {
+ bynL[hotbinB] += 1;
+ inputSampleL = ceil(inputSampleL);
+ }
+ //assign the relevant one to the delay line
+ //and floor/ceil signal accordingly
+
+ totalA = bynL[1] + bynL[2] + bynL[3] + bynL[4] + bynL[5] + bynL[6] + bynL[7] + bynL[8] + bynL[9];
+ totalA /= 1000;
+ if (totalA = 0) totalA = 1;
+ bynL[1] /= totalA;
+ bynL[2] /= totalA;
+ bynL[3] /= totalA;
+ bynL[4] /= totalA;
+ bynL[5] /= totalA;
+ bynL[6] /= totalA;
+ bynL[7] /= totalA;
+ bynL[8] /= totalA;
+ bynL[9] /= totalA;
+ bynL[10] /= 2; //catchall for garbage data
+ //end L
+
+ //begin R
+ benfordize = floor(inputSampleR);
+ while (benfordize >= 1.0) {benfordize /= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ hotbinA = floor(benfordize);
+ //hotbin becomes the Benford bin value for this number floored
+ totalA = 0;
+ if ((hotbinA > 0) && (hotbinA < 10))
+ {
+ bynR[hotbinA] += 1;
+ totalA += (301-bynR[1]);
+ totalA += (176-bynR[2]);
+ totalA += (125-bynR[3]);
+ totalA += (97-bynR[4]);
+ totalA += (79-bynR[5]);
+ totalA += (67-bynR[6]);
+ totalA += (58-bynR[7]);
+ totalA += (51-bynR[8]);
+ totalA += (46-bynR[9]);
+ bynR[hotbinA] -= 1;
+ } else {hotbinA = 10;}
+ //produce total number- smaller is closer to Benford real
+
+ benfordize = ceil(inputSampleR);
+ while (benfordize >= 1.0) {benfordize /= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ hotbinB = floor(benfordize);
+ //hotbin becomes the Benford bin value for this number ceiled
+ totalB = 0;
+ if ((hotbinB > 0) && (hotbinB < 10))
+ {
+ bynR[hotbinB] += 1;
+ totalB += (301-bynR[1]);
+ totalB += (176-bynR[2]);
+ totalB += (125-bynR[3]);
+ totalB += (97-bynR[4]);
+ totalB += (79-bynR[5]);
+ totalB += (67-bynR[6]);
+ totalB += (58-bynR[7]);
+ totalB += (51-bynR[8]);
+ totalB += (46-bynR[9]);
+ bynR[hotbinB] -= 1;
+ } else {hotbinB = 10;}
+ //produce total number- smaller is closer to Benford real
+
+ if (totalA < totalB)
+ {
+ bynR[hotbinA] += 1;
+ inputSampleR = floor(inputSampleR);
+ }
+ else
+ {
+ bynR[hotbinB] += 1;
+ inputSampleR = ceil(inputSampleR);
+ }
+ //assign the relevant one to the delay line
+ //and floor/ceil signal accordingly
+
+ totalA = bynR[1] + bynR[2] + bynR[3] + bynR[4] + bynR[5] + bynR[6] + bynR[7] + bynR[8] + bynR[9];
+ totalA /= 1000;
+ if (totalA = 0) totalA = 1;
+ bynR[1] /= totalA;
+ bynR[2] /= totalA;
+ bynR[3] /= totalA;
+ bynR[4] /= totalA;
+ bynR[5] /= totalA;
+ bynR[6] /= totalA;
+ bynR[7] /= totalA;
+ bynR[8] /= totalA;
+ bynR[9] /= totalA;
+ bynR[10] /= 2; //catchall for garbage data
+ //end R
+
+ if (bitDepth == 2) {
+ inputSampleL /= 8388608.0;
+ inputSampleR /= 8388608.0;
+ }
+ if (bitDepth == 1) {
+ inputSampleL /= 32768.0;
+ inputSampleR /= 32768.0;
+ }
+ noiseShapingL += inputSampleL - drySampleL;
+ noiseShapingR += inputSampleR - drySampleR;
+ }
+
+ if (inputSampleL > refclip) inputSampleL = refclip;
+ if (inputSampleL < -refclip) inputSampleL = -refclip;
+ //iron bar prohibits any overs
+ if (inputSampleR > refclip) inputSampleR = refclip;
+ if (inputSampleR < -refclip) inputSampleR = -refclip;
+ //iron bar prohibits any overs
+
+ *out1 = inputSampleL;
+ *out2 = inputSampleR;
+
+ *in1++;
+ *in2++;
+ *out1++;
+ *out2++;
+ }
+ fpNShapeL *= 0.999999;
+ fpNShapeR *= 0.999999;
+ //we will just delicately dial back the FP noise shaping, not even every sample
+ //this is a good place to put subtle 'no runaway' calculations, though bear in mind
+ //that it will be called more often when you use shorter sample buffers in the DAW.
+ //So, very low latency operation will call these calculations more often.
+}
+
+void Righteous4::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames)
+{
+ double* in1 = inputs[0];
+ double* in2 = inputs[1];
+ double* out1 = outputs[0];
+ double* out2 = outputs[1];
+ long double fpOld = 0.618033988749894848204586; //golden ratio!
+ long double fpNew = 1.0 - fpOld;
+ double overallscale = 1.0;
+ overallscale /= 44100.0;
+ overallscale *= getSampleRate();
+ double IIRscaleback = 0.0002597;//scaleback of harmonic avg
+ IIRscaleback /= overallscale;
+ IIRscaleback = 1.0 - IIRscaleback;
+ double target = (A*24.0)-28.0;
+ target += 17; //gives us scaled distortion factor based on test conditions
+ target = pow(10.0,target/20.0); //we will multiply and divide by this
+ //ShortBuss section
+ if (target == 0) target = 1; //insanity check
+ int bitDepth = (VstInt32)( B * 2.999 )+1; // +1 for Reaper bug workaround
+ double fusswithscale = 149940.0; //corrected
+ double cutofffreq = 20; //was 46/2.0
+ double midAmount = (cutofffreq)/fusswithscale;
+ midAmount /= overallscale;
+ double midaltAmount = 1.0 - midAmount;
+ double gwAfactor = 0.718;
+ gwAfactor -= (overallscale*0.05); //0.2 at 176K, 0.1 at 88.2K, 0.05 at 44.1K
+ //reduce slightly to not less than 0.5 to increase effect
+ double gwBfactor = 1.0 - gwAfactor;
+ double softness = 0.2135;
+ double hardness = 1.0 - softness;
+ double refclip = pow(10.0,-0.0058888);
+
+ while (--sampleFrames >= 0)
+ {
+ long double inputSampleL = *in1;
+ long double inputSampleR = *in2;
+ if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) {
+ static int noisesource = 0;
+ //this declares a variable before anything else is compiled. It won't keep assigning
+ //it to 0 for every sample, it's as if the declaration doesn't exist in this context,
+ //but it lets me add this denormalization fix in a single place rather than updating
+ //it in three different locations. The variable isn't thread-safe but this is only
+ //a random seed and we can share it with whatever.
+ noisesource = noisesource % 1700021; noisesource++;
+ int residue = noisesource * noisesource;
+ residue = residue % 170003; residue *= residue;
+ residue = residue % 17011; residue *= residue;
+ residue = residue % 1709; residue *= residue;
+ residue = residue % 173; residue *= residue;
+ residue = residue % 17;
+ double applyresidue = residue;
+ applyresidue *= 0.00000001;
+ applyresidue *= 0.00000001;
+ inputSampleL = applyresidue;
+ }
+ if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) {
+ static int noisesource = 0;
+ noisesource = noisesource % 1700021; noisesource++;
+ int residue = noisesource * noisesource;
+ residue = residue % 170003; residue *= residue;
+ residue = residue % 17011; residue *= residue;
+ residue = residue % 1709; residue *= residue;
+ residue = residue % 173; residue *= residue;
+ residue = residue % 17;
+ double applyresidue = residue;
+ applyresidue *= 0.00000001;
+ applyresidue *= 0.00000001;
+ inputSampleR = applyresidue;
+ //this denormalization routine produces a white noise at -300 dB which the noise
+ //shaping will interact with to produce a bipolar output, but the noise is actually
+ //all positive. That should stop any variables from going denormal, and the routine
+ //only kicks in if digital black is input. As a final touch, if you save to 24-bit
+ //the silence will return to being digital black again.
+ }
+ double drySampleL = inputSampleL;
+ double drySampleR = inputSampleR;
+ //begin the whole distortion dealiebop
+ inputSampleL /= target;
+ inputSampleR /= target;
+
+ //running shortbuss on direct sample
+ IIRsampleL *= IIRscaleback;
+ double secondharmonicL = sin((2.0 * inputSampleL * inputSampleL) * IIRsampleL);
+ IIRsampleR *= IIRscaleback;
+ double secondharmonicR = sin((2.0 * inputSampleR * inputSampleR) * IIRsampleR);
+ //secondharmonic is calculated before IIRsample is updated, to delay reaction
+
+ long double bridgerectifier = inputSampleL;
+ if (bridgerectifier > 1.2533141373155) bridgerectifier = 1.2533141373155;
+ if (bridgerectifier < -1.2533141373155) bridgerectifier = -1.2533141373155;
+ //clip to 1.2533141373155 to reach maximum output
+ bridgerectifier = sin(bridgerectifier * fabs(bridgerectifier)) / ((bridgerectifier == 0.0) ?1:fabs(bridgerectifier));
+ if (inputSampleL > bridgerectifier) IIRsampleL += ((inputSampleL - bridgerectifier)*0.0009);
+ if (inputSampleL < -bridgerectifier) IIRsampleL += ((inputSampleL + bridgerectifier)*0.0009);
+ //manipulate IIRSampleL
+ inputSampleL = bridgerectifier;
+ //apply the distortion transform for reals. Has been converted back to -1/1
+
+ bridgerectifier = inputSampleR;
+ if (bridgerectifier > 1.2533141373155) bridgerectifier = 1.2533141373155;
+ if (bridgerectifier < -1.2533141373155) bridgerectifier = -1.2533141373155;
+ //clip to 1.2533141373155 to reach maximum output
+ bridgerectifier = sin(bridgerectifier * fabs(bridgerectifier)) / ((bridgerectifier == 0.0) ?1:fabs(bridgerectifier));
+ if (inputSampleR > bridgerectifier) IIRsampleR += ((inputSampleR - bridgerectifier)*0.0009);
+ if (inputSampleR < -bridgerectifier) IIRsampleR += ((inputSampleR + bridgerectifier)*0.0009);
+ //manipulate IIRSampleR
+ inputSampleR = bridgerectifier;
+ //apply the distortion transform for reals. Has been converted back to -1/1
+
+
+ //apply resonant highpass L
+ double tempSample = inputSampleL;
+ leftSampleA = (leftSampleA * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleA; double correction = leftSampleA;
+ leftSampleB = (leftSampleB * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleB; correction += leftSampleB;
+ leftSampleC = (leftSampleC * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleC; correction += leftSampleC;
+ leftSampleD = (leftSampleD * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleD; correction += leftSampleD;
+ leftSampleE = (leftSampleE * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleE; correction += leftSampleE;
+ leftSampleF = (leftSampleF * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleF; correction += leftSampleF;
+ leftSampleG = (leftSampleG * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleG; correction += leftSampleG;
+ leftSampleH = (leftSampleH * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleH; correction += leftSampleH;
+ leftSampleI = (leftSampleI * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleI; correction += leftSampleI;
+ leftSampleJ = (leftSampleJ * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleJ; correction += leftSampleJ;
+ leftSampleK = (leftSampleK * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleK; correction += leftSampleK;
+ leftSampleL = (leftSampleL * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleL; correction += leftSampleL;
+ leftSampleM = (leftSampleM * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleM; correction += leftSampleM;
+ leftSampleN = (leftSampleN * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleN; correction += leftSampleN;
+ leftSampleO = (leftSampleO * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleO; correction += leftSampleO;
+ leftSampleP = (leftSampleP * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleP; correction += leftSampleP;
+ leftSampleQ = (leftSampleQ * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleQ; correction += leftSampleQ;
+ leftSampleR = (leftSampleR * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleR; correction += leftSampleR;
+ leftSampleS = (leftSampleS * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleS; correction += leftSampleS;
+ leftSampleT = (leftSampleT * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleT; correction += leftSampleT;
+ leftSampleU = (leftSampleU * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleU; correction += leftSampleU;
+ leftSampleV = (leftSampleV * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleV; correction += leftSampleV;
+ leftSampleW = (leftSampleW * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleW; correction += leftSampleW;
+ leftSampleX = (leftSampleX * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleX; correction += leftSampleX;
+ leftSampleY = (leftSampleY * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleY; correction += leftSampleY;
+ leftSampleZ = (leftSampleZ * midaltAmount) + (tempSample * midAmount); tempSample -= leftSampleZ; correction += leftSampleZ;
+ correction *= fabs(secondharmonicL);
+ //scale it directly by second harmonic: DC block is now adding harmonics too
+ correction -= secondharmonicL*fpOld;
+ //apply the shortbuss processing to output DCblock by subtracting it
+ //we are not a peak limiter! not using it to clip or nothin'
+ //adding it inversely, it's the same as adding to inputsample only we are accumulating 'stuff' in 'correction'
+ inputSampleL -= correction;
+ if (inputSampleL < 0) inputSampleL = (inputSampleL * fpNew) - (sin(-inputSampleL)*fpOld);
+ //lastly, class A clipping on the negative to combat the one-sidedness
+ //uses bloom/antibloom to dial in previous unconstrained behavior
+ //end the whole distortion dealiebop
+ inputSampleL *= target;
+ //begin simplified Groove Wear, outside the scaling
+ //varies depending on what sample rate you're at:
+ //high sample rate makes it more airy
+ gwBL = gwAL; gwAL = tempSample = (inputSampleL-gwPrevL);
+ tempSample *= gwAfactor;
+ tempSample += (gwBL * gwBfactor);
+ correction = (inputSampleL-gwPrevL) - tempSample;
+ gwPrevL = inputSampleL;
+ inputSampleL -= correction;
+ //simplified Groove Wear L
+
+ //apply resonant highpass R
+ tempSample = inputSampleR;
+ rightSampleA = (rightSampleA * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleA; correction = rightSampleA;
+ rightSampleB = (rightSampleB * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleB; correction += rightSampleB;
+ rightSampleC = (rightSampleC * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleC; correction += rightSampleC;
+ rightSampleD = (rightSampleD * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleD; correction += rightSampleD;
+ rightSampleE = (rightSampleE * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleE; correction += rightSampleE;
+ rightSampleF = (rightSampleF * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleF; correction += rightSampleF;
+ rightSampleG = (rightSampleG * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleG; correction += rightSampleG;
+ rightSampleH = (rightSampleH * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleH; correction += rightSampleH;
+ rightSampleI = (rightSampleI * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleI; correction += rightSampleI;
+ rightSampleJ = (rightSampleJ * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleJ; correction += rightSampleJ;
+ rightSampleK = (rightSampleK * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleK; correction += rightSampleK;
+ rightSampleL = (rightSampleL * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleL; correction += rightSampleL;
+ rightSampleM = (rightSampleM * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleM; correction += rightSampleM;
+ rightSampleN = (rightSampleN * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleN; correction += rightSampleN;
+ rightSampleO = (rightSampleO * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleO; correction += rightSampleO;
+ rightSampleP = (rightSampleP * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleP; correction += rightSampleP;
+ rightSampleQ = (rightSampleQ * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleQ; correction += rightSampleQ;
+ rightSampleR = (rightSampleR * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleR; correction += rightSampleR;
+ rightSampleS = (rightSampleS * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleS; correction += rightSampleS;
+ rightSampleT = (rightSampleT * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleT; correction += rightSampleT;
+ rightSampleU = (rightSampleU * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleU; correction += rightSampleU;
+ rightSampleV = (rightSampleV * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleV; correction += rightSampleV;
+ rightSampleW = (rightSampleW * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleW; correction += rightSampleW;
+ rightSampleX = (rightSampleX * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleX; correction += rightSampleX;
+ rightSampleY = (rightSampleY * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleY; correction += rightSampleY;
+ rightSampleZ = (rightSampleZ * midaltAmount) + (tempSample * midAmount); tempSample -= rightSampleZ; correction += rightSampleZ;
+ correction *= fabs(secondharmonicR);
+ //scale it directly by second harmonic: DC block is now adding harmonics too
+ correction -= secondharmonicR*fpOld;
+ //apply the shortbuss processing to output DCblock by subtracting it
+ //we are not a peak limiter! not using it to clip or nothin'
+ //adding it inversely, it's the same as adding to inputsample only we are accumulating 'stuff' in 'correction'
+ inputSampleR -= correction;
+ if (inputSampleR < 0) inputSampleR = (inputSampleR * fpNew) - (sin(-inputSampleR)*fpOld);
+ //lastly, class A clipping on the negative to combat the one-sidedness
+ //uses bloom/antibloom to dial in previous unconstrained behavior
+ //end the whole distortion dealiebop
+ inputSampleR *= target;
+ //begin simplified Groove Wear, outside the scaling
+ //varies depending on what sample rate you're at:
+ //high sample rate makes it more airy
+ gwBR = gwAR; gwAR = tempSample = (inputSampleR-gwPrevR);
+ tempSample *= gwAfactor;
+ tempSample += (gwBR * gwBfactor);
+ correction = (inputSampleR-gwPrevR) - tempSample;
+ gwPrevR = inputSampleR;
+ inputSampleR -= correction;
+ //simplified Groove Wear R
+
+ //begin simplified ADClip L
+ drySampleL = inputSampleL;
+ if (lastSampleL >= refclip)
+ {
+ if (inputSampleL < refclip)
+ {
+ lastSampleL = ((refclip*hardness) + (inputSampleL * softness));
+ }
+ else lastSampleL = refclip;
+ }
+
+ if (lastSampleL <= -refclip)
+ {
+ if (inputSampleL > -refclip)
+ {
+ lastSampleL = ((-refclip*hardness) + (inputSampleL * softness));
+ }
+ else lastSampleL = -refclip;
+ }
+
+ if (inputSampleL > refclip)
+ {
+ if (lastSampleL < refclip)
+ {
+ inputSampleL = ((refclip*hardness) + (lastSampleL * softness));
+ }
+ else inputSampleL = refclip;
+ }
+
+ if (inputSampleL < -refclip)
+ {
+ if (lastSampleL > -refclip)
+ {
+ inputSampleL = ((-refclip*hardness) + (lastSampleL * softness));
+ }
+ else inputSampleL = -refclip;
+ }
+ lastSampleL = drySampleL;
+
+ //begin simplified ADClip R
+ drySampleR = inputSampleR;
+ if (lastSampleR >= refclip)
+ {
+ if (inputSampleR < refclip)
+ {
+ lastSampleR = ((refclip*hardness) + (inputSampleR * softness));
+ }
+ else lastSampleR = refclip;
+ }
+
+ if (lastSampleR <= -refclip)
+ {
+ if (inputSampleR > -refclip)
+ {
+ lastSampleR = ((-refclip*hardness) + (inputSampleR * softness));
+ }
+ else lastSampleR = -refclip;
+ }
+
+ if (inputSampleR > refclip)
+ {
+ if (lastSampleR < refclip)
+ {
+ inputSampleR = ((refclip*hardness) + (lastSampleR * softness));
+ }
+ else inputSampleR = refclip;
+ }
+
+ if (inputSampleR < -refclip)
+ {
+ if (lastSampleR > -refclip)
+ {
+ inputSampleR = ((-refclip*hardness) + (lastSampleR * softness));
+ }
+ else inputSampleR = -refclip;
+ }
+ lastSampleR = drySampleR;
+
+ //output dither section
+ if (bitDepth == 3) {
+ //noise shaping to 32-bit floating point
+ double fpTemp = inputSampleL;
+ fpNShapeL += (inputSampleL-fpTemp);
+ inputSampleL += fpNShapeL;
+ fpTemp = inputSampleR;
+ fpNShapeR += (inputSampleR-fpTemp);
+ inputSampleR += fpNShapeR;
+ //for deeper space and warmth, we try a non-oscillating noise shaping
+ //that is kind of ruthless: it will forever retain the rounding errors
+ //except we'll dial it back a hair at the end of every buffer processed
+ //end noise shaping on 32 bit output
+ } else {
+ //entire Naturalize section used when not on 32 bit out
+
+ inputSampleL -= noiseShapingL;
+ inputSampleR -= noiseShapingR;
+
+ if (bitDepth == 2) {
+ inputSampleL *= 8388608.0; //go to dither at 24 bit
+ inputSampleR *= 8388608.0; //go to dither at 24 bit
+ }
+ if (bitDepth == 1) {
+ inputSampleL *= 32768.0; //go to dither at 16 bit
+ inputSampleR *= 32768.0; //go to dither at 16 bit
+ }
+
+ //begin L
+ double benfordize = floor(inputSampleL);
+ while (benfordize >= 1.0) {benfordize /= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ int hotbinA = floor(benfordize);
+ //hotbin becomes the Benford bin value for this number floored
+ double totalA = 0;
+ if ((hotbinA > 0) && (hotbinA < 10))
+ {
+ bynL[hotbinA] += 1;
+ totalA += (301-bynL[1]);
+ totalA += (176-bynL[2]);
+ totalA += (125-bynL[3]);
+ totalA += (97-bynL[4]);
+ totalA += (79-bynL[5]);
+ totalA += (67-bynL[6]);
+ totalA += (58-bynL[7]);
+ totalA += (51-bynL[8]);
+ totalA += (46-bynL[9]);
+ bynL[hotbinA] -= 1;
+ } else {hotbinA = 10;}
+ //produce total number- smaller is closer to Benford real
+
+ benfordize = ceil(inputSampleL);
+ while (benfordize >= 1.0) {benfordize /= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ int hotbinB = floor(benfordize);
+ //hotbin becomes the Benford bin value for this number ceiled
+ double totalB = 0;
+ if ((hotbinB > 0) && (hotbinB < 10))
+ {
+ bynL[hotbinB] += 1;
+ totalB += (301-bynL[1]);
+ totalB += (176-bynL[2]);
+ totalB += (125-bynL[3]);
+ totalB += (97-bynL[4]);
+ totalB += (79-bynL[5]);
+ totalB += (67-bynL[6]);
+ totalB += (58-bynL[7]);
+ totalB += (51-bynL[8]);
+ totalB += (46-bynL[9]);
+ bynL[hotbinB] -= 1;
+ } else {hotbinB = 10;}
+ //produce total number- smaller is closer to Benford real
+
+ if (totalA < totalB)
+ {
+ bynL[hotbinA] += 1;
+ inputSampleL = floor(inputSampleL);
+ }
+ else
+ {
+ bynL[hotbinB] += 1;
+ inputSampleL = ceil(inputSampleL);
+ }
+ //assign the relevant one to the delay line
+ //and floor/ceil signal accordingly
+
+ totalA = bynL[1] + bynL[2] + bynL[3] + bynL[4] + bynL[5] + bynL[6] + bynL[7] + bynL[8] + bynL[9];
+ totalA /= 1000;
+ if (totalA = 0) totalA = 1;
+ bynL[1] /= totalA;
+ bynL[2] /= totalA;
+ bynL[3] /= totalA;
+ bynL[4] /= totalA;
+ bynL[5] /= totalA;
+ bynL[6] /= totalA;
+ bynL[7] /= totalA;
+ bynL[8] /= totalA;
+ bynL[9] /= totalA;
+ bynL[10] /= 2; //catchall for garbage data
+ //end L
+
+ //begin R
+ benfordize = floor(inputSampleR);
+ while (benfordize >= 1.0) {benfordize /= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ hotbinA = floor(benfordize);
+ //hotbin becomes the Benford bin value for this number floored
+ totalA = 0;
+ if ((hotbinA > 0) && (hotbinA < 10))
+ {
+ bynR[hotbinA] += 1;
+ totalA += (301-bynR[1]);
+ totalA += (176-bynR[2]);
+ totalA += (125-bynR[3]);
+ totalA += (97-bynR[4]);
+ totalA += (79-bynR[5]);
+ totalA += (67-bynR[6]);
+ totalA += (58-bynR[7]);
+ totalA += (51-bynR[8]);
+ totalA += (46-bynR[9]);
+ bynR[hotbinA] -= 1;
+ } else {hotbinA = 10;}
+ //produce total number- smaller is closer to Benford real
+
+ benfordize = ceil(inputSampleR);
+ while (benfordize >= 1.0) {benfordize /= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ hotbinB = floor(benfordize);
+ //hotbin becomes the Benford bin value for this number ceiled
+ totalB = 0;
+ if ((hotbinB > 0) && (hotbinB < 10))
+ {
+ bynR[hotbinB] += 1;
+ totalB += (301-bynR[1]);
+ totalB += (176-bynR[2]);
+ totalB += (125-bynR[3]);
+ totalB += (97-bynR[4]);
+ totalB += (79-bynR[5]);
+ totalB += (67-bynR[6]);
+ totalB += (58-bynR[7]);
+ totalB += (51-bynR[8]);
+ totalB += (46-bynR[9]);
+ bynR[hotbinB] -= 1;
+ } else {hotbinB = 10;}
+ //produce total number- smaller is closer to Benford real
+
+ if (totalA < totalB)
+ {
+ bynR[hotbinA] += 1;
+ inputSampleR = floor(inputSampleR);
+ }
+ else
+ {
+ bynR[hotbinB] += 1;
+ inputSampleR = ceil(inputSampleR);
+ }
+ //assign the relevant one to the delay line
+ //and floor/ceil signal accordingly
+
+ totalA = bynR[1] + bynR[2] + bynR[3] + bynR[4] + bynR[5] + bynR[6] + bynR[7] + bynR[8] + bynR[9];
+ totalA /= 1000;
+ if (totalA = 0) totalA = 1;
+ bynR[1] /= totalA;
+ bynR[2] /= totalA;
+ bynR[3] /= totalA;
+ bynR[4] /= totalA;
+ bynR[5] /= totalA;
+ bynR[6] /= totalA;
+ bynR[7] /= totalA;
+ bynR[8] /= totalA;
+ bynR[9] /= totalA;
+ bynR[10] /= 2; //catchall for garbage data
+ //end R
+
+ if (bitDepth == 2) {
+ inputSampleL /= 8388608.0;
+ inputSampleR /= 8388608.0;
+ }
+ if (bitDepth == 1) {
+ inputSampleL /= 32768.0;
+ inputSampleR /= 32768.0;
+ }
+ noiseShapingL += inputSampleL - drySampleL;
+ noiseShapingR += inputSampleR - drySampleR;
+ }
+
+ if (inputSampleL > refclip) inputSampleL = refclip;
+ if (inputSampleL < -refclip) inputSampleL = -refclip;
+ //iron bar prohibits any overs
+ if (inputSampleR > refclip) inputSampleR = refclip;
+ if (inputSampleR < -refclip) inputSampleR = -refclip;
+ //iron bar prohibits any overs
+
+ *out1 = inputSampleL;
+ *out2 = inputSampleR;
+
+ *in1++;
+ *in2++;
+ *out1++;
+ *out2++;
+ }
+ fpNShapeL *= 0.999999;
+ fpNShapeR *= 0.999999;
+ //we will just delicately dial back the FP noise shaping, not even every sample
+ //this is a good place to put subtle 'no runaway' calculations, though bear in mind
+ //that it will be called more often when you use shorter sample buffers in the DAW.
+ //So, very low latency operation will call these calculations more often.
+} \ No newline at end of file