diff options
author | airwindows <jinx6568@sover.net> | 2018-04-08 20:25:10 -0400 |
---|---|---|
committer | airwindows <jinx6568@sover.net> | 2018-04-08 20:25:10 -0400 |
commit | 4d9d683cc1101c3ffc4a96408b035f4dc6f30f5d (patch) | |
tree | e62f096a25568d317948f5ddd8184fa7db830413 /plugins/LinuxVST | |
parent | 31a2f1a4e8f1c4aa7d4b7c36dd32ec5d0298b91b (diff) | |
download | airwindows-lv2-port-4d9d683cc1101c3ffc4a96408b035f4dc6f30f5d.tar.gz airwindows-lv2-port-4d9d683cc1101c3ffc4a96408b035f4dc6f30f5d.tar.bz2 airwindows-lv2-port-4d9d683cc1101c3ffc4a96408b035f4dc6f30f5d.zip |
EQ
Diffstat (limited to 'plugins/LinuxVST')
-rwxr-xr-x | plugins/LinuxVST/CMakeLists.txt | 1 | ||||
-rwxr-xr-x | plugins/LinuxVST/src/EQ/EQ.cpp | 269 | ||||
-rwxr-xr-x | plugins/LinuxVST/src/EQ/EQ.h | 173 | ||||
-rwxr-xr-x | plugins/LinuxVST/src/EQ/EQProc.cpp | 922 |
4 files changed, 1365 insertions, 0 deletions
diff --git a/plugins/LinuxVST/CMakeLists.txt b/plugins/LinuxVST/CMakeLists.txt index 10020a1..db253e1 100755 --- a/plugins/LinuxVST/CMakeLists.txt +++ b/plugins/LinuxVST/CMakeLists.txt @@ -12,6 +12,7 @@ add_airwindows_plugin(BitShiftGain) add_airwindows_plugin(C5RawBuss) add_airwindows_plugin(C5RawChannel) add_airwindows_plugin(ElectroHat) +add_airwindows_plugin(EQ) add_airwindows_plugin(GrooveWear) add_airwindows_plugin(HardVacuum) add_airwindows_plugin(NonlinearSpace) diff --git a/plugins/LinuxVST/src/EQ/EQ.cpp b/plugins/LinuxVST/src/EQ/EQ.cpp new file mode 100755 index 0000000..ebdadaa --- /dev/null +++ b/plugins/LinuxVST/src/EQ/EQ.cpp @@ -0,0 +1,269 @@ +/* ======================================== + * EQ - EQ.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __EQ_H +#include "EQ.h" +#endif + +AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new EQ(audioMaster);} + +EQ::EQ(audioMasterCallback audioMaster) : + AudioEffectX(audioMaster, kNumPrograms, kNumParameters) +{ + A = 0.5; //Treble -12 to 12 + B = 0.5; //Mid -12 to 12 + C = 0.5; //Bass -12 to 12 + D = 1.0; //Lowpass 16.0K log 1 to 16 defaulting to 16K + E = 0.4; //TrebFrq 6.0 log 1 to 16 defaulting to 6K + F = 0.4; //BassFrq 100.0 log 30 to 1600 defaulting to 100 hz + G = 0.0; //Hipass 30.0 log 30 to 1600 defaulting to 30 + H = 0.5; //OutGain -18 to 18 + + lastSampleL = 0.0; + last2SampleL = 0.0; + lastSampleR = 0.0; + last2SampleR = 0.0; + + iirHighSampleLA = 0.0; + iirHighSampleLB = 0.0; + iirHighSampleLC = 0.0; + iirHighSampleLD = 0.0; + iirHighSampleLE = 0.0; + iirLowSampleLA = 0.0; + iirLowSampleLB = 0.0; + iirLowSampleLC = 0.0; + iirLowSampleLD = 0.0; + iirLowSampleLE = 0.0; + iirHighSampleL = 0.0; + iirLowSampleL = 0.0; + + iirHighSampleRA = 0.0; + iirHighSampleRB = 0.0; + iirHighSampleRC = 0.0; + iirHighSampleRD = 0.0; + iirHighSampleRE = 0.0; + iirLowSampleRA = 0.0; + iirLowSampleRB = 0.0; + iirLowSampleRC = 0.0; + iirLowSampleRD = 0.0; + iirLowSampleRE = 0.0; + iirHighSampleR = 0.0; + iirLowSampleR = 0.0; + + tripletLA = 0.0; + tripletLB = 0.0; + tripletLC = 0.0; + tripletFactorL = 0.0; + + tripletRA = 0.0; + tripletRB = 0.0; + tripletRC = 0.0; + tripletFactorR = 0.0; + + lowpassSampleLAA = 0.0; + lowpassSampleLAB = 0.0; + lowpassSampleLBA = 0.0; + lowpassSampleLBB = 0.0; + lowpassSampleLCA = 0.0; + lowpassSampleLCB = 0.0; + lowpassSampleLDA = 0.0; + lowpassSampleLDB = 0.0; + lowpassSampleLE = 0.0; + lowpassSampleLF = 0.0; + lowpassSampleLG = 0.0; + + lowpassSampleRAA = 0.0; + lowpassSampleRAB = 0.0; + lowpassSampleRBA = 0.0; + lowpassSampleRBB = 0.0; + lowpassSampleRCA = 0.0; + lowpassSampleRCB = 0.0; + lowpassSampleRDA = 0.0; + lowpassSampleRDB = 0.0; + lowpassSampleRE = 0.0; + lowpassSampleRF = 0.0; + lowpassSampleRG = 0.0; + + highpassSampleLAA = 0.0; + highpassSampleLAB = 0.0; + highpassSampleLBA = 0.0; + highpassSampleLBB = 0.0; + highpassSampleLCA = 0.0; + highpassSampleLCB = 0.0; + highpassSampleLDA = 0.0; + highpassSampleLDB = 0.0; + highpassSampleLE = 0.0; + highpassSampleLF = 0.0; + + highpassSampleRAA = 0.0; + highpassSampleRAB = 0.0; + highpassSampleRBA = 0.0; + highpassSampleRBB = 0.0; + highpassSampleRCA = 0.0; + highpassSampleRCB = 0.0; + highpassSampleRDA = 0.0; + highpassSampleRDB = 0.0; + highpassSampleRE = 0.0; + highpassSampleRF = 0.0; + + flip = false; + flipthree = 0; + + fpNShapeLA = 0.0; + fpNShapeLB = 0.0; + fpNShapeRA = 0.0; + fpNShapeRB = 0.0; + fpFlip = true; + //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 +} + +EQ::~EQ() {} +VstInt32 EQ::getVendorVersion () {return 1000;} +void EQ::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} +void EQ::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 EQ::getChunk (void** data, bool isPreset) +{ + float *chunkData = (float *)calloc(kNumParameters, sizeof(float)); + chunkData[0] = A; + chunkData[1] = B; + chunkData[2] = C; + chunkData[3] = D; + chunkData[4] = E; + chunkData[5] = F; + chunkData[6] = G; + chunkData[7] = H; + /* 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 EQ::setChunk (void* data, VstInt32 byteSize, bool isPreset) +{ + float *chunkData = (float *)data; + A = pinParameter(chunkData[0]); + B = pinParameter(chunkData[1]); + C = pinParameter(chunkData[2]); + D = pinParameter(chunkData[3]); + E = pinParameter(chunkData[4]); + F = pinParameter(chunkData[5]); + G = pinParameter(chunkData[6]); + H = pinParameter(chunkData[7]); + /* 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 EQ::setParameter(VstInt32 index, float value) { + switch (index) { + case kParamA: A = value; break; + case kParamB: B = value; break; + case kParamC: C = value; break; + case kParamD: D = value; break; + case kParamE: E = value; break; + case kParamF: F = value; break; + case kParamG: G = value; break; + case kParamH: H = value; break; + default: throw; // unknown parameter, shouldn't happen! + } +} + +float EQ::getParameter(VstInt32 index) { + switch (index) { + case kParamA: return A; break; + case kParamB: return B; break; + case kParamC: return C; break; + case kParamD: return D; break; + case kParamE: return E; break; + case kParamF: return F; break; + case kParamG: return G; break; + case kParamH: return H; 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 EQ::getParameterName(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "Treble", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "Mid", kVstMaxParamStrLen); break; + case kParamC: vst_strncpy (text, "Bass", kVstMaxParamStrLen); break; + case kParamD: vst_strncpy (text, "Lowpass", kVstMaxParamStrLen); break; + case kParamE: vst_strncpy (text, "TrebFrq", kVstMaxParamStrLen); break; + case kParamF: vst_strncpy (text, "BassFrq", kVstMaxParamStrLen); break; + case kParamG: vst_strncpy (text, "Hipass", kVstMaxParamStrLen); break; + case kParamH: vst_strncpy (text, "OutGain", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this is our labels for displaying in the VST host +} + +void EQ::getParameterDisplay(VstInt32 index, char *text) { + switch (index) { + case kParamA: float2string ((A*24.0)-12.0, text, kVstMaxParamStrLen); break; //Treble -12 to 12 + case kParamB: float2string ((B*24.0)-12.0, text, kVstMaxParamStrLen); break; //Mid -12 to 12 + case kParamC: float2string ((C*24.0)-12.0, text, kVstMaxParamStrLen); break; //Bass -12 to 12 + case kParamD: float2string ((D*D*15.0)+1.0, text, kVstMaxParamStrLen); break; //Lowpass 16.0K log 1 to 16 defaulting to 16K + case kParamE: float2string ((E*E*15.0)+1.0, text, kVstMaxParamStrLen); break; //TrebFrq 6.0 log 1 to 16 defaulting to 6K + case kParamF: float2string ((F*F*1570.0)+30.0, text, kVstMaxParamStrLen); break; //BassFrq 100.0 log 30 to 1600 defaulting to 100 hz + case kParamG: float2string ((G*G*1570.0)+30.0, text, kVstMaxParamStrLen); break; //Hipass 30.0 log 30 to 1600 defaulting to 30 + case kParamH: float2string ((H*36.0)-18.0, text, kVstMaxParamStrLen); break; //OutGain -18 to 18 + default: break; // unknown parameter, shouldn't happen! + } //this displays the values and handles 'popups' where it's discrete choices +} + +void EQ::getParameterLabel(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "dB", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "dB", kVstMaxParamStrLen); break; + case kParamC: vst_strncpy (text, "dB", kVstMaxParamStrLen); break; + case kParamD: vst_strncpy (text, "Khz", kVstMaxParamStrLen); break; + case kParamE: vst_strncpy (text, "Khz", kVstMaxParamStrLen); break; + case kParamF: vst_strncpy (text, "hz", kVstMaxParamStrLen); break; + case kParamG: vst_strncpy (text, "hz", kVstMaxParamStrLen); break; + case kParamH: vst_strncpy (text, "dB", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } +} + +VstInt32 EQ::canDo(char *text) +{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know + +bool EQ::getEffectName(char* name) { + vst_strncpy(name, "EQ", kVstMaxProductStrLen); return true; +} + +VstPlugCategory EQ::getPlugCategory() {return kPlugCategEffect;} + +bool EQ::getProductString(char* text) { + vst_strncpy (text, "airwindows EQ", kVstMaxProductStrLen); return true; +} + +bool EQ::getVendorString(char* text) { + vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; +} diff --git a/plugins/LinuxVST/src/EQ/EQ.h b/plugins/LinuxVST/src/EQ/EQ.h new file mode 100755 index 0000000..4317a2d --- /dev/null +++ b/plugins/LinuxVST/src/EQ/EQ.h @@ -0,0 +1,173 @@ +/* ======================================== + * EQ - EQ.h + * Created 8/12/11 by SPIAdmin + * Copyright (c) 2011 __MyCompanyName__, All rights reserved + * ======================================== */ + +#ifndef __EQ_H +#define __EQ_H + +#ifndef __audioeffect__ +#include "audioeffectx.h" +#endif + +#include <set> +#include <string> +#include <math.h> + +enum { + kParamA = 0, + kParamB = 1, + kParamC = 2, + kParamD = 3, + kParamE = 4, + kParamF = 5, + kParamG = 6, + kParamH = 7, + kNumParameters = 8 +}; // + +const int kNumPrograms = 0; +const int kNumInputs = 2; +const int kNumOutputs = 2; +const unsigned long kUniqueId = 'eqeq'; //Change this to what the AU identity is! + +class EQ : + public AudioEffectX +{ +public: + EQ(audioMasterCallback audioMaster); + ~EQ(); + 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 lastSampleL; + double last2SampleL; + double lastSampleR; + double last2SampleR; + + //begin EQ + double iirHighSampleLA; + double iirHighSampleLB; + double iirHighSampleLC; + double iirHighSampleLD; + double iirHighSampleLE; + double iirLowSampleLA; + double iirLowSampleLB; + double iirLowSampleLC; + double iirLowSampleLD; + double iirLowSampleLE; + double iirHighSampleL; + double iirLowSampleL; + + double iirHighSampleRA; + double iirHighSampleRB; + double iirHighSampleRC; + double iirHighSampleRD; + double iirHighSampleRE; + double iirLowSampleRA; + double iirLowSampleRB; + double iirLowSampleRC; + double iirLowSampleRD; + double iirLowSampleRE; + double iirHighSampleR; + double iirLowSampleR; + + double tripletLA; + double tripletLB; + double tripletLC; + double tripletFactorL; + + double tripletRA; + double tripletRB; + double tripletRC; + double tripletFactorR; + + double lowpassSampleLAA; + double lowpassSampleLAB; + double lowpassSampleLBA; + double lowpassSampleLBB; + double lowpassSampleLCA; + double lowpassSampleLCB; + double lowpassSampleLDA; + double lowpassSampleLDB; + double lowpassSampleLE; + double lowpassSampleLF; + double lowpassSampleLG; + + double lowpassSampleRAA; + double lowpassSampleRAB; + double lowpassSampleRBA; + double lowpassSampleRBB; + double lowpassSampleRCA; + double lowpassSampleRCB; + double lowpassSampleRDA; + double lowpassSampleRDB; + double lowpassSampleRE; + double lowpassSampleRF; + double lowpassSampleRG; + + double highpassSampleLAA; + double highpassSampleLAB; + double highpassSampleLBA; + double highpassSampleLBB; + double highpassSampleLCA; + double highpassSampleLCB; + double highpassSampleLDA; + double highpassSampleLDB; + double highpassSampleLE; + double highpassSampleLF; + + double highpassSampleRAA; + double highpassSampleRAB; + double highpassSampleRBA; + double highpassSampleRBB; + double highpassSampleRCA; + double highpassSampleRCB; + double highpassSampleRDA; + double highpassSampleRDB; + double highpassSampleRE; + double highpassSampleRF; + + bool flip; + int flipthree; + //end EQ + + + float A; + float B; + float C; + float D; + float E; + float F; + float G; + float H; + +}; + +#endif diff --git a/plugins/LinuxVST/src/EQ/EQProc.cpp b/plugins/LinuxVST/src/EQ/EQProc.cpp new file mode 100755 index 0000000..6d994a9 --- /dev/null +++ b/plugins/LinuxVST/src/EQ/EQProc.cpp @@ -0,0 +1,922 @@ +/* ======================================== + * EQ - EQ.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __EQ_H +#include "EQ.h" +#endif + +void EQ::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; + double compscale = overallscale; + overallscale = getSampleRate(); + compscale = compscale * overallscale; + //compscale is the one that's 1 or something like 2.2 for 96K rates + float fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + long double inputSampleL; + long double inputSampleR; + + double highSampleL = 0.0; + double midSampleL = 0.0; + double bassSampleL = 0.0; + + double highSampleR = 0.0; + double midSampleR = 0.0; + double bassSampleR = 0.0; + + double densityA = (A*12.0)-6.0; + double densityB = (B*12.0)-6.0; + double densityC = (C*12.0)-6.0; + bool engageEQ = true; + if ( (0.0 == densityA) && (0.0 == densityB) && (0.0 == densityC) ) engageEQ = false; + + densityA = pow(10.0,densityA/20.0)-1.0; + densityB = pow(10.0,densityB/20.0)-1.0; + densityC = pow(10.0,densityC/20.0)-1.0; + //convert to 0 to X multiplier with 1.0 being O db + //minus one gives nearly -1 to ? (should top out at 1) + //calibrate so that X db roughly equals X db with maximum topping out at 1 internally + + double tripletIntensity = -densityA; + + double iirAmountC = (((D*D*15.0)+1.0)*0.0188) + 0.7; + if (iirAmountC > 1.0) iirAmountC = 1.0; + bool engageLowpass = false; + if (((D*D*15.0)+1.0) < 15.99) engageLowpass = true; + + double iirAmountA = (((E*E*15.0)+1.0)*1000)/overallscale; + double iirAmountB = (((F*F*1570.0)+30.0)*10)/overallscale; + double iirAmountD = (((G*G*1570.0)+30.0)*1.0)/overallscale; + bool engageHighpass = false; + if (((G*G*1570.0)+30.0) > 30.01) engageHighpass = true; + //bypass the highpass and lowpass if set to extremes + double bridgerectifier; + double outA = fabs(densityA); + double outB = fabs(densityB); + double outC = fabs(densityC); + //end EQ + double outputgain = pow(10.0,((H*36.0)-18.0)/20.0); + + 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. + } + + last2SampleL = lastSampleL; + lastSampleL = inputSampleL; + + last2SampleR = lastSampleR; + lastSampleR = inputSampleR; + + flip = !flip; + flipthree++; + if (flipthree < 1 || flipthree > 3) flipthree = 1; + //counters + + //begin highpass + if (engageHighpass) + { + if (flip) + { + highpassSampleLAA = (highpassSampleLAA * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLAA; + highpassSampleLBA = (highpassSampleLBA * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLBA; + highpassSampleLCA = (highpassSampleLCA * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLCA; + highpassSampleLDA = (highpassSampleLDA * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLDA; + } + else + { + highpassSampleLAB = (highpassSampleLAB * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLAB; + highpassSampleLBB = (highpassSampleLBB * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLBB; + highpassSampleLCB = (highpassSampleLCB * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLCB; + highpassSampleLDB = (highpassSampleLDB * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLDB; + } + highpassSampleLE = (highpassSampleLE * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLE; + highpassSampleLF = (highpassSampleLF * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLF; + + if (flip) + { + highpassSampleRAA = (highpassSampleRAA * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRAA; + highpassSampleRBA = (highpassSampleRBA * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRBA; + highpassSampleRCA = (highpassSampleRCA * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRCA; + highpassSampleRDA = (highpassSampleRDA * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRDA; + } + else + { + highpassSampleRAB = (highpassSampleRAB * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRAB; + highpassSampleRBB = (highpassSampleRBB * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRBB; + highpassSampleRCB = (highpassSampleRCB * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRCB; + highpassSampleRDB = (highpassSampleRDB * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRDB; + } + highpassSampleRE = (highpassSampleRE * (1 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRE; + highpassSampleRF = (highpassSampleRF * (1 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRF; + + } + //end highpass + + //begin EQ + if (engageEQ) + { + switch (flipthree) + { + case 1: + tripletFactorL = last2SampleL - inputSampleL; + tripletLA += tripletFactorL; + tripletLC -= tripletFactorL; + tripletFactorL = tripletLA * tripletIntensity; + iirHighSampleLC = (iirHighSampleLC * (1.0 - iirAmountA)) + (inputSampleL * iirAmountA); + highSampleL = inputSampleL - iirHighSampleLC; + iirLowSampleLC = (iirLowSampleLC * (1.0 - iirAmountB)) + (inputSampleL * iirAmountB); + bassSampleL = iirLowSampleLC; + + tripletFactorR = last2SampleR - inputSampleR; + tripletRA += tripletFactorR; + tripletRC -= tripletFactorR; + tripletFactorR = tripletRA * tripletIntensity; + iirHighSampleRC = (iirHighSampleRC * (1.0 - iirAmountA)) + (inputSampleR * iirAmountA); + highSampleR = inputSampleR - iirHighSampleRC; + iirLowSampleRC = (iirLowSampleRC * (1.0 - iirAmountB)) + (inputSampleR * iirAmountB); + bassSampleR = iirLowSampleRC; + break; + case 2: + tripletFactorL = last2SampleL - inputSampleL; + tripletLB += tripletFactorL; + tripletLA -= tripletFactorL; + tripletFactorL = tripletLB * tripletIntensity; + iirHighSampleLD = (iirHighSampleLD * (1.0 - iirAmountA)) + (inputSampleL * iirAmountA); + highSampleL = inputSampleL - iirHighSampleLD; + iirLowSampleLD = (iirLowSampleLD * (1.0 - iirAmountB)) + (inputSampleL * iirAmountB); + bassSampleL = iirLowSampleLD; + + tripletFactorR = last2SampleR - inputSampleR; + tripletRB += tripletFactorR; + tripletRA -= tripletFactorR; + tripletFactorR = tripletRB * tripletIntensity; + iirHighSampleRD = (iirHighSampleRD * (1.0 - iirAmountA)) + (inputSampleR * iirAmountA); + highSampleR = inputSampleR - iirHighSampleRD; + iirLowSampleRD = (iirLowSampleRD * (1.0 - iirAmountB)) + (inputSampleR * iirAmountB); + bassSampleR = iirLowSampleRD; + break; + case 3: + tripletFactorL = last2SampleL - inputSampleL; + tripletLC += tripletFactorL; + tripletLB -= tripletFactorL; + tripletFactorL = tripletLC * tripletIntensity; + iirHighSampleLE = (iirHighSampleLE * (1.0 - iirAmountA)) + (inputSampleL * iirAmountA); + highSampleL = inputSampleL - iirHighSampleLE; + iirLowSampleLE = (iirLowSampleLE * (1.0 - iirAmountB)) + (inputSampleL * iirAmountB); + bassSampleL = iirLowSampleLE; + + tripletFactorR = last2SampleR - inputSampleR; + tripletRC += tripletFactorR; + tripletRB -= tripletFactorR; + tripletFactorR = tripletRC * tripletIntensity; + iirHighSampleRE = (iirHighSampleRE * (1.0 - iirAmountA)) + (inputSampleR * iirAmountA); + highSampleR = inputSampleR - iirHighSampleRE; + iirLowSampleRE = (iirLowSampleRE * (1.0 - iirAmountB)) + (inputSampleR * iirAmountB); + bassSampleR = iirLowSampleRE; + break; + } + tripletLA /= 2.0; + tripletLB /= 2.0; + tripletLC /= 2.0; + highSampleL = highSampleL + tripletFactorL; + + tripletRA /= 2.0; + tripletRB /= 2.0; + tripletRC /= 2.0; + highSampleR = highSampleR + tripletFactorR; + + if (flip) + { + iirHighSampleLA = (iirHighSampleLA * (1.0 - iirAmountA)) + (highSampleL * iirAmountA); + highSampleL -= iirHighSampleLA; + iirLowSampleLA = (iirLowSampleLA * (1.0 - iirAmountB)) + (bassSampleL * iirAmountB); + bassSampleL = iirLowSampleLA; + + iirHighSampleRA = (iirHighSampleRA * (1.0 - iirAmountA)) + (highSampleR * iirAmountA); + highSampleR -= iirHighSampleRA; + iirLowSampleRA = (iirLowSampleRA * (1.0 - iirAmountB)) + (bassSampleR * iirAmountB); + bassSampleR = iirLowSampleRA; + } + else + { + iirHighSampleLB = (iirHighSampleLB * (1.0 - iirAmountA)) + (highSampleL * iirAmountA); + highSampleL -= iirHighSampleLB; + iirLowSampleLB = (iirLowSampleLB * (1.0 - iirAmountB)) + (bassSampleL * iirAmountB); + bassSampleL = iirLowSampleLB; + + iirHighSampleRB = (iirHighSampleRB * (1.0 - iirAmountA)) + (highSampleR * iirAmountA); + highSampleR -= iirHighSampleRB; + iirLowSampleRB = (iirLowSampleRB * (1.0 - iirAmountB)) + (bassSampleR * iirAmountB); + bassSampleR = iirLowSampleRB; + } + + iirHighSampleL = (iirHighSampleL * (1.0 - iirAmountA)) + (highSampleL * iirAmountA); + highSampleL -= iirHighSampleL; + iirLowSampleL = (iirLowSampleL * (1.0 - iirAmountB)) + (bassSampleL * iirAmountB); + bassSampleL = iirLowSampleL; + + iirHighSampleR = (iirHighSampleR * (1.0 - iirAmountA)) + (highSampleR * iirAmountA); + highSampleR -= iirHighSampleR; + iirLowSampleR = (iirLowSampleR * (1.0 - iirAmountB)) + (bassSampleR * iirAmountB); + bassSampleR = iirLowSampleR; + + midSampleL = (inputSampleL-bassSampleL)-highSampleL; + midSampleR = (inputSampleR-bassSampleR)-highSampleR; + + //drive section + highSampleL *= (densityA+1.0); + bridgerectifier = fabs(highSampleL)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityA > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (highSampleL > 0) highSampleL = (highSampleL*(1-outA))+(bridgerectifier*outA); + else highSampleL = (highSampleL*(1-outA))-(bridgerectifier*outA); + //blend according to densityA control + + highSampleR *= (densityA+1.0); + bridgerectifier = fabs(highSampleR)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityA > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (highSampleR > 0) highSampleR = (highSampleR*(1-outA))+(bridgerectifier*outA); + else highSampleR = (highSampleR*(1-outA))-(bridgerectifier*outA); + //blend according to densityA control + + midSampleL *= (densityB+1.0); + bridgerectifier = fabs(midSampleL)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityB > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (midSampleL > 0) midSampleL = (midSampleL*(1-outB))+(bridgerectifier*outB); + else midSampleL = (midSampleL*(1-outB))-(bridgerectifier*outB); + //blend according to densityB control + + midSampleR *= (densityB+1.0); + bridgerectifier = fabs(midSampleR)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityB > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (midSampleR > 0) midSampleR = (midSampleR*(1-outB))+(bridgerectifier*outB); + else midSampleR = (midSampleR*(1-outB))-(bridgerectifier*outB); + //blend according to densityB control + + bassSampleL *= (densityC+1.0); + bridgerectifier = fabs(bassSampleL)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityC > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (bassSampleL > 0) bassSampleL = (bassSampleL*(1-outC))+(bridgerectifier*outC); + else bassSampleL = (bassSampleL*(1-outC))-(bridgerectifier*outC); + //blend according to densityC control + + bassSampleR *= (densityC+1.0); + bridgerectifier = fabs(bassSampleR)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityC > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (bassSampleR > 0) bassSampleR = (bassSampleR*(1-outC))+(bridgerectifier*outC); + else bassSampleR = (bassSampleR*(1-outC))-(bridgerectifier*outC); + //blend according to densityC control + + inputSampleL = midSampleL; + inputSampleL += highSampleL; + inputSampleL += bassSampleL; + + inputSampleR = midSampleR; + inputSampleR += highSampleR; + inputSampleR += bassSampleR; + } + //end EQ + + //EQ lowpass is after all processing like the compressor that might produce hash + if (engageLowpass) + { + if (flip) + { + lowpassSampleLAA = (lowpassSampleLAA * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLAA; + lowpassSampleLBA = (lowpassSampleLBA * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLBA; + lowpassSampleLCA = (lowpassSampleLCA * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLCA; + lowpassSampleLDA = (lowpassSampleLDA * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLDA; + lowpassSampleLE = (lowpassSampleLE * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLE; + + lowpassSampleRAA = (lowpassSampleRAA * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRAA; + lowpassSampleRBA = (lowpassSampleRBA * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRBA; + lowpassSampleRCA = (lowpassSampleRCA * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRCA; + lowpassSampleRDA = (lowpassSampleRDA * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRDA; + lowpassSampleRE = (lowpassSampleRE * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRE; + } + else + { + lowpassSampleLAB = (lowpassSampleLAB * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLAB; + lowpassSampleLBB = (lowpassSampleLBB * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLBB; + lowpassSampleLCB = (lowpassSampleLCB * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLCB; + lowpassSampleLDB = (lowpassSampleLDB * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLDB; + lowpassSampleLF = (lowpassSampleLF * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLF; + + lowpassSampleRAB = (lowpassSampleRAB * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRAB; + lowpassSampleRBB = (lowpassSampleRBB * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRBB; + lowpassSampleRCB = (lowpassSampleRCB * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRCB; + lowpassSampleRDB = (lowpassSampleRDB * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRDB; + lowpassSampleRF = (lowpassSampleRF * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRF; + } + lowpassSampleLG = (lowpassSampleLG * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + lowpassSampleRG = (lowpassSampleRG * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + + inputSampleL = (lowpassSampleLG * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleR = (lowpassSampleRG * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + } + + //built in output trim and dry/wet if desired + if (outputgain != 1.0) { + inputSampleL *= outputgain; + inputSampleR *= outputgain; + } + + //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 EQ::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; + double compscale = overallscale; + overallscale = getSampleRate(); + compscale = compscale * overallscale; + //compscale is the one that's 1 or something like 2.2 for 96K rates + double fpTemp; + long double fpOld = 0.618033988749894848204586; //golden ratio! + long double fpNew = 1.0 - fpOld; + + long double inputSampleL; + long double inputSampleR; + + double highSampleL = 0.0; + double midSampleL = 0.0; + double bassSampleL = 0.0; + + double highSampleR = 0.0; + double midSampleR = 0.0; + double bassSampleR = 0.0; + + double densityA = (A*12.0)-6.0; + double densityB = (B*12.0)-6.0; + double densityC = (C*12.0)-6.0; + bool engageEQ = true; + if ( (0.0 == densityA) && (0.0 == densityB) && (0.0 == densityC) ) engageEQ = false; + + densityA = pow(10.0,densityA/20.0)-1.0; + densityB = pow(10.0,densityB/20.0)-1.0; + densityC = pow(10.0,densityC/20.0)-1.0; + //convert to 0 to X multiplier with 1.0 being O db + //minus one gives nearly -1 to ? (should top out at 1) + //calibrate so that X db roughly equals X db with maximum topping out at 1 internally + + double tripletIntensity = -densityA; + + double iirAmountC = (((D*D*15.0)+1.0)*0.0188) + 0.7; + if (iirAmountC > 1.0) iirAmountC = 1.0; + bool engageLowpass = false; + if (((D*D*15.0)+1.0) < 15.99) engageLowpass = true; + + double iirAmountA = (((E*E*15.0)+1.0)*1000)/overallscale; + double iirAmountB = (((F*F*1570.0)+30.0)*10)/overallscale; + double iirAmountD = (((G*G*1570.0)+30.0)*1.0)/overallscale; + bool engageHighpass = false; + if (((G*G*1570.0)+30.0) > 30.01) engageHighpass = true; + //bypass the highpass and lowpass if set to extremes + double bridgerectifier; + double outA = fabs(densityA); + double outB = fabs(densityB); + double outC = fabs(densityC); + //end EQ + double outputgain = pow(10.0,((H*36.0)-18.0)/20.0); + + 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. + } + + last2SampleL = lastSampleL; + lastSampleL = inputSampleL; + + last2SampleR = lastSampleR; + lastSampleR = inputSampleR; + + flip = !flip; + flipthree++; + if (flipthree < 1 || flipthree > 3) flipthree = 1; + //counters + + //begin highpass + if (engageHighpass) + { + if (flip) + { + highpassSampleLAA = (highpassSampleLAA * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLAA; + highpassSampleLBA = (highpassSampleLBA * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLBA; + highpassSampleLCA = (highpassSampleLCA * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLCA; + highpassSampleLDA = (highpassSampleLDA * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLDA; + } + else + { + highpassSampleLAB = (highpassSampleLAB * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLAB; + highpassSampleLBB = (highpassSampleLBB * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLBB; + highpassSampleLCB = (highpassSampleLCB * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLCB; + highpassSampleLDB = (highpassSampleLDB * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLDB; + } + highpassSampleLE = (highpassSampleLE * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLE; + highpassSampleLF = (highpassSampleLF * (1.0 - iirAmountD)) + (inputSampleL * iirAmountD); + inputSampleL -= highpassSampleLF; + + if (flip) + { + highpassSampleRAA = (highpassSampleRAA * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRAA; + highpassSampleRBA = (highpassSampleRBA * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRBA; + highpassSampleRCA = (highpassSampleRCA * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRCA; + highpassSampleRDA = (highpassSampleRDA * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRDA; + } + else + { + highpassSampleRAB = (highpassSampleRAB * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRAB; + highpassSampleRBB = (highpassSampleRBB * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRBB; + highpassSampleRCB = (highpassSampleRCB * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRCB; + highpassSampleRDB = (highpassSampleRDB * (1.0 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRDB; + } + highpassSampleRE = (highpassSampleRE * (1 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRE; + highpassSampleRF = (highpassSampleRF * (1 - iirAmountD)) + (inputSampleR * iirAmountD); + inputSampleR -= highpassSampleRF; + + } + //end highpass + + //begin EQ + if (engageEQ) + { + switch (flipthree) + { + case 1: + tripletFactorL = last2SampleL - inputSampleL; + tripletLA += tripletFactorL; + tripletLC -= tripletFactorL; + tripletFactorL = tripletLA * tripletIntensity; + iirHighSampleLC = (iirHighSampleLC * (1.0 - iirAmountA)) + (inputSampleL * iirAmountA); + highSampleL = inputSampleL - iirHighSampleLC; + iirLowSampleLC = (iirLowSampleLC * (1.0 - iirAmountB)) + (inputSampleL * iirAmountB); + bassSampleL = iirLowSampleLC; + + tripletFactorR = last2SampleR - inputSampleR; + tripletRA += tripletFactorR; + tripletRC -= tripletFactorR; + tripletFactorR = tripletRA * tripletIntensity; + iirHighSampleRC = (iirHighSampleRC * (1.0 - iirAmountA)) + (inputSampleR * iirAmountA); + highSampleR = inputSampleR - iirHighSampleRC; + iirLowSampleRC = (iirLowSampleRC * (1.0 - iirAmountB)) + (inputSampleR * iirAmountB); + bassSampleR = iirLowSampleRC; + break; + case 2: + tripletFactorL = last2SampleL - inputSampleL; + tripletLB += tripletFactorL; + tripletLA -= tripletFactorL; + tripletFactorL = tripletLB * tripletIntensity; + iirHighSampleLD = (iirHighSampleLD * (1.0 - iirAmountA)) + (inputSampleL * iirAmountA); + highSampleL = inputSampleL - iirHighSampleLD; + iirLowSampleLD = (iirLowSampleLD * (1.0 - iirAmountB)) + (inputSampleL * iirAmountB); + bassSampleL = iirLowSampleLD; + + tripletFactorR = last2SampleR - inputSampleR; + tripletRB += tripletFactorR; + tripletRA -= tripletFactorR; + tripletFactorR = tripletRB * tripletIntensity; + iirHighSampleRD = (iirHighSampleRD * (1.0 - iirAmountA)) + (inputSampleR * iirAmountA); + highSampleR = inputSampleR - iirHighSampleRD; + iirLowSampleRD = (iirLowSampleRD * (1.0 - iirAmountB)) + (inputSampleR * iirAmountB); + bassSampleR = iirLowSampleRD; + break; + case 3: + tripletFactorL = last2SampleL - inputSampleL; + tripletLC += tripletFactorL; + tripletLB -= tripletFactorL; + tripletFactorL = tripletLC * tripletIntensity; + iirHighSampleLE = (iirHighSampleLE * (1.0 - iirAmountA)) + (inputSampleL * iirAmountA); + highSampleL = inputSampleL - iirHighSampleLE; + iirLowSampleLE = (iirLowSampleLE * (1.0 - iirAmountB)) + (inputSampleL * iirAmountB); + bassSampleL = iirLowSampleLE; + + tripletFactorR = last2SampleR - inputSampleR; + tripletRC += tripletFactorR; + tripletRB -= tripletFactorR; + tripletFactorR = tripletRC * tripletIntensity; + iirHighSampleRE = (iirHighSampleRE * (1.0 - iirAmountA)) + (inputSampleR * iirAmountA); + highSampleR = inputSampleR - iirHighSampleRE; + iirLowSampleRE = (iirLowSampleRE * (1.0 - iirAmountB)) + (inputSampleR * iirAmountB); + bassSampleR = iirLowSampleRE; + break; + } + tripletLA /= 2.0; + tripletLB /= 2.0; + tripletLC /= 2.0; + highSampleL = highSampleL + tripletFactorL; + + tripletRA /= 2.0; + tripletRB /= 2.0; + tripletRC /= 2.0; + highSampleR = highSampleR + tripletFactorR; + + if (flip) + { + iirHighSampleLA = (iirHighSampleLA * (1.0 - iirAmountA)) + (highSampleL * iirAmountA); + highSampleL -= iirHighSampleLA; + iirLowSampleLA = (iirLowSampleLA * (1.0 - iirAmountB)) + (bassSampleL * iirAmountB); + bassSampleL = iirLowSampleLA; + + iirHighSampleRA = (iirHighSampleRA * (1.0 - iirAmountA)) + (highSampleR * iirAmountA); + highSampleR -= iirHighSampleRA; + iirLowSampleRA = (iirLowSampleRA * (1.0 - iirAmountB)) + (bassSampleR * iirAmountB); + bassSampleR = iirLowSampleRA; + } + else + { + iirHighSampleLB = (iirHighSampleLB * (1.0 - iirAmountA)) + (highSampleL * iirAmountA); + highSampleL -= iirHighSampleLB; + iirLowSampleLB = (iirLowSampleLB * (1.0 - iirAmountB)) + (bassSampleL * iirAmountB); + bassSampleL = iirLowSampleLB; + + iirHighSampleRB = (iirHighSampleRB * (1.0 - iirAmountA)) + (highSampleR * iirAmountA); + highSampleR -= iirHighSampleRB; + iirLowSampleRB = (iirLowSampleRB * (1.0 - iirAmountB)) + (bassSampleR * iirAmountB); + bassSampleR = iirLowSampleRB; + } + + iirHighSampleL = (iirHighSampleL * (1.0 - iirAmountA)) + (highSampleL * iirAmountA); + highSampleL -= iirHighSampleL; + iirLowSampleL = (iirLowSampleL * (1.0 - iirAmountB)) + (bassSampleL * iirAmountB); + bassSampleL = iirLowSampleL; + + iirHighSampleR = (iirHighSampleR * (1.0 - iirAmountA)) + (highSampleR * iirAmountA); + highSampleR -= iirHighSampleR; + iirLowSampleR = (iirLowSampleR * (1.0 - iirAmountB)) + (bassSampleR * iirAmountB); + bassSampleR = iirLowSampleR; + + midSampleL = (inputSampleL-bassSampleL)-highSampleL; + midSampleR = (inputSampleR-bassSampleR)-highSampleR; + + //drive section + highSampleL *= (densityA+1.0); + bridgerectifier = fabs(highSampleL)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityA > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (highSampleL > 0) highSampleL = (highSampleL*(1-outA))+(bridgerectifier*outA); + else highSampleL = (highSampleL*(1-outA))-(bridgerectifier*outA); + //blend according to densityA control + + highSampleR *= (densityA+1.0); + bridgerectifier = fabs(highSampleR)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityA > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (highSampleR > 0) highSampleR = (highSampleR*(1-outA))+(bridgerectifier*outA); + else highSampleR = (highSampleR*(1-outA))-(bridgerectifier*outA); + //blend according to densityA control + + midSampleL *= (densityB+1.0); + bridgerectifier = fabs(midSampleL)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityB > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (midSampleL > 0) midSampleL = (midSampleL*(1-outB))+(bridgerectifier*outB); + else midSampleL = (midSampleL*(1-outB))-(bridgerectifier*outB); + //blend according to densityB control + + midSampleR *= (densityB+1.0); + bridgerectifier = fabs(midSampleR)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityB > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (midSampleR > 0) midSampleR = (midSampleR*(1-outB))+(bridgerectifier*outB); + else midSampleR = (midSampleR*(1-outB))-(bridgerectifier*outB); + //blend according to densityB control + + bassSampleL *= (densityC+1.0); + bridgerectifier = fabs(bassSampleL)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityC > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (bassSampleL > 0) bassSampleL = (bassSampleL*(1-outC))+(bridgerectifier*outC); + else bassSampleL = (bassSampleL*(1-outC))-(bridgerectifier*outC); + //blend according to densityC control + + bassSampleR *= (densityC+1.0); + bridgerectifier = fabs(bassSampleR)*1.57079633; + if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; + //max value for sine function + if (densityC > 0) bridgerectifier = sin(bridgerectifier); + else bridgerectifier = 1-cos(bridgerectifier); + //produce either boosted or starved version + if (bassSampleR > 0) bassSampleR = (bassSampleR*(1-outC))+(bridgerectifier*outC); + else bassSampleR = (bassSampleR*(1-outC))-(bridgerectifier*outC); + //blend according to densityC control + + inputSampleL = midSampleL; + inputSampleL += highSampleL; + inputSampleL += bassSampleL; + + inputSampleR = midSampleR; + inputSampleR += highSampleR; + inputSampleR += bassSampleR; + } + //end EQ + + //EQ lowpass is after all processing like the compressor that might produce hash + if (engageLowpass) + { + if (flip) + { + lowpassSampleLAA = (lowpassSampleLAA * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLAA; + lowpassSampleLBA = (lowpassSampleLBA * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLBA; + lowpassSampleLCA = (lowpassSampleLCA * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLCA; + lowpassSampleLDA = (lowpassSampleLDA * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLDA; + lowpassSampleLE = (lowpassSampleLE * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLE; + + lowpassSampleRAA = (lowpassSampleRAA * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRAA; + lowpassSampleRBA = (lowpassSampleRBA * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRBA; + lowpassSampleRCA = (lowpassSampleRCA * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRCA; + lowpassSampleRDA = (lowpassSampleRDA * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRDA; + lowpassSampleRE = (lowpassSampleRE * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRE; + } + else + { + lowpassSampleLAB = (lowpassSampleLAB * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLAB; + lowpassSampleLBB = (lowpassSampleLBB * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLBB; + lowpassSampleLCB = (lowpassSampleLCB * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLCB; + lowpassSampleLDB = (lowpassSampleLDB * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLDB; + lowpassSampleLF = (lowpassSampleLF * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleL = lowpassSampleLF; + + lowpassSampleRAB = (lowpassSampleRAB * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRAB; + lowpassSampleRBB = (lowpassSampleRBB * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRBB; + lowpassSampleRCB = (lowpassSampleRCB * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRCB; + lowpassSampleRDB = (lowpassSampleRDB * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRDB; + lowpassSampleRF = (lowpassSampleRF * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + inputSampleR = lowpassSampleRF; + } + lowpassSampleLG = (lowpassSampleLG * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + lowpassSampleRG = (lowpassSampleRG * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + + inputSampleL = (lowpassSampleLG * (1.0 - iirAmountC)) + (inputSampleL * iirAmountC); + inputSampleR = (lowpassSampleRG * (1.0 - iirAmountC)) + (inputSampleR * iirAmountC); + } + + //built in output trim and dry/wet if desired + if (outputgain != 1.0) { + inputSampleL *= outputgain; + inputSampleR *= outputgain; + } + + //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 |