aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/LinuxVST/src
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/LinuxVST/src
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/LinuxVST/src')
-rwxr-xr-xplugins/LinuxVST/src/Channel4/Channel4.cpp158
-rwxr-xr-xplugins/LinuxVST/src/Channel4/Channel4.h75
-rwxr-xr-xplugins/LinuxVST/src/Channel4/Channel4Proc.cpp288
-rwxr-xr-xplugins/LinuxVST/src/Righteous4/Righteous4.cpp223
-rwxr-xr-xplugins/LinuxVST/src/Righteous4/Righteous4.h134
-rwxr-xr-xplugins/LinuxVST/src/Righteous4/Righteous4Proc.cpp1040
6 files changed, 1918 insertions, 0 deletions
diff --git a/plugins/LinuxVST/src/Channel4/Channel4.cpp b/plugins/LinuxVST/src/Channel4/Channel4.cpp
new file mode 100755
index 0000000..acdd74a
--- /dev/null
+++ b/plugins/LinuxVST/src/Channel4/Channel4.cpp
@@ -0,0 +1,158 @@
+/* ========================================
+ * Channel4 - Channel4.h
+ * Copyright (c) 2016 airwindows, All rights reserved
+ * ======================================== */
+
+#ifndef __Channel4_H
+#include "Channel4.h"
+#endif
+
+AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new Channel4(audioMaster);}
+
+Channel4::Channel4(audioMasterCallback audioMaster) :
+ AudioEffectX(audioMaster, kNumPrograms, kNumParameters)
+{
+ consoletype = 0.0;
+ drive = 0.0;
+ fpNShapeLA = 0.0;
+ fpNShapeLB = 0.0;
+ fpNShapeRA = 0.0;
+ fpNShapeRB = 0.0;
+ fpFlip = true;
+ iirSampleLA = 0.0;
+ iirSampleRA = 0.0;
+ iirSampleLB = 0.0;
+ iirSampleRB = 0.0;
+ lastSampleL = 0.0;
+ lastSampleR = 0.0;
+ iirAmount = 0.005832;
+ threshold = 0.33362176; //instantiating with Neve values
+
+ //this is reset: values being initialized only once. Startup values, whatever they are.
+
+ _canDo.insert("plugAsChannelInsert"); // plug-in can be used as a channel insert effect.
+ _canDo.insert("plugAsSend"); // plug-in can be used as a send effect.
+ _canDo.insert("x2in2out");
+ setNumInputs(kNumInputs);
+ setNumOutputs(kNumOutputs);
+ setUniqueID(kUniqueId);
+ canProcessReplacing(); // supports output replacing
+ canDoubleReplacing(); // supports double precision processing
+ programsAreChunks(true);
+ vst_strncpy (_programName, "Default", kVstMaxProgNameLen); // default program name
+}
+
+Channel4::~Channel4() {}
+VstInt32 Channel4::getVendorVersion () {return 1000;}
+void Channel4::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);}
+void Channel4::getProgramName(char *name) {vst_strncpy (name, _programName, kVstMaxProgNameLen);}
+//airwindows likes to ignore this stuff. Make your own programs, and make a different plugin rather than
+//trying to do versioning and preventing people from using older versions. Maybe they like the old one!
+
+static float pinParameter(float data)
+{
+ if (data < 0.0f) return 0.0f;
+ if (data > 1.0f) return 1.0f;
+ return data;
+}
+
+VstInt32 Channel4::getChunk (void** data, bool isPreset)
+{
+ float *chunkData = (float *)calloc(kNumParameters, sizeof(float));
+ chunkData[0] = consoletype;
+ chunkData[1] = drive;
+ /* Note: The way this is set up, it will break if you manage to save settings on an Intel
+ machine and load them on a PPC Mac. However, it's fine if you stick to the machine you
+ started with. */
+
+ *data = chunkData;
+ return kNumParameters * sizeof(float);
+}
+
+VstInt32 Channel4::setChunk (void* data, VstInt32 byteSize, bool isPreset)
+{
+ float *chunkData = (float *)data;
+ consoletype = pinParameter(chunkData[0]);
+ drive = pinParameter(chunkData[1]);
+ /* We're ignoring byteSize as we found it to be a filthy liar */
+
+ /* calculate any other fields you need here - you could copy in
+ code from setParameter() here. */
+ return 0;
+}
+
+void Channel4::setParameter(VstInt32 index, float value) {
+ switch (index) {
+ case kParamA: consoletype = value; break;
+ case kParamB: drive = value; break;
+ default: throw; // unknown parameter, shouldn't happen!
+ }
+ //we can also set other defaults here, and do calculations that only have to happen
+ //once when parameters actually change. Here is the 'popup' setting its (global) values.
+ //variables can also be set in the processreplacing loop, and there they'll be set every buffersize
+ //here they're set when a parameter's actually changed, which should be less frequent, but
+ //you must use global variables in the Channel4.h file to do it.
+ switch((VstInt32)( consoletype * 2.999 ))
+ {
+ case 0: iirAmount = 0.005832; threshold = 0.33362176; break; //Neve
+ case 1: iirAmount = 0.004096; threshold = 0.59969536; break; //API
+ case 2: iirAmount = 0.004913; threshold = 0.84934656; break; //SSL
+ default: break; //should not happen
+ }
+ //this relates to using D as a 'popup' and changing things based on that switch.
+ //we are using fpFlip just because it's already there globally, as an example.
+}
+
+float Channel4::getParameter(VstInt32 index) {
+ switch (index) {
+ case kParamA: return consoletype; break;
+ case kParamB: return drive; break;
+ default: break; // unknown parameter, shouldn't happen!
+ } return 0.0; //we only need to update the relevant name, this is simple to manage
+}
+
+void Channel4::getParameterName(VstInt32 index, char *text) {
+ switch (index) {
+ case kParamA: vst_strncpy (text, "Console Type", kVstMaxParamStrLen); break;
+ case kParamB: vst_strncpy (text, "Drive", kVstMaxParamStrLen); break;
+ default: break; // unknown parameter, shouldn't happen!
+ } //this is our labels for displaying in the VST host
+}
+
+void Channel4::getParameterDisplay(VstInt32 index, char *text) {
+ switch (index) {
+ case kParamA: switch((VstInt32)( consoletype * 2.999 )) //0 to almost edge of # of params
+ { case 0: vst_strncpy (text, "Neve", kVstMaxParamStrLen); break;
+ case 1: vst_strncpy (text, "API", kVstMaxParamStrLen); break;
+ case 2: vst_strncpy (text, "SSL", kVstMaxParamStrLen); break;
+ default: break; // unknown parameter, shouldn't happen!
+ } break; //completed consoletype 'popup' parameter, exit
+ case kParamB: int2string ((VstInt32)(drive*100), text, kVstMaxParamStrLen); break;
+ default: break; // unknown parameter, shouldn't happen!
+ } //this displays the values and handles 'popups' where it's discrete choices
+}
+
+void Channel4::getParameterLabel(VstInt32 index, char *text) {
+ switch (index) {
+ case kParamA: vst_strncpy (text, "", kVstMaxParamStrLen); break;
+ case kParamB: vst_strncpy (text, "%", kVstMaxParamStrLen); break; //the percent
+ default: break; // unknown parameter, shouldn't happen!
+ }
+}
+
+VstInt32 Channel4::canDo(char *text)
+{ return (_canDo.find(text) == _canDo.end()) ? -1 : 1; } // 1 = yes, -1 = no, 0 = don't know
+
+bool Channel4::getEffectName(char* name) {
+ vst_strncpy(name, "Channel4", kVstMaxProductStrLen); return true;
+}
+
+VstPlugCategory Channel4::getPlugCategory() {return kPlugCategEffect;}
+
+bool Channel4::getProductString(char* text) {
+ vst_strncpy (text, "airwindows Channel4", kVstMaxProductStrLen); return true;
+}
+
+bool Channel4::getVendorString(char* text) {
+ vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true;
+}
diff --git a/plugins/LinuxVST/src/Channel4/Channel4.h b/plugins/LinuxVST/src/Channel4/Channel4.h
new file mode 100755
index 0000000..0338d0a
--- /dev/null
+++ b/plugins/LinuxVST/src/Channel4/Channel4.h
@@ -0,0 +1,75 @@
+/* ========================================
+ * Channel4 - Channel4.h
+ * Created 8/12/11 by SPIAdmin
+ * Copyright (c) 2011 __MyCompanyName__, All rights reserved
+ * ======================================== */
+
+#ifndef __Channel4_H
+#define __Channel4_H
+
+#ifndef __audioeffect__
+#include "audioeffectx.h"
+#endif
+
+#include <set>
+#include <string>
+#include <math.h>
+
+enum {
+ kParamA = 0,
+ kParamB = 1,
+ kNumParameters = 2
+}; //
+
+const int kNumPrograms = 0;
+const int kNumInputs = 2;
+const int kNumOutputs = 2;
+const unsigned long kUniqueId = 'cha4'; //Change this to what the AU identity is!
+
+class Channel4 :
+ public AudioEffectX
+{
+public:
+ Channel4(audioMasterCallback audioMaster);
+ ~Channel4();
+ virtual bool getEffectName(char* name); // The plug-in name
+ virtual VstPlugCategory getPlugCategory(); // The general category for the plug-in
+ virtual bool getProductString(char* text); // This is a unique plug-in string provided by Steinberg
+ virtual bool getVendorString(char* text); // Vendor info
+ virtual VstInt32 getVendorVersion(); // Version number
+ virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames);
+ virtual void processDoubleReplacing (double** inputs, double** outputs, VstInt32 sampleFrames);
+ virtual void getProgramName(char *name); // read the name from the host
+ virtual void setProgramName(char *name); // changes the name of the preset displayed in the host
+ virtual VstInt32 getChunk (void** data, bool isPreset);
+ virtual VstInt32 setChunk (void* data, VstInt32 byteSize, bool isPreset);
+ virtual float getParameter(VstInt32 index); // get the parameter value at the specified index
+ virtual void setParameter(VstInt32 index, float value); // set the parameter at index to value
+ virtual void getParameterLabel(VstInt32 index, char *text); // label for the parameter (eg dB)
+ virtual void getParameterName(VstInt32 index, char *text); // name of the parameter
+ virtual void getParameterDisplay(VstInt32 index, char *text); // text description of the current value
+ virtual VstInt32 canDo(char *text);
+private:
+ char _programName[kVstMaxProgNameLen + 1];
+ std::set< std::string > _canDo;
+
+ long double fpNShapeLA;
+ long double fpNShapeLB;
+ long double fpNShapeRA;
+ long double fpNShapeRB;
+ bool fpFlip;
+ //default stuff
+ double iirSampleLA;
+ double iirSampleRA;
+ double iirSampleLB;
+ double iirSampleRB;
+ double lastSampleL;
+ double lastSampleR;
+ double iirAmount;
+ double threshold;
+
+ float consoletype;
+ float drive; //parameters. Always 0-1, and we scale/alter them elsewhere.
+};
+
+#endif
diff --git a/plugins/LinuxVST/src/Channel4/Channel4Proc.cpp b/plugins/LinuxVST/src/Channel4/Channel4Proc.cpp
new file mode 100755
index 0000000..380e52c
--- /dev/null
+++ b/plugins/LinuxVST/src/Channel4/Channel4Proc.cpp
@@ -0,0 +1,288 @@
+/* ========================================
+ * Channel4 - Channel4.h
+ * Copyright (c) 2016 airwindows, All rights reserved
+ * ======================================== */
+
+#ifndef __Channel4_H
+#include "Channel4.h"
+#endif
+
+void Channel4::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames)
+{
+ float* in1 = inputs[0];
+ float* in2 = inputs[1];
+ float* out1 = outputs[0];
+ float* out2 = outputs[1];
+
+ double overallscale = 1.0;
+ overallscale /= 44100.0;
+ overallscale *= getSampleRate();
+ float fpTemp;
+ double fpOld = 0.618033988749894848204586; //golden ratio!
+ double fpNew = 1.0 - fpOld;
+
+ const double localiirAmount = iirAmount / overallscale;
+ const double localthreshold = threshold / overallscale;
+ const double density = pow(drive,2); //this doesn't relate to the plugins Density and Drive much
+ double clamp;
+ long double bridgerectifier;
+
+ long double inputSampleL;
+ long double inputSampleR;
+
+ while (--sampleFrames >= 0)
+ {
+ inputSampleL = *in1;
+ 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.
+ }
+
+ if (fpFlip)
+ {
+ iirSampleLA = (iirSampleLA * (1 - localiirAmount)) + (inputSampleL * localiirAmount);
+ inputSampleL = inputSampleL - iirSampleLA;
+ iirSampleRA = (iirSampleRA * (1 - localiirAmount)) + (inputSampleR * localiirAmount);
+ inputSampleR = inputSampleR - iirSampleRA;
+ }
+ else
+ {
+ iirSampleLB = (iirSampleLB * (1 - localiirAmount)) + (inputSampleL * localiirAmount);
+ inputSampleL = inputSampleL - iirSampleLB;
+ iirSampleRB = (iirSampleRB * (1 - localiirAmount)) + (inputSampleR * localiirAmount);
+ inputSampleR = inputSampleR - iirSampleRB;
+ }
+ //highpass section
+
+ bridgerectifier = fabs(inputSampleL)*1.57079633;
+ if (bridgerectifier > 1.57079633) bridgerectifier = 1.0;
+ else bridgerectifier = sin(bridgerectifier);
+ if (inputSampleL > 0) inputSampleL = (inputSampleL*(1-density))+(bridgerectifier*density);
+ else inputSampleL = (inputSampleL*(1-density))-(bridgerectifier*density);
+
+ bridgerectifier = fabs(inputSampleR)*1.57079633;
+ if (bridgerectifier > 1.57079633) bridgerectifier = 1.0;
+ else bridgerectifier = sin(bridgerectifier);
+ if (inputSampleR > 0) inputSampleR = (inputSampleR*(1-density))+(bridgerectifier*density);
+ else inputSampleR = (inputSampleR*(1-density))-(bridgerectifier*density);
+ //drive section
+
+ clamp = inputSampleL - lastSampleL;
+ if (clamp > localthreshold)
+ inputSampleL = lastSampleL + localthreshold;
+ if (-clamp > localthreshold)
+ inputSampleL = lastSampleL - localthreshold;
+ lastSampleL = inputSampleL;
+
+ clamp = inputSampleR - lastSampleR;
+ if (clamp > localthreshold)
+ inputSampleR = lastSampleR + localthreshold;
+ if (-clamp > localthreshold)
+ inputSampleR = lastSampleR - localthreshold;
+ lastSampleR = inputSampleR;
+ //slew section
+
+ //noise shaping to 32-bit floating point
+ if (fpFlip) {
+ fpTemp = inputSampleL;
+ fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew);
+ inputSampleL += fpNShapeLA;
+ fpTemp = inputSampleR;
+ fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew);
+ inputSampleR += fpNShapeRA;
+ }
+ else {
+ fpTemp = inputSampleL;
+ fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew);
+ inputSampleL += fpNShapeLB;
+ fpTemp = inputSampleR;
+ fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew);
+ inputSampleR += fpNShapeRB;
+ }
+ fpFlip = !fpFlip;
+ //end noise shaping on 32 bit output
+
+ *out1 = inputSampleL;
+ *out2 = inputSampleR;
+
+ *in1++;
+ *in2++;
+ *out1++;
+ *out2++;
+ }
+}
+
+void Channel4::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames)
+{
+ double* in1 = inputs[0];
+ double* in2 = inputs[1];
+ double* out1 = outputs[0];
+ double* out2 = outputs[1];
+
+ double overallscale = 1.0;
+ overallscale /= 44100.0;
+ overallscale *= getSampleRate();
+ double fpTemp; //this is different from singlereplacing
+ double fpOld = 0.618033988749894848204586; //golden ratio!
+ double fpNew = 1.0 - fpOld;
+
+ const double localiirAmount = iirAmount / overallscale;
+ const double localthreshold = threshold / overallscale;
+ const double density = pow(drive,2); //this doesn't relate to the plugins Density and Drive much
+ double clamp;
+ long double bridgerectifier;
+
+ long double inputSampleL;
+ long double inputSampleR;
+
+ while (--sampleFrames >= 0)
+ {
+ inputSampleL = *in1;
+ 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.
+ }
+
+ if (fpFlip)
+ {
+ iirSampleLA = (iirSampleLA * (1 - localiirAmount)) + (inputSampleL * localiirAmount);
+ inputSampleL = inputSampleL - iirSampleLA;
+ iirSampleRA = (iirSampleRA * (1 - localiirAmount)) + (inputSampleR * localiirAmount);
+ inputSampleR = inputSampleR - iirSampleRA;
+ }
+ else
+ {
+ iirSampleLB = (iirSampleLB * (1 - localiirAmount)) + (inputSampleL * localiirAmount);
+ inputSampleL = inputSampleL - iirSampleLB;
+ iirSampleRB = (iirSampleRB * (1 - localiirAmount)) + (inputSampleR * localiirAmount);
+ inputSampleR = inputSampleR - iirSampleRB;
+ }
+ //highpass section
+
+ bridgerectifier = fabs(inputSampleL)*1.57079633;
+ if (bridgerectifier > 1.57079633) bridgerectifier = 1.0;
+ else bridgerectifier = sin(bridgerectifier);
+ if (inputSampleL > 0) inputSampleL = (inputSampleL*(1-density))+(bridgerectifier*density);
+ else inputSampleL = (inputSampleL*(1-density))-(bridgerectifier*density);
+
+ bridgerectifier = fabs(inputSampleR)*1.57079633;
+ if (bridgerectifier > 1.57079633) bridgerectifier = 1.0;
+ else bridgerectifier = sin(bridgerectifier);
+ if (inputSampleR > 0) inputSampleR = (inputSampleR*(1-density))+(bridgerectifier*density);
+ else inputSampleR = (inputSampleR*(1-density))-(bridgerectifier*density);
+ //drive section
+
+ clamp = inputSampleL - lastSampleL;
+ if (clamp > localthreshold)
+ inputSampleL = lastSampleL + localthreshold;
+ if (-clamp > localthreshold)
+ inputSampleL = lastSampleL - localthreshold;
+ lastSampleL = inputSampleL;
+
+ clamp = inputSampleR - lastSampleR;
+ if (clamp > localthreshold)
+ inputSampleR = lastSampleR + localthreshold;
+ if (-clamp > localthreshold)
+ inputSampleR = lastSampleR - localthreshold;
+ lastSampleR = inputSampleR;
+ //slew section
+
+ //noise shaping to 64-bit floating point
+ if (fpFlip) {
+ fpTemp = inputSampleL;
+ fpNShapeLA = (fpNShapeLA*fpOld)+((inputSampleL-fpTemp)*fpNew);
+ inputSampleL += fpNShapeLA;
+ fpTemp = inputSampleR;
+ fpNShapeRA = (fpNShapeRA*fpOld)+((inputSampleR-fpTemp)*fpNew);
+ inputSampleR += fpNShapeRA;
+ }
+ else {
+ fpTemp = inputSampleL;
+ fpNShapeLB = (fpNShapeLB*fpOld)+((inputSampleL-fpTemp)*fpNew);
+ inputSampleL += fpNShapeLB;
+ fpTemp = inputSampleR;
+ fpNShapeRB = (fpNShapeRB*fpOld)+((inputSampleR-fpTemp)*fpNew);
+ inputSampleR += fpNShapeRB;
+ }
+ fpFlip = !fpFlip;
+ //end noise shaping on 64 bit output
+
+ *out1 = inputSampleL;
+ *out2 = inputSampleR;
+
+ *in1++;
+ *in2++;
+ *out1++;
+ *out2++;
+ }
+} \ No newline at end of file
diff --git a/plugins/LinuxVST/src/Righteous4/Righteous4.cpp b/plugins/LinuxVST/src/Righteous4/Righteous4.cpp
new file mode 100755
index 0000000..3c50a74
--- /dev/null
+++ b/plugins/LinuxVST/src/Righteous4/Righteous4.cpp
@@ -0,0 +1,223 @@
+/* ========================================
+ * Righteous4 - Righteous4.h
+ * Copyright (c) 2016 airwindows, All rights reserved
+ * ======================================== */
+
+#ifndef __Righteous4_H
+#include "Righteous4.h"
+#endif
+
+AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new Righteous4(audioMaster);}
+
+Righteous4::Righteous4(audioMasterCallback audioMaster) :
+ AudioEffectX(audioMaster, kNumPrograms, kNumParameters)
+{
+ A = 0.0;
+ B = 0.0;
+
+ leftSampleA = 0.0;
+ leftSampleB = 0.0;
+ leftSampleC = 0.0;
+ leftSampleD = 0.0;
+ leftSampleE = 0.0;
+ leftSampleF = 0.0;
+ leftSampleG = 0.0;
+ leftSampleH = 0.0;
+ leftSampleI = 0.0;
+ leftSampleJ = 0.0;
+ leftSampleK = 0.0;
+ leftSampleL = 0.0;
+ leftSampleM = 0.0;
+ leftSampleN = 0.0;
+ leftSampleO = 0.0;
+ leftSampleP = 0.0;
+ leftSampleQ = 0.0;
+ leftSampleR = 0.0;
+ leftSampleS = 0.0;
+ leftSampleT = 0.0;
+ leftSampleU = 0.0;
+ leftSampleV = 0.0;
+ leftSampleW = 0.0;
+ leftSampleX = 0.0;
+ leftSampleY = 0.0;
+ leftSampleZ = 0.0;
+
+ rightSampleA = 0.0;
+ rightSampleB = 0.0;
+ rightSampleC = 0.0;
+ rightSampleD = 0.0;
+ rightSampleE = 0.0;
+ rightSampleF = 0.0;
+ rightSampleG = 0.0;
+ rightSampleH = 0.0;
+ rightSampleI = 0.0;
+ rightSampleJ = 0.0;
+ rightSampleK = 0.0;
+ rightSampleL = 0.0;
+ rightSampleM = 0.0;
+ rightSampleN = 0.0;
+ rightSampleO = 0.0;
+ rightSampleP = 0.0;
+ rightSampleQ = 0.0;
+ rightSampleR = 0.0;
+ rightSampleS = 0.0;
+ rightSampleT = 0.0;
+ rightSampleU = 0.0;
+ rightSampleV = 0.0;
+ rightSampleW = 0.0;
+ rightSampleX = 0.0;
+ rightSampleY = 0.0;
+ rightSampleZ = 0.0;
+
+ bynL[0] = 1000;
+ bynL[1] = 301;
+ bynL[2] = 176;
+ bynL[3] = 125;
+ bynL[4] = 97;
+ bynL[5] = 79;
+ bynL[6] = 67;
+ bynL[7] = 58;
+ bynL[8] = 51;
+ bynL[9] = 46;
+ bynL[10] = 1000;
+ noiseShapingL = 0.0;
+ lastSampleL = 0.0;
+ IIRsampleL = 0.0;
+ gwPrevL = 0.0;
+ gwAL = 0.0;
+ gwBL = 0.0;
+
+ bynR[0] = 1000;
+ bynR[1] = 301;
+ bynR[2] = 176;
+ bynR[3] = 125;
+ bynR[4] = 97;
+ bynR[5] = 79;
+ bynR[6] = 67;
+ bynR[7] = 58;
+ bynR[8] = 51;
+ bynR[9] = 46;
+ bynR[10] = 1000;
+ noiseShapingR = 0.0;
+ lastSampleR = 0.0;
+ IIRsampleR = 0.0;
+ gwPrevR = 0.0;
+ gwAR = 0.0;
+ gwBR = 0.0;
+
+ fpNShapeL = 0.0;
+ fpNShapeR = 0.0;
+ //this is reset: values being initialized only once. Startup values, whatever they are.
+
+ _canDo.insert("plugAsChannelInsert"); // plug-in can be used as a channel insert effect.
+ _canDo.insert("plugAsSend"); // plug-in can be used as a send effect.
+ _canDo.insert("x2in2out");
+ setNumInputs(kNumInputs);
+ setNumOutputs(kNumOutputs);
+ setUniqueID(kUniqueId);
+ canProcessReplacing(); // supports output replacing
+ canDoubleReplacing(); // supports double precision processing
+ programsAreChunks(true);
+ vst_strncpy (_programName, "Default", kVstMaxProgNameLen); // default program name
+}
+
+Righteous4::~Righteous4() {}
+VstInt32 Righteous4::getVendorVersion () {return 1000;}
+void Righteous4::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);}
+void Righteous4::getProgramName(char *name) {vst_strncpy (name, _programName, kVstMaxProgNameLen);}
+//airwindows likes to ignore this stuff. Make your own programs, and make a different plugin rather than
+//trying to do versioning and preventing people from using older versions. Maybe they like the old one!
+
+static float pinParameter(float data)
+{
+ if (data < 0.0f) return 0.0f;
+ if (data > 1.0f) return 1.0f;
+ return data;
+}
+
+VstInt32 Righteous4::getChunk (void** data, bool isPreset)
+{
+ float *chunkData = (float *)calloc(kNumParameters, sizeof(float));
+ chunkData[0] = A;
+ chunkData[1] = B;
+ /* Note: The way this is set up, it will break if you manage to save settings on an Intel
+ machine and load them on a PPC Mac. However, it's fine if you stick to the machine you
+ started with. */
+
+ *data = chunkData;
+ return kNumParameters * sizeof(float);
+}
+
+VstInt32 Righteous4::setChunk (void* data, VstInt32 byteSize, bool isPreset)
+{
+ float *chunkData = (float *)data;
+ A = pinParameter(chunkData[0]);
+ B = pinParameter(chunkData[1]);
+ /* We're ignoring byteSize as we found it to be a filthy liar */
+
+ /* calculate any other fields you need here - you could copy in
+ code from setParameter() here. */
+ return 0;
+}
+
+void Righteous4::setParameter(VstInt32 index, float value) {
+ switch (index) {
+ case kParamA: A = value; break;
+ case kParamB: B = value; break;
+ default: throw; // unknown parameter, shouldn't happen!
+ }
+}
+
+float Righteous4::getParameter(VstInt32 index) {
+ switch (index) {
+ case kParamA: return A; break;
+ case kParamB: return B; break;
+ default: break; // unknown parameter, shouldn't happen!
+ } return 0.0; //we only need to update the relevant name, this is simple to manage
+}
+
+void Righteous4::getParameterName(VstInt32 index, char *text) {
+ switch (index) {
+ case kParamA: vst_strncpy (text, "LTarget", kVstMaxParamStrLen); break;
+ case kParamB: vst_strncpy (text, "BtDepth", kVstMaxParamStrLen); break;
+ default: break; // unknown parameter, shouldn't happen!
+ } //this is our labels for displaying in the VST host
+}
+
+void Righteous4::getParameterDisplay(VstInt32 index, char *text) {
+ switch (index) {
+ case kParamA: float2string ((A*24.0)-28.0, text, kVstMaxParamStrLen); break;
+ case kParamB: switch((VstInt32)( B * 2.999 )) //0 to almost edge of # of params
+ {case 0: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
+ case 1: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
+ case 2: vst_strncpy (text, "32", kVstMaxParamStrLen); break;
+ default: break; // unknown parameter, shouldn't happen!
+ } break;
+ default: break; // unknown parameter, shouldn't happen!
+ } //this displays the values and handles 'popups' where it's discrete choices
+}
+
+void Righteous4::getParameterLabel(VstInt32 index, char *text) {
+ switch (index) {
+ case kParamA: vst_strncpy (text, "dB", kVstMaxParamStrLen); break;
+ case kParamB: vst_strncpy (text, "bit", kVstMaxParamStrLen); break;
+ default: break; // unknown parameter, shouldn't happen!
+ }
+}
+
+VstInt32 Righteous4::canDo(char *text)
+{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know
+
+bool Righteous4::getEffectName(char* name) {
+ vst_strncpy(name, "Righteous4", kVstMaxProductStrLen); return true;
+}
+
+VstPlugCategory Righteous4::getPlugCategory() {return kPlugCategEffect;}
+
+bool Righteous4::getProductString(char* text) {
+ vst_strncpy (text, "airwindows Righteous4", kVstMaxProductStrLen); return true;
+}
+
+bool Righteous4::getVendorString(char* text) {
+ vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true;
+}
diff --git a/plugins/LinuxVST/src/Righteous4/Righteous4.h b/plugins/LinuxVST/src/Righteous4/Righteous4.h
new file mode 100755
index 0000000..8b9e44b
--- /dev/null
+++ b/plugins/LinuxVST/src/Righteous4/Righteous4.h
@@ -0,0 +1,134 @@
+/* ========================================
+ * Righteous4 - Righteous4.h
+ * Created 8/12/11 by SPIAdmin
+ * Copyright (c) 2011 __MyCompanyName__, All rights reserved
+ * ======================================== */
+
+#ifndef __Righteous4_H
+#define __Righteous4_H
+
+#ifndef __audioeffect__
+#include "audioeffectx.h"
+#endif
+
+#include <set>
+#include <string>
+#include <math.h>
+
+enum {
+ kParamA = 0,
+ kParamB = 1,
+ kNumParameters = 2
+}; //
+
+const int kNumPrograms = 0;
+const int kNumInputs = 2;
+const int kNumOutputs = 2;
+const unsigned long kUniqueId = 'rigk'; //Change this to what the AU identity is!
+
+class Righteous4 :
+ public AudioEffectX
+{
+public:
+ Righteous4(audioMasterCallback audioMaster);
+ ~Righteous4();
+ virtual bool getEffectName(char* name); // The plug-in name
+ virtual VstPlugCategory getPlugCategory(); // The general category for the plug-in
+ virtual bool getProductString(char* text); // This is a unique plug-in string provided by Steinberg
+ virtual bool getVendorString(char* text); // Vendor info
+ virtual VstInt32 getVendorVersion(); // Version number
+ virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames);
+ virtual void processDoubleReplacing (double** inputs, double** outputs, VstInt32 sampleFrames);
+ virtual void getProgramName(char *name); // read the name from the host
+ virtual void setProgramName(char *name); // changes the name of the preset displayed in the host
+ virtual VstInt32 getChunk (void** data, bool isPreset);
+ virtual VstInt32 setChunk (void* data, VstInt32 byteSize, bool isPreset);
+ virtual float getParameter(VstInt32 index); // get the parameter value at the specified index
+ virtual void setParameter(VstInt32 index, float value); // set the parameter at index to value
+ virtual void getParameterLabel(VstInt32 index, char *text); // label for the parameter (eg dB)
+ virtual void getParameterName(VstInt32 index, char *text); // name of the parameter
+ virtual void getParameterDisplay(VstInt32 index, char *text); // text description of the current value
+ virtual VstInt32 canDo(char *text);
+private:
+ char _programName[kVstMaxProgNameLen + 1];
+ std::set< std::string > _canDo;
+
+ double leftSampleA;
+ double leftSampleB;
+ double leftSampleC;
+ double leftSampleD;
+ double leftSampleE;
+ double leftSampleF;
+ double leftSampleG;
+ double leftSampleH;
+ double leftSampleI;
+ double leftSampleJ;
+ double leftSampleK;
+ double leftSampleL;
+ double leftSampleM;
+ double leftSampleN;
+ double leftSampleO;
+ double leftSampleP;
+ double leftSampleQ;
+ double leftSampleR;
+ double leftSampleS;
+ double leftSampleT;
+ double leftSampleU;
+ double leftSampleV;
+ double leftSampleW;
+ double leftSampleX;
+ double leftSampleY;
+ double leftSampleZ;
+
+ double rightSampleA;
+ double rightSampleB;
+ double rightSampleC;
+ double rightSampleD;
+ double rightSampleE;
+ double rightSampleF;
+ double rightSampleG;
+ double rightSampleH;
+ double rightSampleI;
+ double rightSampleJ;
+ double rightSampleK;
+ double rightSampleL;
+ double rightSampleM;
+ double rightSampleN;
+ double rightSampleO;
+ double rightSampleP;
+ double rightSampleQ;
+ double rightSampleR;
+ double rightSampleS;
+ double rightSampleT;
+ double rightSampleU;
+ double rightSampleV;
+ double rightSampleW;
+ double rightSampleX;
+ double rightSampleY;
+ double rightSampleZ;
+
+ double bynL[13];
+ long double noiseShapingL;
+ double lastSampleL;
+ double IIRsampleL;
+ double gwPrevL;
+ double gwAL;
+ double gwBL;
+
+ double bynR[13];
+ long double noiseShapingR;
+ double lastSampleR;
+ double IIRsampleR;
+ double gwPrevR;
+ double gwAR;
+ double gwBR;
+
+ long double fpNShapeL;
+ long double fpNShapeR;
+ //default stuff
+
+ float A;
+ float B;
+};
+
+#endif
diff --git a/plugins/LinuxVST/src/Righteous4/Righteous4Proc.cpp b/plugins/LinuxVST/src/Righteous4/Righteous4Proc.cpp
new file mode 100755
index 0000000..7ed44cf
--- /dev/null
+++ b/plugins/LinuxVST/src/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