From c653c8b38fdc79f61ee191052901ac2012d476b4 Mon Sep 17 00:00:00 2001 From: Chris Johnson Date: Sun, 5 Jul 2020 22:01:06 -0400 Subject: DeRez Dither Updates (Beam, Dark, NJAD) --- plugins/LinuxVST/src/Beam/Beam.cpp | 142 ++++++ plugins/LinuxVST/src/Beam/Beam.h | 67 +++ plugins/LinuxVST/src/Beam/BeamProc.cpp | 266 ++++++++++ plugins/LinuxVST/src/Dark/Dark.cpp | 2 +- plugins/LinuxVST/src/Dark/DarkProc.cpp | 20 +- .../.vs/Console4Channel64/v14/.suo | Bin 32768 -> 0 bytes .../NotJustAnotherDither/.vs/VSTProject/v14/.suo | Bin 23040 -> 0 bytes .../NotJustAnotherDither/NotJustAnotherDither.cpp | 56 ++- .../NotJustAnotherDither/NotJustAnotherDither.h | 10 +- .../NotJustAnotherDitherProc.cpp | 556 +++++++-------------- plugins/MacAU/Beam/Beam.cpp | 6 +- .../Beam/Beam.xcodeproj/christopherjohnson.pbxuser | 58 +-- .../christopherjohnson.perspectivev3 | 37 +- plugins/MacAU/Dark/Dark.cpp | 9 +- .../Dark/Dark.xcodeproj/christopherjohnson.pbxuser | 120 +++-- .../christopherjohnson.perspectivev3 | 85 +++- .../NotJustAnotherDither/NotJustAnotherDither.cpp | 213 ++++---- .../NotJustAnotherDither/NotJustAnotherDither.h | 15 +- .../christopherjohnson.pbxuser | 65 ++- .../christopherjohnson.perspectivev3 | 50 +- .../Beam/Beam.xcodeproj/christopherjohnson.pbxuser | 58 +-- .../christopherjohnson.perspectivev3 | 33 +- plugins/MacVST/Beam/source/BeamProc.cpp | 16 +- .../Dark/Dark.xcodeproj/christopherjohnson.pbxuser | 80 +-- .../christopherjohnson.perspectivev3 | 38 +- plugins/MacVST/Dark/source/Dark.cpp | 2 +- plugins/MacVST/Dark/source/DarkProc.cpp | 20 +- .../christopherjohnson.pbxuser | 71 ++- .../christopherjohnson.perspectivev3 | 37 +- .../source/NotJustAnotherDither.cpp | 56 ++- .../source/NotJustAnotherDither.h | 10 +- .../source/NotJustAnotherDitherProc.cpp | 556 +++++++-------------- plugins/WinVST/Beam/.vs/VSTProject/v14/.suo | Bin 23552 -> 22528 bytes plugins/WinVST/Beam/BeamProc.cpp | 16 +- plugins/WinVST/Dark/.vs/VSTProject/v14/.suo | Bin 22528 -> 23040 bytes plugins/WinVST/Dark/Dark.cpp | 2 +- plugins/WinVST/Dark/DarkProc.cpp | 20 +- .../NotJustAnotherDither/.vs/VSTProject/v14/.suo | Bin 23040 -> 23040 bytes .../NotJustAnotherDither/NotJustAnotherDither.cpp | 56 ++- .../NotJustAnotherDither/NotJustAnotherDither.h | 10 +- .../NotJustAnotherDitherProc.cpp | 556 +++++++-------------- 41 files changed, 1797 insertions(+), 1617 deletions(-) create mode 100755 plugins/LinuxVST/src/Beam/Beam.cpp create mode 100755 plugins/LinuxVST/src/Beam/Beam.h create mode 100755 plugins/LinuxVST/src/Beam/BeamProc.cpp delete mode 100755 plugins/LinuxVST/src/NotJustAnotherDither/.vs/Console4Channel64/v14/.suo delete mode 100755 plugins/LinuxVST/src/NotJustAnotherDither/.vs/VSTProject/v14/.suo diff --git a/plugins/LinuxVST/src/Beam/Beam.cpp b/plugins/LinuxVST/src/Beam/Beam.cpp new file mode 100755 index 0000000..183b5e5 --- /dev/null +++ b/plugins/LinuxVST/src/Beam/Beam.cpp @@ -0,0 +1,142 @@ +/* ======================================== + * Beam - Beam.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __Beam_H +#include "Beam.h" +#endif + +AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new Beam(audioMaster);} + +Beam::Beam(audioMasterCallback audioMaster) : + AudioEffectX(audioMaster, kNumPrograms, kNumParameters) +{ + A = 1.0; + B = 0.5; + C = 0.0; + for(int count = 0; count < 99; count++) { + lastSampleL[count] = 0; + lastSampleR[count] = 0; + } + fpd = 17; + //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 +} + +Beam::~Beam() {} +VstInt32 Beam::getVendorVersion () {return 1000;} +void Beam::setProgramName(char *name) {vst_strncpy (_programName, name, kVstMaxProgNameLen);} +void Beam::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 Beam::getChunk (void** data, bool isPreset) +{ + float *chunkData = (float *)calloc(kNumParameters, sizeof(float)); + chunkData[0] = A; + chunkData[1] = B; + chunkData[2] = C; + /* 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 Beam::setChunk (void* data, VstInt32 byteSize, bool isPreset) +{ + float *chunkData = (float *)data; + A = pinParameter(chunkData[0]); + B = pinParameter(chunkData[1]); + C = pinParameter(chunkData[2]); + /* 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 Beam::setParameter(VstInt32 index, float value) { + switch (index) { + case kParamA: A = value; break; + case kParamB: B = value; break; + case kParamC: C = value; break; + default: throw; // unknown parameter, shouldn't happen! + } +} + +float Beam::getParameter(VstInt32 index) { + switch (index) { + case kParamA: return A; break; + case kParamB: return B; break; + case kParamC: return C; 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 Beam::getParameterName(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "Quant", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "Focus", kVstMaxParamStrLen); break; + case kParamC: vst_strncpy (text, "DeRez", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this is our labels for displaying in the VST host +} + +void Beam::getParameterDisplay(VstInt32 index, char *text) { + switch (index) { + case kParamA: switch((VstInt32)( A * 1.999 )) //0 to almost edge of # of params + { case 0: vst_strncpy (text, "CD 16", kVstMaxParamStrLen); break; + case 1: vst_strncpy (text, "HD 24", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } break; //completed consoletype 'popup' parameter, exit + case kParamB: float2string (B, text, kVstMaxParamStrLen); break; + case kParamC: float2string (C, text, kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this displays the values and handles 'popups' where it's discrete choices +} + +void Beam::getParameterLabel(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "", kVstMaxParamStrLen); break; + case kParamC: vst_strncpy (text, "", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } +} + +VstInt32 Beam::canDo(char *text) +{ return (_canDo.find(text) == _canDo.end()) ? -1: 1; } // 1 = yes, -1 = no, 0 = don't know + +bool Beam::getEffectName(char* name) { + vst_strncpy(name, "Beam", kVstMaxProductStrLen); return true; +} + +VstPlugCategory Beam::getPlugCategory() {return kPlugCategEffect;} + +bool Beam::getProductString(char* text) { + vst_strncpy (text, "airwindows Beam", kVstMaxProductStrLen); return true; +} + +bool Beam::getVendorString(char* text) { + vst_strncpy (text, "airwindows", kVstMaxVendorStrLen); return true; +} diff --git a/plugins/LinuxVST/src/Beam/Beam.h b/plugins/LinuxVST/src/Beam/Beam.h new file mode 100755 index 0000000..30e1ccd --- /dev/null +++ b/plugins/LinuxVST/src/Beam/Beam.h @@ -0,0 +1,67 @@ +/* ======================================== + * Beam - Beam.h + * Created 8/12/11 by SPIAdmin + * Copyright (c) 2011 __MyCompanyName__, All rights reserved + * ======================================== */ + +#ifndef __Beam_H +#define __Beam_H + +#ifndef __audioeffect__ +#include "audioeffectx.h" +#endif + +#include +#include +#include + +enum { + kParamA = 0, + kParamB = 1, + kParamC = 2, + kNumParameters = 3 +}; // + +const int kNumPrograms = 0; +const int kNumInputs = 2; +const int kNumOutputs = 2; +const unsigned long kUniqueId = 'beam'; //Change this to what the AU identity is! + +class Beam : + public AudioEffectX +{ +public: + Beam(audioMasterCallback audioMaster); + ~Beam(); + 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; + + float lastSampleL[100]; + float lastSampleR[100]; + uint32_t fpd; + //default stuff + + float A; + float B; + float C; +}; + +#endif diff --git a/plugins/LinuxVST/src/Beam/BeamProc.cpp b/plugins/LinuxVST/src/Beam/BeamProc.cpp new file mode 100755 index 0000000..5871eb5 --- /dev/null +++ b/plugins/LinuxVST/src/Beam/BeamProc.cpp @@ -0,0 +1,266 @@ +/* ======================================== + * Beam - Beam.h + * Copyright (c) 2016 airwindows, All rights reserved + * ======================================== */ + +#ifndef __Beam_H +#include "Beam.h" +#endif + +void Beam::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) +{ + float* in1 = inputs[0]; + float* in2 = inputs[1]; + float* out1 = outputs[0]; + float* out2 = outputs[1]; + + int processing = (VstInt32)( A * 1.999 ); + float sonority = B * 1.618033988749894848204586; + double overallscale = 1.0; + overallscale /= 44100.0; + overallscale *= getSampleRate(); + int depth = (int)(17.0*overallscale); + if (depth < 3) depth = 3; + if (depth > 98) depth = 98; + bool highres = false; + if (processing == 1) highres = true; + float scaleFactor; + if (highres) scaleFactor = 8388608.0; + else scaleFactor = 32768.0; + float derez = C; + if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; + + while (--sampleFrames >= 0) + { + long double inputSampleL = *in1; + long double inputSampleR = *in2; + if (fabs(inputSampleL)<1.18e-37) inputSampleL = fpd * 1.18e-37; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + if (fabs(inputSampleR)<1.18e-37) inputSampleR = fpd * 1.18e-37; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + + inputSampleL *= scaleFactor; + inputSampleR *= scaleFactor; + //0-1 is now one bit, now we dither + + //We are doing it first Left, then Right, because the loops may run faster if + //they aren't too jammed full of variables. This means re-running code. + + //begin left + int quantA = floor(inputSampleL); + int quantB = floor(inputSampleL+1.0); + //to do this style of dither, we quantize in either direction and then + //do a reconstruction of what the result will be for each choice. + //We then evaluate which one we like, and keep a history of what we previously had + + float expectedSlewA = 0; + for(int x = 0; x < depth; x++) { + expectedSlewA += (lastSampleL[x+1] - lastSampleL[x]); + } + float expectedSlewB = expectedSlewA; + expectedSlewA += (lastSampleL[0] - quantA); + expectedSlewB += (lastSampleL[0] - quantB); + //now we have a collection of all slews, averaged and left at total scale + + float clamp = sonority; + if (fabs(inputSampleL) < sonority) clamp = fabs(inputSampleL); + + float testA = fabs(fabs(expectedSlewA)-clamp); + float testB = fabs(fabs(expectedSlewB)-clamp); + //doing this means the result will be lowest when it's reaching the target slope across + //the desired time range, either positively or negatively. Should produce the same target + //at whatever sample rate, as high rate stuff produces smaller increments. + + if (testA < testB) inputSampleL = quantA; + else inputSampleL = quantB; + //select whichever one departs LEAST from the vector of averaged + //reconstructed previous final samples. This will force a kind of dithering + //as it'll make the output end up as smooth as possible + + for(int x = depth; x >=0; x--) { + lastSampleL[x+1] = lastSampleL[x]; + } + lastSampleL[0] = inputSampleL; + //end left + + //begin right + quantA = floor(inputSampleR); + quantB = floor(inputSampleR+1.0); + //to do this style of dither, we quantize in either direction and then + //do a reconstruction of what the result will be for each choice. + //We then evaluate which one we like, and keep a history of what we previously had + + expectedSlewA = 0; + for(int x = 0; x < depth; x++) { + expectedSlewA += (lastSampleR[x+1] - lastSampleR[x]); + } + expectedSlewB = expectedSlewA; + expectedSlewA += (lastSampleR[0] - quantA); + expectedSlewB += (lastSampleR[0] - quantB); + //now we have a collection of all slews, averaged and left at total scale + + clamp = sonority; + if (fabs(inputSampleR) < sonority) clamp = fabs(inputSampleR); + + testA = fabs(fabs(expectedSlewA)-clamp); + testB = fabs(fabs(expectedSlewB)-clamp); + //doing this means the result will be lowest when it's reaching the target slope across + //the desired time range, either positively or negatively. Should produce the same target + //at whatever sample rate, as high rate stuff produces smaller increments. + + if (testA < testB) inputSampleR = quantA; + else inputSampleR = quantB; + //select whichever one departs LEAST from the vector of averaged + //reconstructed previous final samples. This will force a kind of dithering + //as it'll make the output end up as smooth as possible + + for(int x = depth; x >=0; x--) { + lastSampleR[x+1] = lastSampleR[x]; + } + lastSampleR[0] = inputSampleR; + //end right + + inputSampleL /= outScale; + inputSampleR /= outScale; + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +} + +void Beam::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) +{ + double* in1 = inputs[0]; + double* in2 = inputs[1]; + double* out1 = outputs[0]; + double* out2 = outputs[1]; + + int processing = (VstInt32)( A * 1.999 ); + float sonority = B * 1.618033988749894848204586; + double overallscale = 1.0; + overallscale /= 44100.0; + overallscale *= getSampleRate(); + int depth = (int)(17.0*overallscale); + if (depth < 3) depth = 3; + if (depth > 98) depth = 98; + bool highres = false; + if (processing == 1) highres = true; + float scaleFactor; + if (highres) scaleFactor = 8388608.0; + else scaleFactor = 32768.0; + float derez = C; + if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; + + while (--sampleFrames >= 0) + { + long double inputSampleL = *in1; + long double inputSampleR = *in2; + if (fabs(inputSampleL)<1.18e-43) inputSampleL = fpd * 1.18e-43; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + if (fabs(inputSampleR)<1.18e-43) inputSampleR = fpd * 1.18e-43; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + + inputSampleL *= scaleFactor; + inputSampleR *= scaleFactor; + //0-1 is now one bit, now we dither + + //We are doing it first Left, then Right, because the loops may run faster if + //they aren't too jammed full of variables. This means re-running code. + + //begin left + int quantA = floor(inputSampleL); + int quantB = floor(inputSampleL+1.0); + //to do this style of dither, we quantize in either direction and then + //do a reconstruction of what the result will be for each choice. + //We then evaluate which one we like, and keep a history of what we previously had + + float expectedSlewA = 0; + for(int x = 0; x < depth; x++) { + expectedSlewA += (lastSampleL[x+1] - lastSampleL[x]); + } + float expectedSlewB = expectedSlewA; + expectedSlewA += (lastSampleL[0] - quantA); + expectedSlewB += (lastSampleL[0] - quantB); + //now we have a collection of all slews, averaged and left at total scale + + float clamp = sonority; + if (fabs(inputSampleL) < sonority) clamp = fabs(inputSampleL); + + float testA = fabs(fabs(expectedSlewA)-clamp); + float testB = fabs(fabs(expectedSlewB)-clamp); + //doing this means the result will be lowest when it's reaching the target slope across + //the desired time range, either positively or negatively. Should produce the same target + //at whatever sample rate, as high rate stuff produces smaller increments. + + if (testA < testB) inputSampleL = quantA; + else inputSampleL = quantB; + //select whichever one departs LEAST from the vector of averaged + //reconstructed previous final samples. This will force a kind of dithering + //as it'll make the output end up as smooth as possible + + for(int x = depth; x >=0; x--) { + lastSampleL[x+1] = lastSampleL[x]; + } + lastSampleL[0] = inputSampleL; + //end left + + //begin right + quantA = floor(inputSampleR); + quantB = floor(inputSampleR+1.0); + //to do this style of dither, we quantize in either direction and then + //do a reconstruction of what the result will be for each choice. + //We then evaluate which one we like, and keep a history of what we previously had + + expectedSlewA = 0; + for(int x = 0; x < depth; x++) { + expectedSlewA += (lastSampleR[x+1] - lastSampleR[x]); + } + expectedSlewB = expectedSlewA; + expectedSlewA += (lastSampleR[0] - quantA); + expectedSlewB += (lastSampleR[0] - quantB); + //now we have a collection of all slews, averaged and left at total scale + + clamp = sonority; + if (fabs(inputSampleR) < sonority) clamp = fabs(inputSampleR); + + testA = fabs(fabs(expectedSlewA)-clamp); + testB = fabs(fabs(expectedSlewB)-clamp); + //doing this means the result will be lowest when it's reaching the target slope across + //the desired time range, either positively or negatively. Should produce the same target + //at whatever sample rate, as high rate stuff produces smaller increments. + + if (testA < testB) inputSampleR = quantA; + else inputSampleR = quantB; + //select whichever one departs LEAST from the vector of averaged + //reconstructed previous final samples. This will force a kind of dithering + //as it'll make the output end up as smooth as possible + + for(int x = depth; x >=0; x--) { + lastSampleR[x+1] = lastSampleR[x]; + } + lastSampleR[0] = inputSampleR; + //end right + + inputSampleL /= outScale; + inputSampleR /= outScale; + + *out1 = inputSampleL; + *out2 = inputSampleR; + + *in1++; + *in2++; + *out1++; + *out2++; + } +} diff --git a/plugins/LinuxVST/src/Dark/Dark.cpp b/plugins/LinuxVST/src/Dark/Dark.cpp index bae0428..f652aa4 100755 --- a/plugins/LinuxVST/src/Dark/Dark.cpp +++ b/plugins/LinuxVST/src/Dark/Dark.cpp @@ -14,11 +14,11 @@ Dark::Dark(audioMasterCallback audioMaster) : { A = 1.0; B = 0.0; + fpd = 17; for(int count = 0; count < 99; count++) { lastSampleL[count] = 0; lastSampleR[count] = 0; } - fpd = 17; //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. diff --git a/plugins/LinuxVST/src/Dark/DarkProc.cpp b/plugins/LinuxVST/src/Dark/DarkProc.cpp index 2aa85c4..955a53f 100755 --- a/plugins/LinuxVST/src/Dark/DarkProc.cpp +++ b/plugins/LinuxVST/src/Dark/DarkProc.cpp @@ -13,13 +13,14 @@ void Dark::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram float* in2 = inputs[1]; float* out1 = outputs[0]; float* out2 = outputs[1]; - int processing = (VstInt32)( A * 1.999 ); double overallscale = 1.0; overallscale /= 44100.0; overallscale *= getSampleRate(); int depth = (int)(17.0*overallscale); if (depth < 3) depth = 3; if (depth > 98) depth = 98; + + int processing = (VstInt32)( A * 1.999 ); bool highres = false; if (processing == 1) highres = true; float scaleFactor; @@ -28,6 +29,8 @@ void Dark::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram float derez = B; if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; while (--sampleFrames >= 0) { @@ -105,8 +108,8 @@ void Dark::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram lastSampleR[0] = inputSampleR; //end right - inputSampleL /= scaleFactor; - inputSampleR /= scaleFactor; + inputSampleL /= outScale; + inputSampleR /= outScale; *out1 = inputSampleL; *out2 = inputSampleR; @@ -125,13 +128,14 @@ void Dark::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa double* out1 = outputs[0]; double* out2 = outputs[1]; - int processing = (VstInt32)( A * 1.999 ); double overallscale = 1.0; overallscale /= 44100.0; overallscale *= getSampleRate(); int depth = (int)(17.0*overallscale); if (depth < 3) depth = 3; if (depth > 98) depth = 98; + + int processing = (VstInt32)( A * 1.999 ); bool highres = false; if (processing == 1) highres = true; float scaleFactor; @@ -139,7 +143,9 @@ void Dark::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa else scaleFactor = 32768.0; float derez = B; if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); - if (scaleFactor < 1.0) scaleFactor = 1.0; + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; while (--sampleFrames >= 0) { @@ -217,8 +223,8 @@ void Dark::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa lastSampleR[0] = inputSampleR; //end right - inputSampleL /= scaleFactor; - inputSampleR /= scaleFactor; + inputSampleL /= outScale; + inputSampleR /= outScale; *out1 = inputSampleL; *out2 = inputSampleR; diff --git a/plugins/LinuxVST/src/NotJustAnotherDither/.vs/Console4Channel64/v14/.suo b/plugins/LinuxVST/src/NotJustAnotherDither/.vs/Console4Channel64/v14/.suo deleted file mode 100755 index 777b846..0000000 Binary files a/plugins/LinuxVST/src/NotJustAnotherDither/.vs/Console4Channel64/v14/.suo and /dev/null differ diff --git a/plugins/LinuxVST/src/NotJustAnotherDither/.vs/VSTProject/v14/.suo b/plugins/LinuxVST/src/NotJustAnotherDither/.vs/VSTProject/v14/.suo deleted file mode 100755 index 0b83621..0000000 Binary files a/plugins/LinuxVST/src/NotJustAnotherDither/.vs/VSTProject/v14/.suo and /dev/null differ diff --git a/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDither.cpp b/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDither.cpp index 22a3cc7..7727b50 100755 --- a/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDither.cpp +++ b/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDither.cpp @@ -12,6 +12,9 @@ AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new N NotJustAnotherDither::NotJustAnotherDither(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, kNumPrograms, kNumParameters) { + A = 1.0; + B = 0.0; + fpd = 17; bynL[0] = 1000; bynL[1] = 301; bynL[2] = 176; @@ -58,31 +61,80 @@ void NotJustAnotherDither::getProgramName(char *name) {vst_strncpy (name, _progr //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 NotJustAnotherDither::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 NotJustAnotherDither::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 NotJustAnotherDither::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 NotJustAnotherDither::getParameter(VstInt32 index) { - return 0.0; //we only need to update the relevant name, this is simple to manage + 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 NotJustAnotherDither::getParameterName(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "Quant", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "DeRez", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this is our labels for displaying in the VST host } void NotJustAnotherDither::getParameterDisplay(VstInt32 index, char *text) { + switch (index) { + case kParamA: switch((VstInt32)( A * 1.999 )) //0 to almost edge of # of params + { case 0: vst_strncpy (text, "CD 16", kVstMaxParamStrLen); break; + case 1: vst_strncpy (text, "HD 24", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } break; //completed consoletype 'popup' parameter, exit + case kParamB: float2string (B, text, kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this displays the values and handles 'popups' where it's discrete choices } void NotJustAnotherDither::getParameterLabel(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } } VstInt32 NotJustAnotherDither::canDo(char *text) diff --git a/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDither.h b/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDither.h index 37abf4c..5ca0c0a 100755 --- a/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDither.h +++ b/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDither.h @@ -16,7 +16,9 @@ #include enum { - kNumParameters = 0 + kParamA = 0, + kParamB = 1, + kNumParameters = 2 }; // const int kNumPrograms = 0; @@ -55,7 +57,11 @@ private: double bynR[13]; long double noiseShapingL; long double noiseShapingR; - + uint32_t fpd; + //default stuff + + float A; + float B; }; #endif diff --git a/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDitherProc.cpp b/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDitherProc.cpp index cbc6cc3..1a80711 100755 --- a/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDitherProc.cpp +++ b/plugins/LinuxVST/src/NotJustAnotherDither/NotJustAnotherDitherProc.cpp @@ -14,237 +14,143 @@ void NotJustAnotherDither::processReplacing(float **inputs, float **outputs, Vst float* out1 = outputs[0]; float* out2 = outputs[1]; - long double inputSampleL; - long double inputSampleR; - - double benfordize; - int hotbinA; - int hotbinB; - double totalA; - double totalB; - float drySampleL; - float drySampleR; + int processing = (VstInt32)( A * 1.999 ); + bool highres = false; + if (processing == 1) highres = true; + float scaleFactor; + if (highres) scaleFactor = 8388608.0; + else scaleFactor = 32768.0; + float derez = B; + if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.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. - } - drySampleL = inputSampleL; - drySampleR = inputSampleR; + long double inputSampleL = *in1; + long double inputSampleR = *in2; + if (fabs(inputSampleL)<1.18e-37) inputSampleL = fpd * 1.18e-37; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + if (fabs(inputSampleR)<1.18e-37) inputSampleR = fpd * 1.18e-37; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + + inputSampleL *= scaleFactor; + inputSampleR *= scaleFactor; + //0-1 is now one bit, now we dither + //begin Not Just Another Dither + bool cutbinsL; cutbinsL = false; + bool cutbinsR; cutbinsR = false; + long double drySampleL; drySampleL = inputSampleL; + long double drySampleR; drySampleR = inputSampleR; inputSampleL -= noiseShapingL; inputSampleR -= noiseShapingR; - - inputSampleL *= 8388608.0; - inputSampleR *= 8388608.0; - //0-1 is now one bit, now we dither - - //begin L - 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;} - hotbinA = floor(benfordize); + + //NJAD L + long double benfordize; benfordize = floor(inputSampleL); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinA; hotbinA = floor(benfordize); //hotbin becomes the Benford bin value for this number floored - totalA = 0; + long double totalA; 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; if (bynL[hotbinA] > 982) cutbinsL = true; + 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;} + } 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;} - hotbinB = floor(benfordize); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinB; hotbinB = floor(benfordize); //hotbin becomes the Benford bin value for this number ceiled - totalB = 0; + long double totalB; 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; if (bynL[hotbinB] > 982) cutbinsL = true; + 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;} + } 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); - } + long double outputSample; + if (totalA < totalB) {bynL[hotbinA] += 1; outputSample = floor(inputSampleL);} + else {bynL[hotbinB] += 1; outputSample = floor(inputSampleL+1);} //assign the relevant one to the delay line //and floor/ceil signal accordingly + if (cutbinsL) { + bynL[1] *= 0.99; bynL[2] *= 0.99; bynL[3] *= 0.99; bynL[4] *= 0.99; bynL[5] *= 0.99; + bynL[6] *= 0.99; bynL[7] *= 0.99; bynL[8] *= 0.99; bynL[9] *= 0.99; bynL[10] *= 0.99; + } + noiseShapingL += outputSample - drySampleL; + if (noiseShapingL > fabs(inputSampleL)) noiseShapingL = fabs(inputSampleL); + if (noiseShapingL < -fabs(inputSampleL)) noiseShapingL = -fabs(inputSampleL); + //finished NJAD L - 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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 + //NJAD 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinA] > 982) cutbinsR = true; + 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;} + } 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinB] > 982) cutbinsR = true; + 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;} + } 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); - } + if (totalA < totalB) {bynR[hotbinA] += 1; outputSample = floor(inputSampleR);} + else {bynR[hotbinB] += 1; outputSample = floor(inputSampleR+1);} //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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 (cutbinsR) { + bynR[1] *= 0.99; bynR[2] *= 0.99; bynR[3] *= 0.99; bynR[4] *= 0.99; bynR[5] *= 0.99; + bynR[6] *= 0.99; bynR[7] *= 0.99; bynR[8] *= 0.99; bynR[9] *= 0.99; bynR[10] *= 0.99; + } + noiseShapingR += outputSample - drySampleR; + if (noiseShapingR > fabs(inputSampleR)) noiseShapingR = fabs(inputSampleR); + if (noiseShapingR < -fabs(inputSampleR)) noiseShapingR = -fabs(inputSampleR); + //finished NJAD R + - inputSampleL /= 8388608.0; - inputSampleR /= 8388608.0; - - noiseShapingL += inputSampleL - drySampleL; - noiseShapingR += inputSampleR - drySampleR; + inputSampleL /= outScale; + inputSampleR /= outScale; + if (inputSampleL > 1.0) inputSampleL = 1.0; + if (inputSampleL < -1.0) inputSampleL = -1.0; + if (inputSampleR > 1.0) inputSampleR = 1.0; + if (inputSampleR < -1.0) inputSampleR = -1.0; + *out1 = inputSampleL; *out2 = inputSampleR; @@ -262,237 +168,143 @@ void NotJustAnotherDither::processDoubleReplacing(double **inputs, double **outp double* out1 = outputs[0]; double* out2 = outputs[1]; - - long double inputSampleL; - long double inputSampleR; - - double benfordize; - int hotbinA; - int hotbinB; - double totalA; - double totalB; - double drySampleL; - double drySampleR; + int processing = (VstInt32)( A * 1.999 ); + bool highres = false; + if (processing == 1) highres = true; + float scaleFactor; + if (highres) scaleFactor = 8388608.0; + else scaleFactor = 32768.0; + float derez = B; + if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.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. - } - drySampleL = inputSampleL; - drySampleR = inputSampleR; - - inputSampleL -= noiseShapingL; - inputSampleR -= noiseShapingR; + long double inputSampleL = *in1; + long double inputSampleR = *in2; + if (fabs(inputSampleL)<1.18e-43) inputSampleL = fpd * 1.18e-43; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + if (fabs(inputSampleR)<1.18e-43) inputSampleR = fpd * 1.18e-43; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; - inputSampleL *= 8388608.0; - inputSampleR *= 8388608.0; + inputSampleL *= scaleFactor; + inputSampleR *= scaleFactor; //0-1 is now one bit, now we dither - //begin L - 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;} - hotbinA = floor(benfordize); + //begin Not Just Another Dither + bool cutbinsL; cutbinsL = false; + bool cutbinsR; cutbinsR = false; + long double drySampleL; drySampleL = inputSampleL; + long double drySampleR; drySampleR = inputSampleR; + inputSampleL -= noiseShapingL; + inputSampleR -= noiseShapingR; + + //NJAD L + long double benfordize; benfordize = floor(inputSampleL); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinA; hotbinA = floor(benfordize); //hotbin becomes the Benford bin value for this number floored - totalA = 0; + long double totalA; 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; if (bynL[hotbinA] > 982) cutbinsL = true; + 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;} + } 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;} - hotbinB = floor(benfordize); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinB; hotbinB = floor(benfordize); //hotbin becomes the Benford bin value for this number ceiled - totalB = 0; + long double totalB; 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; if (bynL[hotbinB] > 982) cutbinsL = true; + 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;} + } 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); - } + long double outputSampleL; + if (totalA < totalB) {bynL[hotbinA] += 1; outputSampleL = floor(inputSampleL);} + else {bynL[hotbinB] += 1; outputSampleL = floor(inputSampleL+1);} //assign the relevant one to the delay line //and floor/ceil signal accordingly + if (cutbinsL) { + bynL[1] *= 0.99; bynL[2] *= 0.99; bynL[3] *= 0.99; bynL[4] *= 0.99; bynL[5] *= 0.99; + bynL[6] *= 0.99; bynL[7] *= 0.99; bynL[8] *= 0.99; bynL[9] *= 0.99; bynL[10] *= 0.99; + } + noiseShapingL += outputSampleL - drySampleL; + if (noiseShapingL > fabs(inputSampleL)) noiseShapingL = fabs(inputSampleL); + if (noiseShapingL < -fabs(inputSampleL)) noiseShapingL = -fabs(inputSampleL); + //finished NJAD L - 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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 + //NJAD 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinA] > 982) cutbinsR = true; + 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;} + } 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinB] > 982) cutbinsR = true; + 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;} + } 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); - } + long double outputSampleR; + if (totalA < totalB) {bynR[hotbinA] += 1; outputSampleR = floor(inputSampleR);} + else {bynR[hotbinB] += 1; outputSampleR = floor(inputSampleR+1);} //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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 (cutbinsR) { + bynR[1] *= 0.99; bynR[2] *= 0.99; bynR[3] *= 0.99; bynR[4] *= 0.99; bynR[5] *= 0.99; + bynR[6] *= 0.99; bynR[7] *= 0.99; bynR[8] *= 0.99; bynR[9] *= 0.99; bynR[10] *= 0.99; + } + noiseShapingR += outputSampleR - drySampleR; + if (noiseShapingR > fabs(inputSampleR)) noiseShapingR = fabs(inputSampleR); + if (noiseShapingR < -fabs(inputSampleR)) noiseShapingR = -fabs(inputSampleR); + //finished NJAD R + - inputSampleL /= 8388608.0; - inputSampleR /= 8388608.0; + inputSampleL = outputSampleL / outScale; + inputSampleR = outputSampleR / outScale; - noiseShapingL += inputSampleL - drySampleL; - noiseShapingR += inputSampleR - drySampleR; + if (inputSampleL > 1.0) inputSampleL = 1.0; + if (inputSampleL < -1.0) inputSampleL = -1.0; + if (inputSampleR > 1.0) inputSampleR = 1.0; + if (inputSampleR < -1.0) inputSampleR = -1.0; *out1 = inputSampleL; *out2 = inputSampleR; diff --git a/plugins/MacAU/Beam/Beam.cpp b/plugins/MacAU/Beam/Beam.cpp index b8079d9..25737f8 100755 --- a/plugins/MacAU/Beam/Beam.cpp +++ b/plugins/MacAU/Beam/Beam.cpp @@ -219,7 +219,9 @@ void Beam::BeamKernel::Process( const Float32 *inSourceP, else scaleFactor = 32768.0; Float32 derez = GetParameter( kParam_Three ); if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); - if (scaleFactor < 1.0) scaleFactor = 1.0; + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + Float32 outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; while (nSampleFrames-- > 0) { Float32 inputSample = *sourceP; @@ -260,7 +262,7 @@ void Beam::BeamKernel::Process( const Float32 *inSourceP, } lastSample[0] = inputSample; - inputSample /= scaleFactor; + inputSample /= outScale; *destP = inputSample; diff --git a/plugins/MacAU/Beam/Beam.xcodeproj/christopherjohnson.pbxuser b/plugins/MacAU/Beam/Beam.xcodeproj/christopherjohnson.pbxuser index 6090610..e625ba4 100755 --- a/plugins/MacAU/Beam/Beam.xcodeproj/christopherjohnson.pbxuser +++ b/plugins/MacAU/Beam/Beam.xcodeproj/christopherjohnson.pbxuser @@ -49,13 +49,13 @@ PBXFileDataSource_Warnings_ColumnID, ); }; - PBXPerProjectTemplateStateSaveDate = 613785694; - PBXWorkspaceStateSaveDate = 613785694; + PBXPerProjectTemplateStateSaveDate = 615683094; + PBXWorkspaceStateSaveDate = 615683094; }; perUserProjectItems = { + 8BB9A45624B2942900CD76A8 /* PBXTextBookmark */ = 8BB9A45624B2942900CD76A8 /* PBXTextBookmark */; + 8BB9A45B24B2943A00CD76A8 /* PBXTextBookmark */ = 8BB9A45B24B2943A00CD76A8 /* PBXTextBookmark */; 8BD150E124956DDF00B025B9 /* PBXTextBookmark */ = 8BD150E124956DDF00B025B9 /* PBXTextBookmark */; - 8BD150E324956DDF00B025B9 /* PBXTextBookmark */ = 8BD150E324956DDF00B025B9 /* PBXTextBookmark */; - 8BD151922495B1A800B025B9 /* PBXTextBookmark */ = 8BD151922495B1A800B025B9 /* PBXTextBookmark */; 8BDD3FE42482756800609929 /* PlistBookmark */ = 8BDD3FE42482756800609929 /* PlistBookmark */; }; sourceControlManager = 8BD3CCB8148830B20062E48C /* Source Control */; @@ -64,9 +64,9 @@ }; 8BA05A660720730100365D66 /* Beam.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {670, 3640}}"; - sepNavSelRange = "{9702, 0}"; - sepNavVisRange = "{8793, 1474}"; + sepNavIntBoundsRect = "{{0, 0}, {691, 3731}}"; + sepNavSelRange = "{11340, 0}"; + sepNavVisRange = "{10187, 1243}"; sepNavWindowFrame = "{{29, 57}, {790, 821}}"; }; }; @@ -78,11 +78,31 @@ sepNavWindowFrame = "{{15, 57}, {790, 821}}"; }; }; + 8BB9A45624B2942900CD76A8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8BA05A660720730100365D66 /* Beam.cpp */; + name = "Beam.cpp: 265"; + rLen = 0; + rLoc = 11340; + rType = 0; + vrLen = 1175; + vrLoc = 10255; + }; + 8BB9A45B24B2943A00CD76A8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8BA05A660720730100365D66 /* Beam.cpp */; + name = "Beam.cpp: 265"; + rLen = 0; + rLoc = 11340; + rType = 0; + vrLen = 1243; + vrLoc = 10187; + }; 8BC6025B073B072D006C4272 /* Beam.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {894, 1911}}"; + sepNavIntBoundsRect = "{{0, 0}, {894, 1898}}"; sepNavSelRange = "{3452, 0}"; - sepNavVisRange = "{3874, 1297}"; + sepNavVisRange = "{2317, 1514}"; sepNavWindowFrame = "{{631, 57}, {790, 821}}"; }; }; @@ -96,26 +116,6 @@ vrLen = 1297; vrLoc = 3874; }; - 8BD150E324956DDF00B025B9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 8BA05A660720730100365D66 /* Beam.cpp */; - name = "Beam.cpp: 217"; - rLen = 0; - rLoc = 9473; - rType = 0; - vrLen = 1546; - vrLoc = 8567; - }; - 8BD151922495B1A800B025B9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 8BA05A660720730100365D66 /* Beam.cpp */; - name = "Beam.cpp: 222"; - rLen = 0; - rLoc = 9702; - rType = 0; - vrLen = 1474; - vrLoc = 8793; - }; 8BD3CCB8148830B20062E48C /* Source Control */ = { isa = PBXSourceControlManager; fallbackIsa = XCSourceControlManager; diff --git a/plugins/MacAU/Beam/Beam.xcodeproj/christopherjohnson.perspectivev3 b/plugins/MacAU/Beam/Beam.xcodeproj/christopherjohnson.perspectivev3 index 0675966..b49ebae 100755 --- a/plugins/MacAU/Beam/Beam.xcodeproj/christopherjohnson.perspectivev3 +++ b/plugins/MacAU/Beam/Beam.xcodeproj/christopherjohnson.perspectivev3 @@ -256,8 +256,6 @@ Layout - BecomeActive - ContentConfiguration PBXBottomSmartGroupGIDs @@ -302,7 +300,7 @@ PBXSmartGroupTreeModuleOutlineStateSelectionKey - 4 + 3 2 1 0 @@ -326,7 +324,7 @@ 288 RubberWindowFrame - 28 202 841 654 0 0 1440 878 + 599 201 841 654 0 0 1440 878 Module PBXSmartGroupTreeModule @@ -354,12 +352,12 @@ _historyCapacity 0 bookmark - 8BD151922495B1A800B025B9 + 8BB9A45B24B2943A00CD76A8 history 8BDD3FE42482756800609929 8BD150E124956DDF00B025B9 - 8BD150E324956DDF00B025B9 + 8BB9A45624B2942900CD76A8 SplitCount @@ -373,18 +371,18 @@ GeometryConfiguration Frame - {{0, 0}, {531, 502}} + {{0, 0}, {531, 494}} RubberWindowFrame - 28 202 841 654 0 0 1440 878 + 599 201 841 654 0 0 1440 878 Module PBXNavigatorGroup Proportion - 502pt + 494pt Proportion - 106pt + 114pt Tabs @@ -398,9 +396,7 @@ GeometryConfiguration Frame - {{10, 27}, {531, 79}} - RubberWindowFrame - 28 202 841 654 0 0 1440 878 + {{10, 27}, {531, 87}} Module XCDetailModule @@ -454,7 +450,9 @@ GeometryConfiguration Frame - {{10, 27}, {531, 339}} + {{10, 27}, {531, 87}} + RubberWindowFrame + 599 201 841 654 0 0 1440 878 Module PBXBuildResultsModule @@ -482,11 +480,11 @@ TableOfContents - 8BD151932495B1A800B025B9 + 8BB9A45C24B2943A00CD76A8 1CA23ED40692098700951B8B - 8BD151942495B1A800B025B9 + 8BB9A45D24B2943A00CD76A8 8BD7274A1D46E5A5000176F0 - 8BD151952495B1A800B025B9 + 8BB9A45E24B2943A00CD76A8 1CA23EDF0692099D00951B8B 1CA23EE00692099D00951B8B 1CA23EE10692099D00951B8B @@ -659,7 +657,7 @@ StatusbarIsVisible TimeStamp - 613790120.45657098 + 615683130.465276 ToolbarConfigUserDefaultsMinorVersion 2 ToolbarDisplayMode @@ -676,11 +674,10 @@ 5 WindowOrderList - 8BD151962495B1A800B025B9 /Users/christopherjohnson/Desktop/Dithers/MacAU/Beam/Beam.xcodeproj WindowString - 28 202 841 654 0 0 1440 878 + 599 201 841 654 0 0 1440 878 WindowToolsV3 diff --git a/plugins/MacAU/Dark/Dark.cpp b/plugins/MacAU/Dark/Dark.cpp index 5f24cd4..f53b842 100755 --- a/plugins/MacAU/Dark/Dark.cpp +++ b/plugins/MacAU/Dark/Dark.cpp @@ -203,6 +203,7 @@ void Dark::DarkKernel::Process( const Float32 *inSourceP, int depth = (int)(17.0*overallscale); if (depth < 3) depth = 3; if (depth > 98) depth = 98; + bool highres = false; if (GetParameter( kParam_One ) == 1) highres = true; Float32 scaleFactor; @@ -210,8 +211,10 @@ void Dark::DarkKernel::Process( const Float32 *inSourceP, else scaleFactor = 32768.0; Float32 derez = GetParameter( kParam_Two ); if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); - if (scaleFactor < 1.0) scaleFactor = 1.0; - + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + Float32 outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; + while (nSampleFrames-- > 0) { Float32 inputSample = *sourceP; if (fabs(inputSample)<1.18e-37) inputSample = fpd * 1.18e-37; @@ -248,7 +251,7 @@ void Dark::DarkKernel::Process( const Float32 *inSourceP, } lastSample[0] = inputSample; - inputSample /= scaleFactor; + inputSample /= outScale; *destP = inputSample; diff --git a/plugins/MacAU/Dark/Dark.xcodeproj/christopherjohnson.pbxuser b/plugins/MacAU/Dark/Dark.xcodeproj/christopherjohnson.pbxuser index f8a4499..ae3e8aa 100755 --- a/plugins/MacAU/Dark/Dark.xcodeproj/christopherjohnson.pbxuser +++ b/plugins/MacAU/Dark/Dark.xcodeproj/christopherjohnson.pbxuser @@ -49,15 +49,18 @@ PBXFileDataSource_Warnings_ColumnID, ); }; - PBXPerProjectTemplateStateSaveDate = 613790145; - PBXWorkspaceStateSaveDate = 613790145; + PBXPerProjectTemplateStateSaveDate = 615682975; + PBXWorkspaceStateSaveDate = 615682975; }; perUserProjectItems = { + 8BB06EB9249D96E9000F894A /* PBXTextBookmark */ = 8BB06EB9249D96E9000F894A /* PBXTextBookmark */; + 8BB06EBA249D96E9000F894A /* PBXTextBookmark */ = 8BB06EBA249D96E9000F894A /* PBXTextBookmark */; + 8BB9A43124B293A300CD76A8 /* PBXBookmark */ = 8BB9A43124B293A300CD76A8 /* PBXBookmark */; + 8BB9A43F24B293E100CD76A8 /* PBXTextBookmark */ = 8BB9A43F24B293E100CD76A8 /* PBXTextBookmark */; + 8BB9A44424B293FB00CD76A8 /* PBXTextBookmark */ = 8BB9A44424B293FB00CD76A8 /* PBXTextBookmark */; + 8BB9A44A24B293FB00CD76A8 /* PBXTextBookmark */ = 8BB9A44A24B293FB00CD76A8 /* PBXTextBookmark */; 8BD14F0224842AB600B025B9 /* PlistBookmark */ = 8BD14F0224842AB600B025B9 /* PlistBookmark */; 8BD14F0324842AB600B025B9 /* PBXTextBookmark */ = 8BD14F0324842AB600B025B9 /* PBXTextBookmark */; - 8BD150CD24956DA100B025B9 /* PBXTextBookmark */ = 8BD150CD24956DA100B025B9 /* PBXTextBookmark */; - 8BD1515C2495A6F200B025B9 /* PBXTextBookmark */ = 8BD1515C2495A6F200B025B9 /* PBXTextBookmark */; - 8BD151A22495B1D300B025B9 /* PBXTextBookmark */ = 8BD151A22495B1D300B025B9 /* PBXTextBookmark */; }; sourceControlManager = 8BD3CCB8148830B20062E48C /* Source Control */; userBuildSettings = { @@ -65,10 +68,17 @@ }; 8BA05A660720730100365D66 /* Dark.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {656, 3536}}"; - sepNavSelRange = "{10164, 0}"; - sepNavVisRange = "{9020, 1552}"; - sepNavWindowFrame = "{{6, 57}, {790, 821}}"; + sepNavIntBoundsRect = "{{0, 0}, {743, 3588}}"; + sepNavSelRange = "{10714, 0}"; + sepNavVisRange = "{8961, 1843}"; + sepNavWindowFrame = "{{650, 57}, {790, 821}}"; + }; + }; + 8BA05A670720730100365D66 /* Dark.exp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {482, 479}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 11}"; }; }; 8BA05A690720730100365D66 /* DarkVersion.h */ = { @@ -79,12 +89,66 @@ sepNavWindowFrame = "{{15, 57}, {790, 821}}"; }; }; + 8BB06EB9249D96E9000F894A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8BA05A660720730100365D66 /* Dark.cpp */; + name = "Dark.cpp: 238"; + rLen = 0; + rLoc = 10241; + rType = 0; + vrLen = 1542; + vrLoc = 5953; + }; + 8BB06EBA249D96E9000F894A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8BA05A670720730100365D66 /* Dark.exp */; + name = "Dark.exp: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 11; + vrLoc = 0; + }; + 8BB9A43124B293A300CD76A8 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 8BA05A660720730100365D66 /* Dark.cpp */; + }; + 8BB9A43F24B293E100CD76A8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8BC6025B073B072D006C4272 /* Dark.h */; + name = "Dark.h: 135"; + rLen = 16; + rLoc = 5249; + rType = 0; + vrLen = 1016; + vrLoc = 4358; + }; + 8BB9A44424B293FB00CD76A8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8BC6025B073B072D006C4272 /* Dark.h */; + name = "Dark.h: 135"; + rLen = 16; + rLoc = 5249; + rType = 0; + vrLen = 1016; + vrLoc = 4358; + }; + 8BB9A44A24B293FB00CD76A8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8BA05A660720730100365D66 /* Dark.cpp */; + name = "Dark.cpp: 254"; + rLen = 0; + rLoc = 10714; + rType = 0; + vrLen = 1843; + vrLoc = 8961; + }; 8BC6025B073B072D006C4272 /* Dark.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {824, 1716}}"; - sepNavSelRange = "{5175, 0}"; - sepNavVisRange = "{2696, 815}"; - sepNavWindowFrame = "{{28, 47}, {790, 821}}"; + sepNavIntBoundsRect = "{{0, 0}, {894, 2054}}"; + sepNavSelRange = "{5249, 16}"; + sepNavVisRange = "{4358, 1016}"; + sepNavWindowFrame = "{{687, 57}, {790, 821}}"; }; }; 8BD14F0224842AB600B025B9 /* PlistBookmark */ = { @@ -109,36 +173,6 @@ vrLen = 1283; vrLoc = 1638; }; - 8BD150CD24956DA100B025B9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 8BC6025B073B072D006C4272 /* Dark.h */; - name = "Dark.h: 130"; - rLen = 0; - rLoc = 5175; - rType = 0; - vrLen = 815; - vrLoc = 2696; - }; - 8BD1515C2495A6F200B025B9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 8BA05A660720730100365D66 /* Dark.cpp */; - name = "Dark.cpp: 213"; - rLen = 0; - rLoc = 9186; - rType = 0; - vrLen = 1424; - vrLoc = 8513; - }; - 8BD151A22495B1D300B025B9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 8BA05A660720730100365D66 /* Dark.cpp */; - name = "Dark.cpp: 238"; - rLen = 0; - rLoc = 10164; - rType = 0; - vrLen = 1552; - vrLoc = 9020; - }; 8BD3CCB8148830B20062E48C /* Source Control */ = { isa = PBXSourceControlManager; fallbackIsa = XCSourceControlManager; diff --git a/plugins/MacAU/Dark/Dark.xcodeproj/christopherjohnson.perspectivev3 b/plugins/MacAU/Dark/Dark.xcodeproj/christopherjohnson.perspectivev3 index 1848996..d9f2308 100755 --- a/plugins/MacAU/Dark/Dark.xcodeproj/christopherjohnson.perspectivev3 +++ b/plugins/MacAU/Dark/Dark.xcodeproj/christopherjohnson.perspectivev3 @@ -222,7 +222,48 @@ OpenEditors - + + + Content + + PBXProjectModuleGUID + 8BB9A44824B293FB00CD76A8 + PBXProjectModuleLabel + Dark.cpp + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 8BB9A44924B293FB00CD76A8 + PBXProjectModuleLabel + Dark.cpp + _historyCapacity + 0 + bookmark + 8BB9A44A24B293FB00CD76A8 + history + + 8BB9A43124B293A300CD76A8 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {790, 724}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 650 113 790 765 0 0 1440 878 + + + PerspectiveWidths 841 @@ -324,7 +365,7 @@ 288 RubberWindowFrame - 7 216 841 654 0 0 1440 878 + 596 140 841 654 0 0 1440 878 Module PBXSmartGroupTreeModule @@ -335,14 +376,12 @@ Dock - BecomeActive - ContentConfiguration PBXProjectModuleGUID 8BD7274A1D46E5A5000176F0 PBXProjectModuleLabel - Dark.cpp + Dark.h PBXSplitModuleInNavigatorKey Split0 @@ -350,17 +389,18 @@ PBXProjectModuleGUID 8BD7274B1D46E5A5000176F0 PBXProjectModuleLabel - Dark.cpp + Dark.h _historyCapacity 0 bookmark - 8BD151A22495B1D300B025B9 + 8BB9A44424B293FB00CD76A8 history 8BD14F0224842AB600B025B9 8BD14F0324842AB600B025B9 - 8BD150CD24956DA100B025B9 - 8BD1515C2495A6F200B025B9 + 8BB06EB9249D96E9000F894A + 8BB06EBA249D96E9000F894A + 8BB9A43F24B293E100CD76A8 SplitCount @@ -374,18 +414,18 @@ GeometryConfiguration Frame - {{0, 0}, {531, 514}} + {{0, 0}, {531, 508}} RubberWindowFrame - 7 216 841 654 0 0 1440 878 + 596 140 841 654 0 0 1440 878 Module PBXNavigatorGroup Proportion - 514pt + 508pt Proportion - 94pt + 100pt Tabs @@ -399,9 +439,7 @@ GeometryConfiguration Frame - {{10, 27}, {531, 67}} - RubberWindowFrame - 7 216 841 654 0 0 1440 878 + {{10, 27}, {531, 73}} Module XCDetailModule @@ -455,7 +493,9 @@ GeometryConfiguration Frame - {{10, 27}, {531, 61}} + {{10, 27}, {531, 73}} + RubberWindowFrame + 596 140 841 654 0 0 1440 878 Module PBXBuildResultsModule @@ -483,11 +523,11 @@ TableOfContents - 8BD151A32495B1D300B025B9 + 8BB9A44524B293FB00CD76A8 1CA23ED40692098700951B8B - 8BD151A42495B1D300B025B9 + 8BB9A44624B293FB00CD76A8 8BD7274A1D46E5A5000176F0 - 8BD151A52495B1D300B025B9 + 8BB9A44724B293FB00CD76A8 1CA23EDF0692099D00951B8B 1CA23EE00692099D00951B8B 1CA23EE10692099D00951B8B @@ -660,7 +700,7 @@ StatusbarIsVisible TimeStamp - 613790163.86573398 + 615683067.592103 ToolbarConfigUserDefaultsMinorVersion 2 ToolbarDisplayMode @@ -677,10 +717,11 @@ 5 WindowOrderList + 8BB9A44824B293FB00CD76A8 /Users/christopherjohnson/Desktop/Dithers/MacAU/Dark/Dark.xcodeproj WindowString - 7 216 841 654 0 0 1440 878 + 596 140 841 654 0 0 1440 878 WindowToolsV3 diff --git a/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.cpp b/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.cpp index 2ca3c6f..5ca17fd 100755 --- a/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.cpp +++ b/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.cpp @@ -59,6 +59,8 @@ NotJustAnotherDither::NotJustAnotherDither(AudioUnit component) { CreateElements(); Globals()->UseIndexedParameters(kNumberOfParameters); + SetParameter(kParam_One, kDefaultValue_ParamOne ); + SetParameter(kParam_Two, kDefaultValue_ParamTwo ); #if AU_DEBUG_DISPATCHER mDebugDispatcher = new AUDebugDispatcher (this); @@ -74,7 +76,22 @@ ComponentResult NotJustAnotherDither::GetParameterValueStrings(AudioUnitScope AudioUnitParameterID inParameterID, CFArrayRef * outStrings) { - + if ((inScope == kAudioUnitScope_Global) && (inParameterID == kParam_One)) //ID must be actual name of parameter identifier, not number + { + if (outStrings == NULL) return noErr; + CFStringRef strings [] = + { + kMenuItem_CD, + kMenuItem_HD, + }; + *outStrings = CFArrayCreate ( + NULL, + (const void **) strings, + (sizeof (strings) / sizeof (strings [0])), + NULL + ); + return noErr; + } return kAudioUnitErr_InvalidProperty; } @@ -95,10 +112,24 @@ ComponentResult NotJustAnotherDither::GetParameterInfo(AudioUnitScope inScope if (inScope == kAudioUnitScope_Global) { switch(inParameterID) { - default: + case kParam_One: + AUBase::FillInParameterName (outParameterInfo, kParameterOneName, false); + outParameterInfo.unit = kAudioUnitParameterUnit_Indexed; + outParameterInfo.minValue = kCD; + outParameterInfo.maxValue = kHD; + outParameterInfo.defaultValue = kDefaultValue_ParamOne; + break; + case kParam_Two: + AUBase::FillInParameterName (outParameterInfo, kParameterTwoName, false); + outParameterInfo.unit = kAudioUnitParameterUnit_Generic; + outParameterInfo.minValue = 0.0; + outParameterInfo.maxValue = 1.0; + outParameterInfo.defaultValue = kDefaultValue_ParamTwo; + break; + default: result = kAudioUnitErr_InvalidParameter; break; - } + } } else { result = kAudioUnitErr_InvalidParameter; } @@ -150,18 +181,19 @@ ComponentResult NotJustAnotherDither::Initialize() //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void NotJustAnotherDither::NotJustAnotherDitherKernel::Reset() { - byn[0] = 1000; - byn[1] = 301; - byn[2] = 176; - byn[3] = 125; - byn[4] = 97; - byn[5] = 79; - byn[6] = 67; - byn[7] = 58; - byn[8] = 51; - byn[9] = 46; - byn[10] = 1000; + byn[0] = 1000.0; + byn[1] = 301.0; + byn[2] = 176.0; + byn[3] = 125.0; + byn[4] = 97.0; + byn[5] = 79.0; + byn[6] = 67.0; + byn[7] = 58.0; + byn[8] = 51.0; + byn[9] = 46.0; + byn[10] = 1000.0; noiseShaping = 0.0; + fpd = 17; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -175,133 +207,82 @@ void NotJustAnotherDither::NotJustAnotherDitherKernel::Process( const Float32 { UInt32 nSampleFrames = inFramesToProcess; const Float32 *sourceP = inSourceP; - Float32 *destP = inDestP; + Float32 *destP = inDestP; - long double inputSample; - Float64 benfordize; - int hotbinA; - int hotbinB; - Float64 totalA; - Float64 totalB; - Float32 drySample; + bool highres = false; + if (GetParameter( kParam_One ) == 1) highres = true; + Float32 scaleFactor; + if (highres) scaleFactor = 8388608.0; + else scaleFactor = 32768.0; + Float32 derez = GetParameter( kParam_Two ); + if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + Float32 outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; while (nSampleFrames-- > 0) { - inputSample = *sourceP; - if (inputSample<1.2e-38 && -inputSample<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; - inputSample = 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. - } - drySample = inputSample; + long double inputSample = *sourceP; + if (fabs(inputSample)<1.18e-37) inputSample = fpd * 1.18e-37; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + inputSample *= scaleFactor; + //0-1 is now one bit, now we dither + bool cutbins; cutbins = false; + long double drySample = inputSample; inputSample -= noiseShaping; - inputSample *= 8388608.0; - //0-1 is now one bit, now we dither - benfordize = floor(inputSample); - 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); + long double benfordize; benfordize = floor(inputSample); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinA; hotbinA = floor(benfordize); //hotbin becomes the Benford bin value for this number floored - totalA = 0; + long double totalA; totalA = 0; if ((hotbinA > 0) && (hotbinA < 10)) { - byn[hotbinA] += 1; - totalA += (301-byn[1]); - totalA += (176-byn[2]); - totalA += (125-byn[3]); - totalA += (97-byn[4]); - totalA += (79-byn[5]); - totalA += (67-byn[6]); - totalA += (58-byn[7]); - totalA += (51-byn[8]); - totalA += (46-byn[9]); + byn[hotbinA] += 1; if (byn[hotbinA] > 982) cutbins = true; + totalA += (301-byn[1]); totalA += (176-byn[2]); totalA += (125-byn[3]); + totalA += (97-byn[4]); totalA += (79-byn[5]); totalA += (67-byn[6]); + totalA += (58-byn[7]); totalA += (51-byn[8]); totalA += (46-byn[9]); byn[hotbinA] -= 1; - } else {hotbinA = 10;} + } else hotbinA = 10; //produce total number- smaller is closer to Benford real benfordize = ceil(inputSample); - 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); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinB; hotbinB = floor(benfordize); //hotbin becomes the Benford bin value for this number ceiled - totalB = 0; + long double totalB; totalB = 0; if ((hotbinB > 0) && (hotbinB < 10)) { - byn[hotbinB] += 1; - totalB += (301-byn[1]); - totalB += (176-byn[2]); - totalB += (125-byn[3]); - totalB += (97-byn[4]); - totalB += (79-byn[5]); - totalB += (67-byn[6]); - totalB += (58-byn[7]); - totalB += (51-byn[8]); - totalB += (46-byn[9]); + byn[hotbinB] += 1; if (byn[hotbinB] > 982) cutbins = true; + totalB += (301-byn[1]); totalB += (176-byn[2]); totalB += (125-byn[3]); + totalB += (97-byn[4]); totalB += (79-byn[5]); totalB += (67-byn[6]); + totalB += (58-byn[7]); totalB += (51-byn[8]); totalB += (46-byn[9]); byn[hotbinB] -= 1; - } else {hotbinB = 10;} + } else hotbinB = 10; //produce total number- smaller is closer to Benford real - if (totalA < totalB) - { - byn[hotbinA] += 1; - inputSample = floor(inputSample); - } - else - { - byn[hotbinB] += 1; - inputSample = ceil(inputSample); - } + long double outputSample; + if (totalA < totalB) {byn[hotbinA] += 1; outputSample = floor(inputSample);} + else {byn[hotbinB] += 1; outputSample = floor(inputSample+1);} //assign the relevant one to the delay line //and floor/ceil signal accordingly + if (cutbins) { + byn[1] *= 0.99; byn[2] *= 0.99; byn[3] *= 0.99; byn[4] *= 0.99; byn[5] *= 0.99; + byn[6] *= 0.99; byn[7] *= 0.99; byn[8] *= 0.99; byn[9] *= 0.99; byn[10] *= 0.99; + } + noiseShaping += outputSample - drySample; + if (noiseShaping > fabs(inputSample)) noiseShaping = fabs(inputSample); + if (noiseShaping < -fabs(inputSample)) noiseShaping = -fabs(inputSample); - totalA = byn[1] + byn[2] + byn[3] + byn[4] + byn[5] + byn[6] + byn[7] + byn[8] + byn[9]; - totalA /= 1000; - if (totalA = 0) totalA = 1; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - byn[1] /= totalA; - byn[2] /= totalA; - byn[3] /= totalA; - byn[4] /= totalA; - byn[5] /= totalA; - byn[6] /= totalA; - byn[7] /= totalA; - byn[8] /= totalA; - byn[9] /= totalA; - byn[10] /= 2; //catchall for garbage data - - inputSample /= 8388608.0; - - noiseShaping += inputSample - drySample; + inputSample = outputSample / outScale; + if (inputSample > 1.0) inputSample = 1.0; + if (inputSample < -1.0) inputSample = -1.0; + *destP = inputSample; sourceP += inNumChannels; destP += inNumChannels; } diff --git a/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.h b/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.h index 87b74c6..d519bfb 100755 --- a/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.h +++ b/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.h @@ -54,11 +54,21 @@ #pragma mark ____NotJustAnotherDither Parameters // parameters -//Alter the name if desired, but using the plugin name is a start +static CFStringRef kParameterOneName = CFSTR("Quantizer"); +static const int kCD = 0; +static const int kHD = 1; +static const int kDefaultValue_ParamOne = kHD; +static CFStringRef kMenuItem_CD = CFSTR ("CD 16 bit"); +static CFStringRef kMenuItem_HD = CFSTR ("HD 24 bit"); + +static CFStringRef kParameterTwoName = CFSTR("DeRez"); +static const float kDefaultValue_ParamTwo = 0.0; enum { + kParam_One = 0, + kParam_Two = 1, //Add your parameters here... - kNumberOfParameters=0 + kNumberOfParameters=2 }; #pragma mark ____NotJustAnotherDither @@ -123,6 +133,7 @@ public: private: Float64 byn[13]; long double noiseShaping; + uint32_t fpd; }; }; diff --git a/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.pbxuser b/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.pbxuser index 3aee3d6..18ab75c 100755 --- a/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.pbxuser +++ b/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.pbxuser @@ -10,7 +10,7 @@ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; PBXFileTableDataSourceColumnWidthsKey = ( 20, - 292, + 594, 20, 48, 43, @@ -49,13 +49,14 @@ PBXFileDataSource_Warnings_ColumnID, ); }; - PBXPerProjectTemplateStateSaveDate = 568766952; - PBXWorkspaceStateSaveDate = 568766952; + PBXPerProjectTemplateStateSaveDate = 615683941; + PBXWorkspaceStateSaveDate = 615683941; }; perUserProjectItems = { 8B8D6A12207ABF2E0029B7B0 /* PlistBookmark */ = 8B8D6A12207ABF2E0029B7B0 /* PlistBookmark */; - 8BAF09C221E6BA5C00C38394 /* PBXTextBookmark */ = 8BAF09C221E6BA5C00C38394 /* PBXTextBookmark */; - 8BBB2F6D21B620F100825986 /* PBXTextBookmark */ = 8BBB2F6D21B620F100825986 /* PBXTextBookmark */; + 8BB071CA24A94A14000F894A /* PBXTextBookmark */ = 8BB071CA24A94A14000F894A /* PBXTextBookmark */; + 8BB9A46B24B2945000CD76A8 /* PBXTextBookmark */ = 8BB9A46B24B2945000CD76A8 /* PBXTextBookmark */; + 8BB9A55324B2977000CD76A8 /* PBXTextBookmark */ = 8BB9A55324B2977000CD76A8 /* PBXTextBookmark */; }; sourceControlManager = 8BD3CCB8148830B20062E48C /* Source Control */; userBuildSettings = { @@ -75,10 +76,10 @@ }; 8BA05A660720730100365D66 /* NotJustAnotherDither.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {691, 4082}}"; - sepNavSelRange = "{8123, 0}"; - sepNavVisRange = "{8086, 233}"; - sepNavWindowFrame = "{{517, 41}, {923, 837}}"; + sepNavIntBoundsRect = "{{0, 0}, {784, 3965}}"; + sepNavSelRange = "{9521, 119}"; + sepNavVisRange = "{11022, 1332}"; + sepNavWindowFrame = "{{743, 57}, {923, 821}}"; }; }; 8BA05A680720730100365D66 /* NotJustAnotherDither.r */ = { @@ -93,36 +94,46 @@ uiCtxt = { sepNavIntBoundsRect = "{{0, 0}, {876, 767}}"; sepNavSelRange = "{2971, 0}"; - sepNavVisRange = "{60, 2974}"; - sepNavWindowFrame = "{{15, 39}, {923, 837}}"; + sepNavVisRange = "{45, 2989}"; + sepNavWindowFrame = "{{15, 57}, {923, 821}}"; }; }; - 8BAF09C221E6BA5C00C38394 /* PBXTextBookmark */ = { + 8BB071CA24A94A14000F894A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 8BC6025B073B072D006C4272 /* NotJustAnotherDither.h */; + name = "NotJustAnotherDither.h: 136"; + rLen = 16; + rLoc = 5477; + rType = 0; + vrLen = 969; + vrLoc = 4633; + }; + 8BB9A46B24B2945000CD76A8 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 8BA05A660720730100365D66 /* NotJustAnotherDither.cpp */; - name = "NotJustAnotherDither.cpp: 190"; - rLen = 0; - rLoc = 8123; + name = "NotJustAnotherDither.cpp: 219"; + rLen = 119; + rLoc = 9521; rType = 0; - vrLen = 233; - vrLoc = 8086; + vrLen = 1374; + vrLoc = 9281; }; - 8BBB2F6D21B620F100825986 /* PBXTextBookmark */ = { + 8BB9A55324B2977000CD76A8 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 8BA05A660720730100365D66 /* NotJustAnotherDither.cpp */; - name = "NotJustAnotherDither.cpp: 190"; - rLen = 0; - rLoc = 8123; + name = "NotJustAnotherDither.cpp: 219"; + rLen = 119; + rLoc = 9521; rType = 0; - vrLen = 253; - vrLoc = 8066; + vrLen = 1332; + vrLoc = 11022; }; 8BC6025B073B072D006C4272 /* NotJustAnotherDither.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {894, 1716}}"; - sepNavSelRange = "{4975, 0}"; - sepNavVisRange = "{3502, 1743}"; - sepNavWindowFrame = "{{517, 39}, {923, 837}}"; + sepNavIntBoundsRect = "{{0, 0}, {894, 1807}}"; + sepNavSelRange = "{5477, 16}"; + sepNavVisRange = "{3917, 1685}"; + sepNavWindowFrame = "{{0, 57}, {923, 821}}"; }; }; 8BD3CCB8148830B20062E48C /* Source Control */ = { diff --git a/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.perspectivev3 b/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.perspectivev3 index faa330c..84eaaac 100755 --- a/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.perspectivev3 +++ b/plugins/MacAU/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.perspectivev3 @@ -256,8 +256,6 @@ Layout - BecomeActive - ContentConfiguration PBXBottomSmartGroupGIDs @@ -282,7 +280,7 @@ PBXSmartGroupTreeModuleColumnWidthsKey - 288 + 230 PBXSmartGroupTreeModuleColumnsKey_v4 @@ -308,7 +306,7 @@ PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {288, 595}} + {{0, 0}, {230, 605}} PBXTopSmartGroupGIDs @@ -318,24 +316,26 @@ GeometryConfiguration Frame - {{0, 0}, {305, 613}} + {{0, 0}, {247, 623}} GroupTreeTableConfiguration MainColumn - 288 + 230 RubberWindowFrame - 780 134 841 654 0 0 1440 878 + 68 214 1085 664 0 0 1440 878 Module PBXSmartGroupTreeModule Proportion - 305pt + 247pt Dock + BecomeActive + ContentConfiguration PBXProjectModuleGUID @@ -353,11 +353,12 @@ _historyCapacity 0 bookmark - 8BAF09C221E6BA5C00C38394 + 8BB9A55324B2977000CD76A8 history 8B8D6A12207ABF2E0029B7B0 - 8BBB2F6D21B620F100825986 + 8BB071CA24A94A14000F894A + 8BB9A46B24B2945000CD76A8 SplitCount @@ -371,18 +372,18 @@ GeometryConfiguration Frame - {{0, 0}, {531, 109}} + {{0, 0}, {833, 470}} RubberWindowFrame - 780 134 841 654 0 0 1440 878 + 68 214 1085 664 0 0 1440 878 Module PBXNavigatorGroup Proportion - 109pt + 470pt Proportion - 499pt + 148pt Tabs @@ -396,9 +397,9 @@ GeometryConfiguration Frame - {{10, 27}, {531, 472}} + {{10, 27}, {833, 121}} RubberWindowFrame - 780 134 841 654 0 0 1440 878 + 68 214 1085 664 0 0 1440 878 Module XCDetailModule @@ -452,7 +453,7 @@ GeometryConfiguration Frame - {{10, 27}, {531, 315}} + {{10, 27}, {531, 489}} Module PBXBuildResultsModule @@ -461,7 +462,7 @@ Proportion - 531pt + 833pt Name @@ -480,11 +481,11 @@ TableOfContents - 8BAF09C321E6BA5C00C38394 + 8BB9A55424B2977000CD76A8 1CA23ED40692098700951B8B - 8BAF09C421E6BA5C00C38394 + 8BB9A55524B2977000CD76A8 8BD7274A1D46E5A5000176F0 - 8BAF09C521E6BA5C00C38394 + 8BB9A55624B2977000CD76A8 1CA23EDF0692099D00951B8B 1CA23EE00692099D00951B8B 1CA23EE10692099D00951B8B @@ -657,7 +658,7 @@ StatusbarIsVisible TimeStamp - 568769116.18578196 + 615683952.11029994 ToolbarConfigUserDefaultsMinorVersion 2 ToolbarDisplayMode @@ -674,11 +675,10 @@ 5 WindowOrderList - 8BAF09C621E6BA5C00C38394 - /Users/christopherjohnson/Desktop/MacAU/NotJustAnotherDither/NotJustAnotherDither.xcodeproj + /Users/christopherjohnson/Desktop/Dithers/MacAU/NotJustAnotherDither/NotJustAnotherDither.xcodeproj WindowString - 780 134 841 654 0 0 1440 878 + 68 214 1085 664 0 0 1440 878 WindowToolsV3 diff --git a/plugins/MacVST/Beam/Beam.xcodeproj/christopherjohnson.pbxuser b/plugins/MacVST/Beam/Beam.xcodeproj/christopherjohnson.pbxuser index bf949c7..ab6dc93 100755 --- a/plugins/MacVST/Beam/Beam.xcodeproj/christopherjohnson.pbxuser +++ b/plugins/MacVST/Beam/Beam.xcodeproj/christopherjohnson.pbxuser @@ -49,14 +49,14 @@ PBXFileDataSource_Warnings_ColumnID, ); }; - PBXPerProjectTemplateStateSaveDate = 613785702; - PBXWorkspaceStateSaveDate = 613785702; + PBXPerProjectTemplateStateSaveDate = 615684221; + PBXWorkspaceStateSaveDate = 615684221; }; perUserProjectItems = { + 8BB9A54324B296EC00CD76A8 /* PBXTextBookmark */ = 8BB9A54324B296EC00CD76A8 /* PBXTextBookmark */; + 8BB9A5B624B2988F00CD76A8 /* PBXTextBookmark */ = 8BB9A5B624B2988F00CD76A8 /* PBXTextBookmark */; 8BD150EB24956DE000B025B9 /* PBXTextBookmark */ = 8BD150EB24956DE000B025B9 /* PBXTextBookmark */; 8BD150EC24956DE000B025B9 /* PBXTextBookmark */ = 8BD150EC24956DE000B025B9 /* PBXTextBookmark */; - 8BD151822495B14D00B025B9 /* PBXTextBookmark */ = 8BD151822495B14D00B025B9 /* PBXTextBookmark */; - 8BD151892495B18A00B025B9 /* PBXTextBookmark */ = 8BD151892495B18A00B025B9 /* PBXTextBookmark */; }; sourceControlManager = 8B02375E1D42B1C400E1E8C8 /* Source Control */; userBuildSettings = { @@ -64,9 +64,9 @@ }; 2407DEB6089929BA00EB68BF /* Beam.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {740, 1859}}"; + sepNavIntBoundsRect = "{{0, 0}, {848, 1859}}"; sepNavSelRange = "{4202, 0}"; - sepNavVisRange = "{1092, 1054}"; + sepNavVisRange = "{0, 1908}"; sepNavWindowFrame = "{{530, 57}, {895, 821}}"; }; }; @@ -88,9 +88,9 @@ }; 24D8286F09A914000093AEF8 /* BeamProc.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {691, 3536}}"; - sepNavSelRange = "{5480, 0}"; - sepNavVisRange = "{5165, 926}"; + sepNavIntBoundsRect = "{{0, 0}, {691, 3471}}"; + sepNavSelRange = "{5619, 0}"; + sepNavVisRange = "{8812, 565}"; sepNavWindowFrame = "{{543, 57}, {895, 821}}"; }; }; @@ -108,6 +108,26 @@ isa = PBXCodeSenseManager; indexTemplatePath = ""; }; + 8BB9A54324B296EC00CD76A8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 24D8286F09A914000093AEF8 /* BeamProc.cpp */; + name = "BeamProc.cpp: 164"; + rLen = 0; + rLoc = 5619; + rType = 0; + vrLen = 766; + vrLoc = 295; + }; + 8BB9A5B624B2988F00CD76A8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 24D8286F09A914000093AEF8 /* BeamProc.cpp */; + name = "BeamProc.cpp: 164"; + rLen = 0; + rLoc = 5619; + rType = 0; + vrLen = 565; + vrLoc = 8812; + }; 8BD150EB24956DE000B025B9 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 245463B80991757100464AD3 /* Beam.h */; @@ -128,26 +148,6 @@ vrLen = 1054; vrLoc = 1092; }; - 8BD151822495B14D00B025B9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 24D8286F09A914000093AEF8 /* BeamProc.cpp */; - name = "BeamProc.cpp: 159"; - rLen = 0; - rLoc = 5480; - rType = 0; - vrLen = 926; - vrLoc = 5161; - }; - 8BD151892495B18A00B025B9 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 24D8286F09A914000093AEF8 /* BeamProc.cpp */; - name = "BeamProc.cpp: 159"; - rLen = 0; - rLoc = 5480; - rType = 0; - vrLen = 926; - vrLoc = 5165; - }; 8D01CCC60486CAD60068D4B7 /* Beam */ = { activeExec = 0; }; diff --git a/plugins/MacVST/Beam/Beam.xcodeproj/christopherjohnson.perspectivev3 b/plugins/MacVST/Beam/Beam.xcodeproj/christopherjohnson.perspectivev3 index cc1d5e4..69d60a1 100755 --- a/plugins/MacVST/Beam/Beam.xcodeproj/christopherjohnson.perspectivev3 +++ b/plugins/MacVST/Beam/Beam.xcodeproj/christopherjohnson.perspectivev3 @@ -256,6 +256,8 @@ Layout + BecomeActive + ContentConfiguration PBXBottomSmartGroupGIDs @@ -321,7 +323,7 @@ 185 RubberWindowFrame - 621 354 810 487 0 0 1440 878 + 584 368 810 487 0 0 1440 878 Module PBXSmartGroupTreeModule @@ -349,12 +351,12 @@ _historyCapacity 0 bookmark - 8BD151892495B18A00B025B9 + 8BB9A5B624B2988F00CD76A8 history 8BD150EB24956DE000B025B9 8BD150EC24956DE000B025B9 - 8BD151822495B14D00B025B9 + 8BB9A54324B296EC00CD76A8 SplitCount @@ -368,18 +370,18 @@ GeometryConfiguration Frame - {{0, 0}, {603, 358}} + {{0, 0}, {603, 346}} RubberWindowFrame - 621 354 810 487 0 0 1440 878 + 584 368 810 487 0 0 1440 878 Module PBXNavigatorGroup Proportion - 358pt + 346pt Proportion - 83pt + 95pt Tabs @@ -393,7 +395,9 @@ GeometryConfiguration Frame - {{10, 27}, {603, 56}} + {{10, 27}, {603, 68}} + RubberWindowFrame + 584 368 810 487 0 0 1440 878 Module XCDetailModule @@ -448,8 +452,6 @@ Frame {{10, 27}, {603, 56}} - RubberWindowFrame - 621 354 810 487 0 0 1440 878 Module PBXBuildResultsModule @@ -477,11 +479,11 @@ TableOfContents - 8BD1518A2495B18A00B025B9 + 8BB9A5B724B2988F00CD76A8 1CA23ED40692098700951B8B - 8BD1518B2495B18A00B025B9 + 8BB9A5B824B2988F00CD76A8 8B0237581D42B1C400E1E8C8 - 8BD1518C2495B18A00B025B9 + 8BB9A5B924B2988F00CD76A8 1CA23EDF0692099D00951B8B 1CA23EE00692099D00951B8B 1CA23EE10692099D00951B8B @@ -634,7 +636,7 @@ StatusbarIsVisible TimeStamp - 613790090.00095999 + 615684239.58308196 ToolbarConfigUserDefaultsMinorVersion 2 ToolbarDisplayMode @@ -651,11 +653,10 @@ 5 WindowOrderList - 8BD1518D2495B18A00B025B9 /Users/christopherjohnson/Desktop/Dithers/MacVST/Beam/Beam.xcodeproj WindowString - 621 354 810 487 0 0 1440 878 + 584 368 810 487 0 0 1440 878 WindowToolsV3 diff --git a/plugins/MacVST/Beam/source/BeamProc.cpp b/plugins/MacVST/Beam/source/BeamProc.cpp index 920f5b4..5871eb5 100755 --- a/plugins/MacVST/Beam/source/BeamProc.cpp +++ b/plugins/MacVST/Beam/source/BeamProc.cpp @@ -30,6 +30,8 @@ void Beam::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram float derez = C; if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; while (--sampleFrames >= 0) { @@ -121,8 +123,8 @@ void Beam::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram lastSampleR[0] = inputSampleR; //end right - inputSampleL /= scaleFactor; - inputSampleR /= scaleFactor; + inputSampleL /= outScale; + inputSampleR /= outScale; *out1 = inputSampleL; *out2 = inputSampleR; @@ -156,8 +158,10 @@ void Beam::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa else scaleFactor = 32768.0; float derez = C; if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); - if (scaleFactor < 1.0) scaleFactor = 1.0; - + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; + while (--sampleFrames >= 0) { long double inputSampleL = *in1; @@ -248,8 +252,8 @@ void Beam::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa lastSampleR[0] = inputSampleR; //end right - inputSampleL /= scaleFactor; - inputSampleR /= scaleFactor; + inputSampleL /= outScale; + inputSampleR /= outScale; *out1 = inputSampleL; *out2 = inputSampleR; diff --git a/plugins/MacVST/Dark/Dark.xcodeproj/christopherjohnson.pbxuser b/plugins/MacVST/Dark/Dark.xcodeproj/christopherjohnson.pbxuser index ab4e77f..fade19f 100755 --- a/plugins/MacVST/Dark/Dark.xcodeproj/christopherjohnson.pbxuser +++ b/plugins/MacVST/Dark/Dark.xcodeproj/christopherjohnson.pbxuser @@ -10,7 +10,7 @@ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; PBXFileTableDataSourceColumnWidthsKey = ( 20, - 364, + 433, 20, 48, 43, @@ -49,14 +49,14 @@ PBXFileDataSource_Warnings_ColumnID, ); }; - PBXPerProjectTemplateStateSaveDate = 613785687; - PBXWorkspaceStateSaveDate = 613785687; + PBXPerProjectTemplateStateSaveDate = 615684199; + PBXWorkspaceStateSaveDate = 615684199; }; perUserProjectItems = { - 8BD150E724956DDF00B025B9 /* PBXTextBookmark */ = 8BD150E724956DDF00B025B9 /* PBXTextBookmark */; - 8BD150E824956DDF00B025B9 /* PBXTextBookmark */ = 8BD150E824956DDF00B025B9 /* PBXTextBookmark */; - 8BD150EA24956DDF00B025B9 /* PBXTextBookmark */ = 8BD150EA24956DDF00B025B9 /* PBXTextBookmark */; - 8BD151602495A6F400B025B9 /* PBXTextBookmark */ = 8BD151602495A6F400B025B9 /* PBXTextBookmark */; + 8BB07C2224B14991000F894A /* PBXTextBookmark */ = 8BB07C2224B14991000F894A /* PBXTextBookmark */; + 8BB07C8D24B14CB2000F894A /* PBXTextBookmark */ = 8BB07C8D24B14CB2000F894A /* PBXTextBookmark */; + 8BB9A52024B2969B00CD76A8 /* PBXTextBookmark */ = 8BB9A52024B2969B00CD76A8 /* PBXTextBookmark */; + 8BB9A59624B2987700CD76A8 /* PBXTextBookmark */ = 8BB9A59624B2987700CD76A8 /* PBXTextBookmark */; }; sourceControlManager = 8B02375E1D42B1C400E1E8C8 /* Source Control */; userBuildSettings = { @@ -64,18 +64,18 @@ }; 2407DEB6089929BA00EB68BF /* Dark.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {740, 1807}}"; - sepNavSelRange = "{4061, 0}"; - sepNavVisRange = "{1333, 920}"; - sepNavWindowFrame = "{{559, 57}, {895, 821}}"; + sepNavIntBoundsRect = "{{0, 0}, {656, 1768}}"; + sepNavSelRange = "{4121, 231}"; + sepNavVisRange = "{3916, 978}"; + sepNavWindowFrame = "{{545, 57}, {895, 821}}"; }; }; 245463B80991757100464AD3 /* Dark.h */ = { uiCtxt = { sepNavIntBoundsRect = "{{0, 0}, {866, 858}}"; - sepNavSelRange = "{2475, 0}"; - sepNavVisRange = "{204, 390}"; - sepNavWindowFrame = "{{545, 57}, {895, 821}}"; + sepNavSelRange = "{2418, 59}"; + sepNavVisRange = "{0, 580}"; + sepNavWindowFrame = "{{888, -91}, {895, 821}}"; }; }; 24A2FFDB0F90D1DD003BB5A7 /* audioeffectx.cpp */ = { @@ -88,9 +88,9 @@ }; 24D8286F09A914000093AEF8 /* DarkProc.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {656, 3146}}"; - sepNavSelRange = "{4768, 0}"; - sepNavVisRange = "{4380, 807}"; + sepNavIntBoundsRect = "{{0, 0}, {656, 3107}}"; + sepNavSelRange = "{4793, 117}"; + sepNavVisRange = "{4314, 1529}"; sepNavWindowFrame = "{{531, 57}, {895, 821}}"; }; }; @@ -108,45 +108,45 @@ isa = PBXCodeSenseManager; indexTemplatePath = ""; }; - 8BD150E724956DDF00B025B9 /* PBXTextBookmark */ = { + 8BB07C2224B14991000F894A /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 245463B80991757100464AD3 /* Dark.h */; - name = "Dark.h: 62"; - rLen = 0; - rLoc = 2475; + name = "Dark.h: 58"; + rLen = 59; + rLoc = 2418; rType = 0; - vrLen = 390; - vrLoc = 204; + vrLen = 580; + vrLoc = 0; }; - 8BD150E824956DDF00B025B9 /* PBXTextBookmark */ = { + 8BB07C8D24B14CB2000F894A /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 2407DEB6089929BA00EB68BF /* Dark.cpp */; - name = "Dark.cpp: 110"; - rLen = 0; - rLoc = 4061; + name = "Dark.cpp: 112"; + rLen = 231; + rLoc = 4121; rType = 0; - vrLen = 920; - vrLoc = 1333; + vrLen = 978; + vrLoc = 3916; }; - 8BD150EA24956DDF00B025B9 /* PBXTextBookmark */ = { + 8BB9A52024B2969B00CD76A8 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 24D8286F09A914000093AEF8 /* DarkProc.cpp */; - name = "DarkProc.cpp: 143"; + name = "DarkProc.cpp: 227"; rLen = 0; - rLoc = 4770; + rLoc = 7947; rType = 0; - vrLen = 881; - vrLoc = 642; + vrLen = 1334; + vrLoc = 6717; }; - 8BD151602495A6F400B025B9 /* PBXTextBookmark */ = { + 8BB9A59624B2987700CD76A8 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 24D8286F09A914000093AEF8 /* DarkProc.cpp */; - name = "DarkProc.cpp: 142"; - rLen = 0; - rLoc = 4768; + name = "DarkProc.cpp: 146"; + rLen = 117; + rLoc = 4793; rType = 0; - vrLen = 807; - vrLoc = 4380; + vrLen = 1529; + vrLoc = 4314; }; 8D01CCC60486CAD60068D4B7 /* Dark */ = { activeExec = 0; diff --git a/plugins/MacVST/Dark/Dark.xcodeproj/christopherjohnson.perspectivev3 b/plugins/MacVST/Dark/Dark.xcodeproj/christopherjohnson.perspectivev3 index 0626f1d..9acdef6 100755 --- a/plugins/MacVST/Dark/Dark.xcodeproj/christopherjohnson.perspectivev3 +++ b/plugins/MacVST/Dark/Dark.xcodeproj/christopherjohnson.perspectivev3 @@ -304,7 +304,7 @@ PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {185, 428}} + {{0, 0}, {185, 695}} PBXTopSmartGroupGIDs @@ -314,14 +314,14 @@ GeometryConfiguration Frame - {{0, 0}, {202, 446}} + {{0, 0}, {202, 713}} GroupTreeTableConfiguration MainColumn 185 RubberWindowFrame - 625 378 810 487 0 0 1440 878 + 493 122 879 754 0 0 1440 878 Module PBXSmartGroupTreeModule @@ -351,12 +351,12 @@ _historyCapacity 0 bookmark - 8BD151602495A6F400B025B9 + 8BB9A59624B2987700CD76A8 history - 8BD150E724956DDF00B025B9 - 8BD150E824956DDF00B025B9 - 8BD150EA24956DDF00B025B9 + 8BB07C2224B14991000F894A + 8BB07C8D24B14CB2000F894A + 8BB9A52024B2969B00CD76A8 SplitCount @@ -370,18 +370,18 @@ GeometryConfiguration Frame - {{0, 0}, {603, 334}} + {{0, 0}, {672, 593}} RubberWindowFrame - 625 378 810 487 0 0 1440 878 + 493 122 879 754 0 0 1440 878 Module PBXNavigatorGroup Proportion - 334pt + 593pt Proportion - 107pt + 115pt Tabs @@ -395,9 +395,9 @@ GeometryConfiguration Frame - {{10, 27}, {603, 80}} + {{10, 27}, {672, 88}} RubberWindowFrame - 625 378 810 487 0 0 1440 878 + 493 122 879 754 0 0 1440 878 Module XCDetailModule @@ -460,7 +460,7 @@ Proportion - 603pt + 672pt Name @@ -479,11 +479,11 @@ TableOfContents - 8BD151612495A6F400B025B9 + 8BB9A59724B2987700CD76A8 1CA23ED40692098700951B8B - 8BD151622495A6F400B025B9 + 8BB9A59824B2987700CD76A8 8B0237581D42B1C400E1E8C8 - 8BD151632495A6F400B025B9 + 8BB9A59924B2987700CD76A8 1CA23EDF0692099D00951B8B 1CA23EE00692099D00951B8B 1CA23EE10692099D00951B8B @@ -636,7 +636,7 @@ StatusbarIsVisible TimeStamp - 613787380.50059402 + 615684215.23886502 ToolbarConfigUserDefaultsMinorVersion 2 ToolbarDisplayMode @@ -656,7 +656,7 @@ /Users/christopherjohnson/Desktop/Dithers/MacVST/Dark/Dark.xcodeproj WindowString - 625 378 810 487 0 0 1440 878 + 493 122 879 754 0 0 1440 878 WindowToolsV3 diff --git a/plugins/MacVST/Dark/source/Dark.cpp b/plugins/MacVST/Dark/source/Dark.cpp index bae0428..f652aa4 100755 --- a/plugins/MacVST/Dark/source/Dark.cpp +++ b/plugins/MacVST/Dark/source/Dark.cpp @@ -14,11 +14,11 @@ Dark::Dark(audioMasterCallback audioMaster) : { A = 1.0; B = 0.0; + fpd = 17; for(int count = 0; count < 99; count++) { lastSampleL[count] = 0; lastSampleR[count] = 0; } - fpd = 17; //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. diff --git a/plugins/MacVST/Dark/source/DarkProc.cpp b/plugins/MacVST/Dark/source/DarkProc.cpp index 2aa85c4..955a53f 100755 --- a/plugins/MacVST/Dark/source/DarkProc.cpp +++ b/plugins/MacVST/Dark/source/DarkProc.cpp @@ -13,13 +13,14 @@ void Dark::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram float* in2 = inputs[1]; float* out1 = outputs[0]; float* out2 = outputs[1]; - int processing = (VstInt32)( A * 1.999 ); double overallscale = 1.0; overallscale /= 44100.0; overallscale *= getSampleRate(); int depth = (int)(17.0*overallscale); if (depth < 3) depth = 3; if (depth > 98) depth = 98; + + int processing = (VstInt32)( A * 1.999 ); bool highres = false; if (processing == 1) highres = true; float scaleFactor; @@ -28,6 +29,8 @@ void Dark::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram float derez = B; if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; while (--sampleFrames >= 0) { @@ -105,8 +108,8 @@ void Dark::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram lastSampleR[0] = inputSampleR; //end right - inputSampleL /= scaleFactor; - inputSampleR /= scaleFactor; + inputSampleL /= outScale; + inputSampleR /= outScale; *out1 = inputSampleL; *out2 = inputSampleR; @@ -125,13 +128,14 @@ void Dark::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa double* out1 = outputs[0]; double* out2 = outputs[1]; - int processing = (VstInt32)( A * 1.999 ); double overallscale = 1.0; overallscale /= 44100.0; overallscale *= getSampleRate(); int depth = (int)(17.0*overallscale); if (depth < 3) depth = 3; if (depth > 98) depth = 98; + + int processing = (VstInt32)( A * 1.999 ); bool highres = false; if (processing == 1) highres = true; float scaleFactor; @@ -139,7 +143,9 @@ void Dark::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa else scaleFactor = 32768.0; float derez = B; if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); - if (scaleFactor < 1.0) scaleFactor = 1.0; + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; while (--sampleFrames >= 0) { @@ -217,8 +223,8 @@ void Dark::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa lastSampleR[0] = inputSampleR; //end right - inputSampleL /= scaleFactor; - inputSampleR /= scaleFactor; + inputSampleL /= outScale; + inputSampleR /= outScale; *out1 = inputSampleL; *out2 = inputSampleR; diff --git a/plugins/MacVST/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.pbxuser b/plugins/MacVST/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.pbxuser index baca580..0c7cd53 100755 --- a/plugins/MacVST/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.pbxuser +++ b/plugins/MacVST/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.pbxuser @@ -49,14 +49,13 @@ PBXFileDataSource_Warnings_ColumnID, ); }; - PBXPerProjectTemplateStateSaveDate = 557696448; - PBXWorkspaceStateSaveDate = 557696448; + PBXPerProjectTemplateStateSaveDate = 615684254; + PBXWorkspaceStateSaveDate = 615684254; }; perUserProjectItems = { - 8B7E3DCF20A6735C00482CB5 /* PBXTextBookmark */ = 8B7E3DCF20A6735C00482CB5 /* PBXTextBookmark */; - 8B7E3DD020A6735C00482CB5 /* PBXTextBookmark */ = 8B7E3DD020A6735C00482CB5 /* PBXTextBookmark */; - 8B91401D213DC60B00BA6EEC /* PBXTextBookmark */ = 8B91401D213DC60B00BA6EEC /* PBXTextBookmark */; - 8B91401E213DC60B00BA6EEC /* PBXTextBookmark */ = 8B91401E213DC60B00BA6EEC /* PBXTextBookmark */; + 8BB9A42324B28A6700CD76A8 /* PBXTextBookmark */ = 8BB9A42324B28A6700CD76A8 /* PBXTextBookmark */; + 8BB9A50B24B2963800CD76A8 /* PBXTextBookmark */ = 8BB9A50B24B2963800CD76A8 /* PBXTextBookmark */; + 8BB9A5D724B298B700CD76A8 /* PBXTextBookmark */ = 8BB9A5D724B298B700CD76A8 /* PBXTextBookmark */; }; sourceControlManager = 8B02375E1D42B1C400E1E8C8 /* Source Control */; userBuildSettings = { @@ -64,34 +63,34 @@ }; 2407DEB6089929BA00EB68BF /* NotJustAnotherDither.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {810, 1352}}"; - sepNavSelRange = "{528, 392}"; - sepNavVisRange = "{1431, 451}"; - sepNavWindowFrame = "{{12, 47}, {895, 831}}"; + sepNavIntBoundsRect = "{{0, 0}, {848, 2028}}"; + sepNavSelRange = "{4950, 0}"; + sepNavVisRange = "{3151, 2322}"; + sepNavWindowFrame = "{{12, 57}, {895, 821}}"; }; }; 245463B80991757100464AD3 /* NotJustAnotherDither.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {481, 832}}"; + sepNavIntBoundsRect = "{{0, 0}, {481, 897}}"; sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{0, 331}"; - sepNavWindowFrame = "{{20, 47}, {895, 831}}"; + sepNavVisRange = "{0, 237}"; + sepNavWindowFrame = "{{20, 57}, {895, 821}}"; }; }; 24A2FFDB0F90D1DD003BB5A7 /* audioeffectx.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {838, 19838}}"; + sepNavIntBoundsRect = "{{0, 0}, {838, 19890}}"; sepNavSelRange = "{10616, 0}"; - sepNavVisRange = "{10613, 123}"; + sepNavVisRange = "{10459, 280}"; sepNavWindowFrame = "{{15, 42}, {895, 831}}"; }; }; 24D8286F09A914000093AEF8 /* NotJustAnotherDitherProc.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {677, 6474}}"; - sepNavSelRange = "{2713, 0}"; - sepNavVisRange = "{1671, 272}"; - sepNavWindowFrame = "{{545, 47}, {895, 831}}"; + sepNavIntBoundsRect = "{{0, 0}, {768, 4147}}"; + sepNavSelRange = "{6513, 0}"; + sepNavVisRange = "{6511, 68}"; + sepNavWindowFrame = "{{24, 57}, {895, 821}}"; }; }; 8B02375E1D42B1C400E1E8C8 /* Source Control */ = { @@ -108,45 +107,35 @@ isa = PBXCodeSenseManager; indexTemplatePath = ""; }; - 8B7E3DCF20A6735C00482CB5 /* PBXTextBookmark */ = { + 8BB9A42324B28A6700CD76A8 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 245463B80991757100464AD3 /* NotJustAnotherDither.h */; name = "NotJustAnotherDither.h: 1"; rLen = 0; rLoc = 0; rType = 0; - vrLen = 331; + vrLen = 237; vrLoc = 0; }; - 8B7E3DD020A6735C00482CB5 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 2407DEB6089929BA00EB68BF /* NotJustAnotherDither.cpp */; - name = "NotJustAnotherDither.cpp: 15"; - rLen = 392; - rLoc = 528; - rType = 0; - vrLen = 451; - vrLoc = 1431; - }; - 8B91401D213DC60B00BA6EEC /* PBXTextBookmark */ = { + 8BB9A50B24B2963800CD76A8 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 24D8286F09A914000093AEF8 /* NotJustAnotherDitherProc.cpp */; - name = "NotJustAnotherDitherProc.cpp: 73"; + name = "NotJustAnotherDitherProc.cpp: 171"; rLen = 0; - rLoc = 2713; + rLoc = 6513; rType = 0; - vrLen = 272; - vrLoc = 1671; + vrLen = 130; + vrLoc = 6449; }; - 8B91401E213DC60B00BA6EEC /* PBXTextBookmark */ = { + 8BB9A5D724B298B700CD76A8 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 24D8286F09A914000093AEF8 /* NotJustAnotherDitherProc.cpp */; - name = "NotJustAnotherDitherProc.cpp: 73"; + name = "NotJustAnotherDitherProc.cpp: 171"; rLen = 0; - rLoc = 2713; + rLoc = 6513; rType = 0; - vrLen = 272; - vrLoc = 1671; + vrLen = 68; + vrLoc = 6511; }; 8D01CCC60486CAD60068D4B7 /* NotJustAnotherDither */ = { activeExec = 0; diff --git a/plugins/MacVST/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.perspectivev3 b/plugins/MacVST/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.perspectivev3 index 0bb2bde..42e7114 100755 --- a/plugins/MacVST/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.perspectivev3 +++ b/plugins/MacVST/NotJustAnotherDither/NotJustAnotherDither.xcodeproj/christopherjohnson.perspectivev3 @@ -323,7 +323,7 @@ 258 RubberWindowFrame - 630 259 810 487 0 0 1440 878 + 17 360 810 487 0 0 1440 878 Module PBXSmartGroupTreeModule @@ -351,12 +351,11 @@ _historyCapacity 0 bookmark - 8B91401E213DC60B00BA6EEC + 8BB9A5D724B298B700CD76A8 history - 8B7E3DCF20A6735C00482CB5 - 8B7E3DD020A6735C00482CB5 - 8B91401D213DC60B00BA6EEC + 8BB9A42324B28A6700CD76A8 + 8BB9A50B24B2963800CD76A8 SplitCount @@ -370,18 +369,18 @@ GeometryConfiguration Frame - {{0, 0}, {530, 117}} + {{0, 0}, {530, 69}} RubberWindowFrame - 630 259 810 487 0 0 1440 878 + 17 360 810 487 0 0 1440 878 Module PBXNavigatorGroup Proportion - 117pt + 69pt Proportion - 324pt + 372pt Tabs @@ -395,9 +394,9 @@ GeometryConfiguration Frame - {{10, 27}, {530, 297}} + {{10, 27}, {530, 345}} RubberWindowFrame - 630 259 810 487 0 0 1440 878 + 17 360 810 487 0 0 1440 878 Module XCDetailModule @@ -451,7 +450,7 @@ GeometryConfiguration Frame - {{10, 27}, {603, 345}} + {{10, 27}, {530, 282}} Module PBXBuildResultsModule @@ -479,11 +478,11 @@ TableOfContents - 8B91401F213DC60B00BA6EEC + 8BB9A5D824B298B700CD76A8 1CA23ED40692098700951B8B - 8B914020213DC60B00BA6EEC + 8BB9A5D924B298B700CD76A8 8B0237581D42B1C400E1E8C8 - 8B914021213DC60B00BA6EEC + 8BB9A5DA24B298B700CD76A8 1CA23EDF0692099D00951B8B 1CA23EE00692099D00951B8B 1CA23EE10692099D00951B8B @@ -636,7 +635,7 @@ StatusbarIsVisible TimeStamp - 557696523.36446095 + 615684279.64847696 ToolbarConfigUserDefaultsMinorVersion 2 ToolbarDisplayMode @@ -653,11 +652,11 @@ 5 WindowOrderList - 8B914022213DC60B00BA6EEC - /Users/christopherjohnson/Desktop/MacVST/NotJustAnotherDither/NotJustAnotherDither.xcodeproj + 8BB9A5DB24B298B700CD76A8 + /Users/christopherjohnson/Desktop/NotJustAnotherDither/NotJustAnotherDither.xcodeproj WindowString - 630 259 810 487 0 0 1440 878 + 17 360 810 487 0 0 1440 878 WindowToolsV3 diff --git a/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDither.cpp b/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDither.cpp index 22a3cc7..7727b50 100755 --- a/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDither.cpp +++ b/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDither.cpp @@ -12,6 +12,9 @@ AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new N NotJustAnotherDither::NotJustAnotherDither(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, kNumPrograms, kNumParameters) { + A = 1.0; + B = 0.0; + fpd = 17; bynL[0] = 1000; bynL[1] = 301; bynL[2] = 176; @@ -58,31 +61,80 @@ void NotJustAnotherDither::getProgramName(char *name) {vst_strncpy (name, _progr //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 NotJustAnotherDither::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 NotJustAnotherDither::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 NotJustAnotherDither::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 NotJustAnotherDither::getParameter(VstInt32 index) { - return 0.0; //we only need to update the relevant name, this is simple to manage + 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 NotJustAnotherDither::getParameterName(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "Quant", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "DeRez", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this is our labels for displaying in the VST host } void NotJustAnotherDither::getParameterDisplay(VstInt32 index, char *text) { + switch (index) { + case kParamA: switch((VstInt32)( A * 1.999 )) //0 to almost edge of # of params + { case 0: vst_strncpy (text, "CD 16", kVstMaxParamStrLen); break; + case 1: vst_strncpy (text, "HD 24", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } break; //completed consoletype 'popup' parameter, exit + case kParamB: float2string (B, text, kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this displays the values and handles 'popups' where it's discrete choices } void NotJustAnotherDither::getParameterLabel(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } } VstInt32 NotJustAnotherDither::canDo(char *text) diff --git a/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDither.h b/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDither.h index 37abf4c..5ca0c0a 100755 --- a/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDither.h +++ b/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDither.h @@ -16,7 +16,9 @@ #include enum { - kNumParameters = 0 + kParamA = 0, + kParamB = 1, + kNumParameters = 2 }; // const int kNumPrograms = 0; @@ -55,7 +57,11 @@ private: double bynR[13]; long double noiseShapingL; long double noiseShapingR; - + uint32_t fpd; + //default stuff + + float A; + float B; }; #endif diff --git a/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDitherProc.cpp b/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDitherProc.cpp index cbc6cc3..1a80711 100755 --- a/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDitherProc.cpp +++ b/plugins/MacVST/NotJustAnotherDither/source/NotJustAnotherDitherProc.cpp @@ -14,237 +14,143 @@ void NotJustAnotherDither::processReplacing(float **inputs, float **outputs, Vst float* out1 = outputs[0]; float* out2 = outputs[1]; - long double inputSampleL; - long double inputSampleR; - - double benfordize; - int hotbinA; - int hotbinB; - double totalA; - double totalB; - float drySampleL; - float drySampleR; + int processing = (VstInt32)( A * 1.999 ); + bool highres = false; + if (processing == 1) highres = true; + float scaleFactor; + if (highres) scaleFactor = 8388608.0; + else scaleFactor = 32768.0; + float derez = B; + if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.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. - } - drySampleL = inputSampleL; - drySampleR = inputSampleR; + long double inputSampleL = *in1; + long double inputSampleR = *in2; + if (fabs(inputSampleL)<1.18e-37) inputSampleL = fpd * 1.18e-37; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + if (fabs(inputSampleR)<1.18e-37) inputSampleR = fpd * 1.18e-37; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + + inputSampleL *= scaleFactor; + inputSampleR *= scaleFactor; + //0-1 is now one bit, now we dither + //begin Not Just Another Dither + bool cutbinsL; cutbinsL = false; + bool cutbinsR; cutbinsR = false; + long double drySampleL; drySampleL = inputSampleL; + long double drySampleR; drySampleR = inputSampleR; inputSampleL -= noiseShapingL; inputSampleR -= noiseShapingR; - - inputSampleL *= 8388608.0; - inputSampleR *= 8388608.0; - //0-1 is now one bit, now we dither - - //begin L - 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;} - hotbinA = floor(benfordize); + + //NJAD L + long double benfordize; benfordize = floor(inputSampleL); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinA; hotbinA = floor(benfordize); //hotbin becomes the Benford bin value for this number floored - totalA = 0; + long double totalA; 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; if (bynL[hotbinA] > 982) cutbinsL = true; + 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;} + } 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;} - hotbinB = floor(benfordize); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinB; hotbinB = floor(benfordize); //hotbin becomes the Benford bin value for this number ceiled - totalB = 0; + long double totalB; 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; if (bynL[hotbinB] > 982) cutbinsL = true; + 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;} + } 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); - } + long double outputSample; + if (totalA < totalB) {bynL[hotbinA] += 1; outputSample = floor(inputSampleL);} + else {bynL[hotbinB] += 1; outputSample = floor(inputSampleL+1);} //assign the relevant one to the delay line //and floor/ceil signal accordingly + if (cutbinsL) { + bynL[1] *= 0.99; bynL[2] *= 0.99; bynL[3] *= 0.99; bynL[4] *= 0.99; bynL[5] *= 0.99; + bynL[6] *= 0.99; bynL[7] *= 0.99; bynL[8] *= 0.99; bynL[9] *= 0.99; bynL[10] *= 0.99; + } + noiseShapingL += outputSample - drySampleL; + if (noiseShapingL > fabs(inputSampleL)) noiseShapingL = fabs(inputSampleL); + if (noiseShapingL < -fabs(inputSampleL)) noiseShapingL = -fabs(inputSampleL); + //finished NJAD L - 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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 + //NJAD 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinA] > 982) cutbinsR = true; + 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;} + } 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinB] > 982) cutbinsR = true; + 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;} + } 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); - } + if (totalA < totalB) {bynR[hotbinA] += 1; outputSample = floor(inputSampleR);} + else {bynR[hotbinB] += 1; outputSample = floor(inputSampleR+1);} //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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 (cutbinsR) { + bynR[1] *= 0.99; bynR[2] *= 0.99; bynR[3] *= 0.99; bynR[4] *= 0.99; bynR[5] *= 0.99; + bynR[6] *= 0.99; bynR[7] *= 0.99; bynR[8] *= 0.99; bynR[9] *= 0.99; bynR[10] *= 0.99; + } + noiseShapingR += outputSample - drySampleR; + if (noiseShapingR > fabs(inputSampleR)) noiseShapingR = fabs(inputSampleR); + if (noiseShapingR < -fabs(inputSampleR)) noiseShapingR = -fabs(inputSampleR); + //finished NJAD R + - inputSampleL /= 8388608.0; - inputSampleR /= 8388608.0; - - noiseShapingL += inputSampleL - drySampleL; - noiseShapingR += inputSampleR - drySampleR; + inputSampleL /= outScale; + inputSampleR /= outScale; + if (inputSampleL > 1.0) inputSampleL = 1.0; + if (inputSampleL < -1.0) inputSampleL = -1.0; + if (inputSampleR > 1.0) inputSampleR = 1.0; + if (inputSampleR < -1.0) inputSampleR = -1.0; + *out1 = inputSampleL; *out2 = inputSampleR; @@ -262,237 +168,143 @@ void NotJustAnotherDither::processDoubleReplacing(double **inputs, double **outp double* out1 = outputs[0]; double* out2 = outputs[1]; - - long double inputSampleL; - long double inputSampleR; - - double benfordize; - int hotbinA; - int hotbinB; - double totalA; - double totalB; - double drySampleL; - double drySampleR; + int processing = (VstInt32)( A * 1.999 ); + bool highres = false; + if (processing == 1) highres = true; + float scaleFactor; + if (highres) scaleFactor = 8388608.0; + else scaleFactor = 32768.0; + float derez = B; + if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.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. - } - drySampleL = inputSampleL; - drySampleR = inputSampleR; - - inputSampleL -= noiseShapingL; - inputSampleR -= noiseShapingR; + long double inputSampleL = *in1; + long double inputSampleR = *in2; + if (fabs(inputSampleL)<1.18e-43) inputSampleL = fpd * 1.18e-43; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + if (fabs(inputSampleR)<1.18e-43) inputSampleR = fpd * 1.18e-43; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; - inputSampleL *= 8388608.0; - inputSampleR *= 8388608.0; + inputSampleL *= scaleFactor; + inputSampleR *= scaleFactor; //0-1 is now one bit, now we dither - //begin L - 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;} - hotbinA = floor(benfordize); + //begin Not Just Another Dither + bool cutbinsL; cutbinsL = false; + bool cutbinsR; cutbinsR = false; + long double drySampleL; drySampleL = inputSampleL; + long double drySampleR; drySampleR = inputSampleR; + inputSampleL -= noiseShapingL; + inputSampleR -= noiseShapingR; + + //NJAD L + long double benfordize; benfordize = floor(inputSampleL); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinA; hotbinA = floor(benfordize); //hotbin becomes the Benford bin value for this number floored - totalA = 0; + long double totalA; 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; if (bynL[hotbinA] > 982) cutbinsL = true; + 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;} + } 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;} - hotbinB = floor(benfordize); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinB; hotbinB = floor(benfordize); //hotbin becomes the Benford bin value for this number ceiled - totalB = 0; + long double totalB; 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; if (bynL[hotbinB] > 982) cutbinsL = true; + 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;} + } 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); - } + long double outputSampleL; + if (totalA < totalB) {bynL[hotbinA] += 1; outputSampleL = floor(inputSampleL);} + else {bynL[hotbinB] += 1; outputSampleL = floor(inputSampleL+1);} //assign the relevant one to the delay line //and floor/ceil signal accordingly + if (cutbinsL) { + bynL[1] *= 0.99; bynL[2] *= 0.99; bynL[3] *= 0.99; bynL[4] *= 0.99; bynL[5] *= 0.99; + bynL[6] *= 0.99; bynL[7] *= 0.99; bynL[8] *= 0.99; bynL[9] *= 0.99; bynL[10] *= 0.99; + } + noiseShapingL += outputSampleL - drySampleL; + if (noiseShapingL > fabs(inputSampleL)) noiseShapingL = fabs(inputSampleL); + if (noiseShapingL < -fabs(inputSampleL)) noiseShapingL = -fabs(inputSampleL); + //finished NJAD L - 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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 + //NJAD 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinA] > 982) cutbinsR = true; + 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;} + } 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinB] > 982) cutbinsR = true; + 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;} + } 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); - } + long double outputSampleR; + if (totalA < totalB) {bynR[hotbinA] += 1; outputSampleR = floor(inputSampleR);} + else {bynR[hotbinB] += 1; outputSampleR = floor(inputSampleR+1);} //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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 (cutbinsR) { + bynR[1] *= 0.99; bynR[2] *= 0.99; bynR[3] *= 0.99; bynR[4] *= 0.99; bynR[5] *= 0.99; + bynR[6] *= 0.99; bynR[7] *= 0.99; bynR[8] *= 0.99; bynR[9] *= 0.99; bynR[10] *= 0.99; + } + noiseShapingR += outputSampleR - drySampleR; + if (noiseShapingR > fabs(inputSampleR)) noiseShapingR = fabs(inputSampleR); + if (noiseShapingR < -fabs(inputSampleR)) noiseShapingR = -fabs(inputSampleR); + //finished NJAD R + - inputSampleL /= 8388608.0; - inputSampleR /= 8388608.0; + inputSampleL = outputSampleL / outScale; + inputSampleR = outputSampleR / outScale; - noiseShapingL += inputSampleL - drySampleL; - noiseShapingR += inputSampleR - drySampleR; + if (inputSampleL > 1.0) inputSampleL = 1.0; + if (inputSampleL < -1.0) inputSampleL = -1.0; + if (inputSampleR > 1.0) inputSampleR = 1.0; + if (inputSampleR < -1.0) inputSampleR = -1.0; *out1 = inputSampleL; *out2 = inputSampleR; diff --git a/plugins/WinVST/Beam/.vs/VSTProject/v14/.suo b/plugins/WinVST/Beam/.vs/VSTProject/v14/.suo index 2d36924..2822196 100755 Binary files a/plugins/WinVST/Beam/.vs/VSTProject/v14/.suo and b/plugins/WinVST/Beam/.vs/VSTProject/v14/.suo differ diff --git a/plugins/WinVST/Beam/BeamProc.cpp b/plugins/WinVST/Beam/BeamProc.cpp index 920f5b4..5871eb5 100755 --- a/plugins/WinVST/Beam/BeamProc.cpp +++ b/plugins/WinVST/Beam/BeamProc.cpp @@ -30,6 +30,8 @@ void Beam::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram float derez = C; if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; while (--sampleFrames >= 0) { @@ -121,8 +123,8 @@ void Beam::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram lastSampleR[0] = inputSampleR; //end right - inputSampleL /= scaleFactor; - inputSampleR /= scaleFactor; + inputSampleL /= outScale; + inputSampleR /= outScale; *out1 = inputSampleL; *out2 = inputSampleR; @@ -156,8 +158,10 @@ void Beam::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa else scaleFactor = 32768.0; float derez = C; if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); - if (scaleFactor < 1.0) scaleFactor = 1.0; - + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; + while (--sampleFrames >= 0) { long double inputSampleL = *in1; @@ -248,8 +252,8 @@ void Beam::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa lastSampleR[0] = inputSampleR; //end right - inputSampleL /= scaleFactor; - inputSampleR /= scaleFactor; + inputSampleL /= outScale; + inputSampleR /= outScale; *out1 = inputSampleL; *out2 = inputSampleR; diff --git a/plugins/WinVST/Dark/.vs/VSTProject/v14/.suo b/plugins/WinVST/Dark/.vs/VSTProject/v14/.suo index 54d92ad..cc5812b 100755 Binary files a/plugins/WinVST/Dark/.vs/VSTProject/v14/.suo and b/plugins/WinVST/Dark/.vs/VSTProject/v14/.suo differ diff --git a/plugins/WinVST/Dark/Dark.cpp b/plugins/WinVST/Dark/Dark.cpp index bae0428..f652aa4 100755 --- a/plugins/WinVST/Dark/Dark.cpp +++ b/plugins/WinVST/Dark/Dark.cpp @@ -14,11 +14,11 @@ Dark::Dark(audioMasterCallback audioMaster) : { A = 1.0; B = 0.0; + fpd = 17; for(int count = 0; count < 99; count++) { lastSampleL[count] = 0; lastSampleR[count] = 0; } - fpd = 17; //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. diff --git a/plugins/WinVST/Dark/DarkProc.cpp b/plugins/WinVST/Dark/DarkProc.cpp index 2aa85c4..955a53f 100755 --- a/plugins/WinVST/Dark/DarkProc.cpp +++ b/plugins/WinVST/Dark/DarkProc.cpp @@ -13,13 +13,14 @@ void Dark::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram float* in2 = inputs[1]; float* out1 = outputs[0]; float* out2 = outputs[1]; - int processing = (VstInt32)( A * 1.999 ); double overallscale = 1.0; overallscale /= 44100.0; overallscale *= getSampleRate(); int depth = (int)(17.0*overallscale); if (depth < 3) depth = 3; if (depth > 98) depth = 98; + + int processing = (VstInt32)( A * 1.999 ); bool highres = false; if (processing == 1) highres = true; float scaleFactor; @@ -28,6 +29,8 @@ void Dark::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram float derez = B; if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; while (--sampleFrames >= 0) { @@ -105,8 +108,8 @@ void Dark::processReplacing(float **inputs, float **outputs, VstInt32 sampleFram lastSampleR[0] = inputSampleR; //end right - inputSampleL /= scaleFactor; - inputSampleR /= scaleFactor; + inputSampleL /= outScale; + inputSampleR /= outScale; *out1 = inputSampleL; *out2 = inputSampleR; @@ -125,13 +128,14 @@ void Dark::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa double* out1 = outputs[0]; double* out2 = outputs[1]; - int processing = (VstInt32)( A * 1.999 ); double overallscale = 1.0; overallscale /= 44100.0; overallscale *= getSampleRate(); int depth = (int)(17.0*overallscale); if (depth < 3) depth = 3; if (depth > 98) depth = 98; + + int processing = (VstInt32)( A * 1.999 ); bool highres = false; if (processing == 1) highres = true; float scaleFactor; @@ -139,7 +143,9 @@ void Dark::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa else scaleFactor = 32768.0; float derez = B; if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); - if (scaleFactor < 1.0) scaleFactor = 1.0; + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.0; while (--sampleFrames >= 0) { @@ -217,8 +223,8 @@ void Dark::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sa lastSampleR[0] = inputSampleR; //end right - inputSampleL /= scaleFactor; - inputSampleR /= scaleFactor; + inputSampleL /= outScale; + inputSampleR /= outScale; *out1 = inputSampleL; *out2 = inputSampleR; diff --git a/plugins/WinVST/NotJustAnotherDither/.vs/VSTProject/v14/.suo b/plugins/WinVST/NotJustAnotherDither/.vs/VSTProject/v14/.suo index 0b83621..bfde065 100755 Binary files a/plugins/WinVST/NotJustAnotherDither/.vs/VSTProject/v14/.suo and b/plugins/WinVST/NotJustAnotherDither/.vs/VSTProject/v14/.suo differ diff --git a/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDither.cpp b/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDither.cpp index 22a3cc7..7727b50 100755 --- a/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDither.cpp +++ b/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDither.cpp @@ -12,6 +12,9 @@ AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new N NotJustAnotherDither::NotJustAnotherDither(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, kNumPrograms, kNumParameters) { + A = 1.0; + B = 0.0; + fpd = 17; bynL[0] = 1000; bynL[1] = 301; bynL[2] = 176; @@ -58,31 +61,80 @@ void NotJustAnotherDither::getProgramName(char *name) {vst_strncpy (name, _progr //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 NotJustAnotherDither::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 NotJustAnotherDither::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 NotJustAnotherDither::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 NotJustAnotherDither::getParameter(VstInt32 index) { - return 0.0; //we only need to update the relevant name, this is simple to manage + 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 NotJustAnotherDither::getParameterName(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "Quant", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "DeRez", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this is our labels for displaying in the VST host } void NotJustAnotherDither::getParameterDisplay(VstInt32 index, char *text) { + switch (index) { + case kParamA: switch((VstInt32)( A * 1.999 )) //0 to almost edge of # of params + { case 0: vst_strncpy (text, "CD 16", kVstMaxParamStrLen); break; + case 1: vst_strncpy (text, "HD 24", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } break; //completed consoletype 'popup' parameter, exit + case kParamB: float2string (B, text, kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } //this displays the values and handles 'popups' where it's discrete choices } void NotJustAnotherDither::getParameterLabel(VstInt32 index, char *text) { + switch (index) { + case kParamA: vst_strncpy (text, "", kVstMaxParamStrLen); break; + case kParamB: vst_strncpy (text, "", kVstMaxParamStrLen); break; + default: break; // unknown parameter, shouldn't happen! + } } VstInt32 NotJustAnotherDither::canDo(char *text) diff --git a/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDither.h b/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDither.h index 37abf4c..5ca0c0a 100755 --- a/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDither.h +++ b/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDither.h @@ -16,7 +16,9 @@ #include enum { - kNumParameters = 0 + kParamA = 0, + kParamB = 1, + kNumParameters = 2 }; // const int kNumPrograms = 0; @@ -55,7 +57,11 @@ private: double bynR[13]; long double noiseShapingL; long double noiseShapingR; - + uint32_t fpd; + //default stuff + + float A; + float B; }; #endif diff --git a/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDitherProc.cpp b/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDitherProc.cpp index cbc6cc3..1a80711 100755 --- a/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDitherProc.cpp +++ b/plugins/WinVST/NotJustAnotherDither/NotJustAnotherDitherProc.cpp @@ -14,237 +14,143 @@ void NotJustAnotherDither::processReplacing(float **inputs, float **outputs, Vst float* out1 = outputs[0]; float* out2 = outputs[1]; - long double inputSampleL; - long double inputSampleR; - - double benfordize; - int hotbinA; - int hotbinB; - double totalA; - double totalB; - float drySampleL; - float drySampleR; + int processing = (VstInt32)( A * 1.999 ); + bool highres = false; + if (processing == 1) highres = true; + float scaleFactor; + if (highres) scaleFactor = 8388608.0; + else scaleFactor = 32768.0; + float derez = B; + if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.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. - } - drySampleL = inputSampleL; - drySampleR = inputSampleR; + long double inputSampleL = *in1; + long double inputSampleR = *in2; + if (fabs(inputSampleL)<1.18e-37) inputSampleL = fpd * 1.18e-37; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + if (fabs(inputSampleR)<1.18e-37) inputSampleR = fpd * 1.18e-37; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + + inputSampleL *= scaleFactor; + inputSampleR *= scaleFactor; + //0-1 is now one bit, now we dither + //begin Not Just Another Dither + bool cutbinsL; cutbinsL = false; + bool cutbinsR; cutbinsR = false; + long double drySampleL; drySampleL = inputSampleL; + long double drySampleR; drySampleR = inputSampleR; inputSampleL -= noiseShapingL; inputSampleR -= noiseShapingR; - - inputSampleL *= 8388608.0; - inputSampleR *= 8388608.0; - //0-1 is now one bit, now we dither - - //begin L - 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;} - hotbinA = floor(benfordize); + + //NJAD L + long double benfordize; benfordize = floor(inputSampleL); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinA; hotbinA = floor(benfordize); //hotbin becomes the Benford bin value for this number floored - totalA = 0; + long double totalA; 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; if (bynL[hotbinA] > 982) cutbinsL = true; + 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;} + } 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;} - hotbinB = floor(benfordize); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinB; hotbinB = floor(benfordize); //hotbin becomes the Benford bin value for this number ceiled - totalB = 0; + long double totalB; 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; if (bynL[hotbinB] > 982) cutbinsL = true; + 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;} + } 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); - } + long double outputSample; + if (totalA < totalB) {bynL[hotbinA] += 1; outputSample = floor(inputSampleL);} + else {bynL[hotbinB] += 1; outputSample = floor(inputSampleL+1);} //assign the relevant one to the delay line //and floor/ceil signal accordingly + if (cutbinsL) { + bynL[1] *= 0.99; bynL[2] *= 0.99; bynL[3] *= 0.99; bynL[4] *= 0.99; bynL[5] *= 0.99; + bynL[6] *= 0.99; bynL[7] *= 0.99; bynL[8] *= 0.99; bynL[9] *= 0.99; bynL[10] *= 0.99; + } + noiseShapingL += outputSample - drySampleL; + if (noiseShapingL > fabs(inputSampleL)) noiseShapingL = fabs(inputSampleL); + if (noiseShapingL < -fabs(inputSampleL)) noiseShapingL = -fabs(inputSampleL); + //finished NJAD L - 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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 + //NJAD 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinA] > 982) cutbinsR = true; + 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;} + } 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinB] > 982) cutbinsR = true; + 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;} + } 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); - } + if (totalA < totalB) {bynR[hotbinA] += 1; outputSample = floor(inputSampleR);} + else {bynR[hotbinB] += 1; outputSample = floor(inputSampleR+1);} //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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 (cutbinsR) { + bynR[1] *= 0.99; bynR[2] *= 0.99; bynR[3] *= 0.99; bynR[4] *= 0.99; bynR[5] *= 0.99; + bynR[6] *= 0.99; bynR[7] *= 0.99; bynR[8] *= 0.99; bynR[9] *= 0.99; bynR[10] *= 0.99; + } + noiseShapingR += outputSample - drySampleR; + if (noiseShapingR > fabs(inputSampleR)) noiseShapingR = fabs(inputSampleR); + if (noiseShapingR < -fabs(inputSampleR)) noiseShapingR = -fabs(inputSampleR); + //finished NJAD R + - inputSampleL /= 8388608.0; - inputSampleR /= 8388608.0; - - noiseShapingL += inputSampleL - drySampleL; - noiseShapingR += inputSampleR - drySampleR; + inputSampleL /= outScale; + inputSampleR /= outScale; + if (inputSampleL > 1.0) inputSampleL = 1.0; + if (inputSampleL < -1.0) inputSampleL = -1.0; + if (inputSampleR > 1.0) inputSampleR = 1.0; + if (inputSampleR < -1.0) inputSampleR = -1.0; + *out1 = inputSampleL; *out2 = inputSampleR; @@ -262,237 +168,143 @@ void NotJustAnotherDither::processDoubleReplacing(double **inputs, double **outp double* out1 = outputs[0]; double* out2 = outputs[1]; - - long double inputSampleL; - long double inputSampleR; - - double benfordize; - int hotbinA; - int hotbinB; - double totalA; - double totalB; - double drySampleL; - double drySampleR; + int processing = (VstInt32)( A * 1.999 ); + bool highres = false; + if (processing == 1) highres = true; + float scaleFactor; + if (highres) scaleFactor = 8388608.0; + else scaleFactor = 32768.0; + float derez = B; + if (derez > 0.0) scaleFactor *= pow(1.0-derez,6); + if (scaleFactor < 0.0001) scaleFactor = 0.0001; + float outScale = scaleFactor; + if (outScale < 8.0) outScale = 8.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. - } - drySampleL = inputSampleL; - drySampleR = inputSampleR; - - inputSampleL -= noiseShapingL; - inputSampleR -= noiseShapingR; + long double inputSampleL = *in1; + long double inputSampleR = *in2; + if (fabs(inputSampleL)<1.18e-43) inputSampleL = fpd * 1.18e-43; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; + if (fabs(inputSampleR)<1.18e-43) inputSampleR = fpd * 1.18e-43; + fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5; - inputSampleL *= 8388608.0; - inputSampleR *= 8388608.0; + inputSampleL *= scaleFactor; + inputSampleR *= scaleFactor; //0-1 is now one bit, now we dither - //begin L - 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;} - hotbinA = floor(benfordize); + //begin Not Just Another Dither + bool cutbinsL; cutbinsL = false; + bool cutbinsR; cutbinsR = false; + long double drySampleL; drySampleL = inputSampleL; + long double drySampleR; drySampleR = inputSampleR; + inputSampleL -= noiseShapingL; + inputSampleR -= noiseShapingR; + + //NJAD L + long double benfordize; benfordize = floor(inputSampleL); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinA; hotbinA = floor(benfordize); //hotbin becomes the Benford bin value for this number floored - totalA = 0; + long double totalA; 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; if (bynL[hotbinA] > 982) cutbinsL = true; + 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;} + } 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;} - hotbinB = floor(benfordize); + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) benfordize *= 10; + int hotbinB; hotbinB = floor(benfordize); //hotbin becomes the Benford bin value for this number ceiled - totalB = 0; + long double totalB; 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; if (bynL[hotbinB] > 982) cutbinsL = true; + 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;} + } 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); - } + long double outputSampleL; + if (totalA < totalB) {bynL[hotbinA] += 1; outputSampleL = floor(inputSampleL);} + else {bynL[hotbinB] += 1; outputSampleL = floor(inputSampleL+1);} //assign the relevant one to the delay line //and floor/ceil signal accordingly + if (cutbinsL) { + bynL[1] *= 0.99; bynL[2] *= 0.99; bynL[3] *= 0.99; bynL[4] *= 0.99; bynL[5] *= 0.99; + bynL[6] *= 0.99; bynL[7] *= 0.99; bynL[8] *= 0.99; bynL[9] *= 0.99; bynL[10] *= 0.99; + } + noiseShapingL += outputSampleL - drySampleL; + if (noiseShapingL > fabs(inputSampleL)) noiseShapingL = fabs(inputSampleL); + if (noiseShapingL < -fabs(inputSampleL)) noiseShapingL = -fabs(inputSampleL); + //finished NJAD L - 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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 + //NJAD 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinA] > 982) cutbinsR = true; + 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;} + } 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;} + while (benfordize >= 1.0) benfordize /= 10; + while (benfordize < 1.0 && benfordize > 0.0000001) 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; if (bynR[hotbinB] > 982) cutbinsR = true; + 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;} + } 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); - } + long double outputSampleR; + if (totalA < totalB) {bynR[hotbinA] += 1; outputSampleR = floor(inputSampleR);} + else {bynR[hotbinB] += 1; outputSampleR = floor(inputSampleR+1);} //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; // spotted by Laserbat: this 'scaling back' code doesn't. It always divides by the fallback of 1. Old NJAD doesn't scale back the things we're comparing against. Kept to retain known behavior, use the one in StudioTan and Monitoring for a tuned-as-intended NJAD. - 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 (cutbinsR) { + bynR[1] *= 0.99; bynR[2] *= 0.99; bynR[3] *= 0.99; bynR[4] *= 0.99; bynR[5] *= 0.99; + bynR[6] *= 0.99; bynR[7] *= 0.99; bynR[8] *= 0.99; bynR[9] *= 0.99; bynR[10] *= 0.99; + } + noiseShapingR += outputSampleR - drySampleR; + if (noiseShapingR > fabs(inputSampleR)) noiseShapingR = fabs(inputSampleR); + if (noiseShapingR < -fabs(inputSampleR)) noiseShapingR = -fabs(inputSampleR); + //finished NJAD R + - inputSampleL /= 8388608.0; - inputSampleR /= 8388608.0; + inputSampleL = outputSampleL / outScale; + inputSampleR = outputSampleR / outScale; - noiseShapingL += inputSampleL - drySampleL; - noiseShapingR += inputSampleR - drySampleR; + if (inputSampleL > 1.0) inputSampleL = 1.0; + if (inputSampleL < -1.0) inputSampleL = -1.0; + if (inputSampleR > 1.0) inputSampleR = 1.0; + if (inputSampleR < -1.0) inputSampleR = -1.0; *out1 = inputSampleL; *out2 = inputSampleR; -- cgit v1.2.3