aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/MacVST/Ditherbox
diff options
context:
space:
mode:
authorChris Johnson <jinx6568@sover.net>2018-09-03 16:35:36 -0400
committerChris Johnson <jinx6568@sover.net>2018-09-03 16:35:36 -0400
commit3dd30d920a374ba31994f784fadd5ee130752247 (patch)
tree4a8350099d829390fc1e75234875ff76a82ec9e9 /plugins/MacVST/Ditherbox
parentb4f55328448d087a68e6f658638fb3d38d86be12 (diff)
downloadairwindows-lv2-port-3dd30d920a374ba31994f784fadd5ee130752247.tar.gz
airwindows-lv2-port-3dd30d920a374ba31994f784fadd5ee130752247.tar.bz2
airwindows-lv2-port-3dd30d920a374ba31994f784fadd5ee130752247.zip
Ditherbox update
Diffstat (limited to 'plugins/MacVST/Ditherbox')
-rwxr-xr-xplugins/MacVST/Ditherbox/Ditherbox.xcodeproj/christopherjohnson.pbxuser61
-rwxr-xr-xplugins/MacVST/Ditherbox/Ditherbox.xcodeproj/christopherjohnson.perspectivev337
-rwxr-xr-xplugins/MacVST/Ditherbox/source/Ditherbox.cpp62
-rwxr-xr-xplugins/MacVST/Ditherbox/source/Ditherbox.h2
-rwxr-xr-xplugins/MacVST/Ditherbox/source/DitherboxProc.cpp295
5 files changed, 368 insertions, 89 deletions
diff --git a/plugins/MacVST/Ditherbox/Ditherbox.xcodeproj/christopherjohnson.pbxuser b/plugins/MacVST/Ditherbox/Ditherbox.xcodeproj/christopherjohnson.pbxuser
index b36856e..fafb484 100755
--- a/plugins/MacVST/Ditherbox/Ditherbox.xcodeproj/christopherjohnson.pbxuser
+++ b/plugins/MacVST/Ditherbox/Ditherbox.xcodeproj/christopherjohnson.pbxuser
@@ -49,12 +49,13 @@
PBXFileDataSource_Warnings_ColumnID,
);
};
- PBXPerProjectTemplateStateSaveDate = 557543533;
- PBXWorkspaceStateSaveDate = 557543533;
+ PBXPerProjectTemplateStateSaveDate = 557697507;
+ PBXWorkspaceStateSaveDate = 557697507;
};
perUserProjectItems = {
- 8B39A1A1213B713000112CCA /* PBXTextBookmark */ = 8B39A1A1213B713000112CCA /* PBXTextBookmark */;
- 8B39A1A2213B713000112CCA /* PBXTextBookmark */ = 8B39A1A2213B713000112CCA /* PBXTextBookmark */;
+ 8B913F89213DBC2200BA6EEC /* PBXTextBookmark */ = 8B913F89213DBC2200BA6EEC /* PBXTextBookmark */;
+ 8B914093213DCA1600BA6EEC /* PBXTextBookmark */ = 8B914093213DCA1600BA6EEC /* PBXTextBookmark */;
+ 8B914094213DCA1600BA6EEC /* PBXTextBookmark */ = 8B914094213DCA1600BA6EEC /* PBXTextBookmark */;
};
sourceControlManager = 8B02375E1D42B1C400E1E8C8 /* Source Control */;
userBuildSettings = {
@@ -62,17 +63,17 @@
};
2407DEB6089929BA00EB68BF /* Ditherbox.cpp */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {733, 3107}}";
- sepNavSelRange = "{5938, 0}";
- sepNavVisRange = "{6518, 428}";
+ sepNavIntBoundsRect = "{{0, 0}, {558, 3757}}";
+ sepNavSelRange = "{6184, 0}";
+ sepNavVisRange = "{6556, 137}";
sepNavWindowFrame = "{{13, 47}, {895, 831}}";
};
};
245463B80991757100464AD3 /* Ditherbox.h */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {866, 1716}}";
- sepNavSelRange = "{2755, 0}";
- sepNavVisRange = "{1597, 1663}";
+ sepNavIntBoundsRect = "{{0, 0}, {866, 1573}}";
+ sepNavSelRange = "{2576, 0}";
+ sepNavVisRange = "{1102, 2059}";
sepNavWindowFrame = "{{17, 44}, {895, 831}}";
};
};
@@ -86,10 +87,10 @@
};
24D8286F09A914000093AEF8 /* DitherboxProc.cpp */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {848, 23439}}";
- sepNavSelRange = "{72139, 0}";
- sepNavVisRange = "{37029, 1848}";
- sepNavWindowFrame = "{{32, 38}, {895, 831}}";
+ sepNavIntBoundsRect = "{{0, 0}, {565, 26065}}";
+ sepNavSelRange = "{81896, 0}";
+ sepNavVisRange = "{39186, 42}";
+ sepNavWindowFrame = "{{516, 47}, {895, 831}}";
};
};
8B02375E1D42B1C400E1E8C8 /* Source Control */ = {
@@ -106,25 +107,35 @@
isa = PBXCodeSenseManager;
indexTemplatePath = "";
};
- 8B39A1A1213B713000112CCA /* PBXTextBookmark */ = {
+ 8B913F89213DBC2200BA6EEC /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
- fRef = 2407DEB6089929BA00EB68BF /* Ditherbox.cpp */;
- name = "Ditherbox.cpp: 223";
+ fRef = 24D8286F09A914000093AEF8 /* DitherboxProc.cpp */;
+ name = "DitherboxProc.cpp: 1829";
rLen = 0;
- rLoc = 5938;
+ rLoc = 81896;
rType = 0;
- vrLen = 428;
- vrLoc = 6518;
+ vrLen = 246;
+ vrLoc = 38973;
};
- 8B39A1A2213B713000112CCA /* PBXTextBookmark */ = {
+ 8B914093213DCA1600BA6EEC /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 2407DEB6089929BA00EB68BF /* Ditherbox.cpp */;
- name = "Ditherbox.cpp: 223";
+ name = "Ditherbox.cpp: 228";
+ rLen = 0;
+ rLoc = 6184;
+ rType = 0;
+ vrLen = 137;
+ vrLoc = 6556;
+ };
+ 8B914094213DCA1600BA6EEC /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 24D8286F09A914000093AEF8 /* DitherboxProc.cpp */;
+ name = "DitherboxProc.cpp: 2008";
rLen = 0;
- rLoc = 5938;
+ rLoc = 81896;
rType = 0;
- vrLen = 428;
- vrLoc = 6518;
+ vrLen = 42;
+ vrLoc = 39186;
};
8D01CCC60486CAD60068D4B7 /* Ditherbox */ = {
activeExec = 0;
diff --git a/plugins/MacVST/Ditherbox/Ditherbox.xcodeproj/christopherjohnson.perspectivev3 b/plugins/MacVST/Ditherbox/Ditherbox.xcodeproj/christopherjohnson.perspectivev3
index 4c6b162..b9f897f 100755
--- a/plugins/MacVST/Ditherbox/Ditherbox.xcodeproj/christopherjohnson.perspectivev3
+++ b/plugins/MacVST/Ditherbox/Ditherbox.xcodeproj/christopherjohnson.perspectivev3
@@ -323,7 +323,7 @@
<real>185</real>
</array>
<key>RubberWindowFrame</key>
- <string>44 351 810 487 0 0 1440 878 </string>
+ <string>34 315 810 487 0 0 1440 878 </string>
</dict>
<key>Module</key>
<string>PBXSmartGroupTreeModule</string>
@@ -339,7 +339,7 @@
<key>PBXProjectModuleGUID</key>
<string>8B0237581D42B1C400E1E8C8</string>
<key>PBXProjectModuleLabel</key>
- <string>Ditherbox.cpp</string>
+ <string>DitherboxProc.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
@@ -347,14 +347,15 @@
<key>PBXProjectModuleGUID</key>
<string>8B0237591D42B1C400E1E8C8</string>
<key>PBXProjectModuleLabel</key>
- <string>Ditherbox.cpp</string>
+ <string>DitherboxProc.cpp</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
- <string>8B39A1A2213B713000112CCA</string>
+ <string>8B914094213DCA1600BA6EEC</string>
<key>history</key>
<array>
- <string>8B39A1A1213B713000112CCA</string>
+ <string>8B914093213DCA1600BA6EEC</string>
+ <string>8B913F89213DBC2200BA6EEC</string>
</array>
</dict>
<key>SplitCount</key>
@@ -368,18 +369,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
- <string>{{0, 0}, {603, 132}}</string>
+ <string>{{0, 0}, {603, 51}}</string>
<key>RubberWindowFrame</key>
- <string>44 351 810 487 0 0 1440 878 </string>
+ <string>34 315 810 487 0 0 1440 878 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
- <string>132pt</string>
+ <string>51pt</string>
</dict>
<dict>
<key>Proportion</key>
- <string>309pt</string>
+ <string>390pt</string>
<key>Tabs</key>
<array>
<dict>
@@ -393,9 +394,9 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
- <string>{{10, 27}, {603, 282}}</string>
+ <string>{{10, 27}, {603, 363}}</string>
<key>RubberWindowFrame</key>
- <string>44 351 810 487 0 0 1440 878 </string>
+ <string>34 315 810 487 0 0 1440 878 </string>
</dict>
<key>Module</key>
<string>XCDetailModule</string>
@@ -449,7 +450,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
- <string>{{10, 27}, {603, 414}}</string>
+ <string>{{10, 27}, {603, 297}}</string>
</dict>
<key>Module</key>
<string>PBXBuildResultsModule</string>
@@ -477,11 +478,11 @@
</array>
<key>TableOfContents</key>
<array>
- <string>8B39A1A3213B713000112CCA</string>
+ <string>8B914095213DCA1600BA6EEC</string>
<string>1CA23ED40692098700951B8B</string>
- <string>8B39A1A4213B713000112CCA</string>
+ <string>8B914096213DCA1600BA6EEC</string>
<string>8B0237581D42B1C400E1E8C8</string>
- <string>8B39A1A5213B713000112CCA</string>
+ <string>8B914097213DCA1600BA6EEC</string>
<string>1CA23EDF0692099D00951B8B</string>
<string>1CA23EE00692099D00951B8B</string>
<string>1CA23EE10692099D00951B8B</string>
@@ -634,7 +635,7 @@
<key>StatusbarIsVisible</key>
<true/>
<key>TimeStamp</key>
- <real>557543728.63115299</real>
+ <real>557697558.29189706</real>
<key>ToolbarConfigUserDefaultsMinorVersion</key>
<string>2</string>
<key>ToolbarDisplayMode</key>
@@ -651,11 +652,11 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
- <string>8B39A1A6213B713000112CCA</string>
+ <string>8B914098213DCA1600BA6EEC</string>
<string>/Users/christopherjohnson/Desktop/MacVST/Ditherbox/Ditherbox.xcodeproj</string>
</array>
<key>WindowString</key>
- <string>44 351 810 487 0 0 1440 878 </string>
+ <string>34 315 810 487 0 0 1440 878 </string>
<key>WindowToolsV3</key>
<array>
<dict>
diff --git a/plugins/MacVST/Ditherbox/source/Ditherbox.cpp b/plugins/MacVST/Ditherbox/source/Ditherbox.cpp
index 7e57c49..0d3822f 100755
--- a/plugins/MacVST/Ditherbox/source/Ditherbox.cpp
+++ b/plugins/MacVST/Ditherbox/source/Ditherbox.cpp
@@ -12,11 +12,13 @@ AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {return new D
Ditherbox::Ditherbox(audioMasterCallback audioMaster) :
AudioEffectX(audioMaster, kNumPrograms, kNumParameters)
{
- A = 0.825;
+ A = 0.86;
Position = 99999999;
contingentErrL = 0.0;
contingentErrR = 0.0;
+ currentDitherL = 0.0;
+ currentDitherR = 0.0;
bynL[0] = 1000;
bynL[1] = 301;
bynL[2] = 176;
@@ -211,27 +213,33 @@ void Ditherbox::getParameterName(VstInt32 index, char *text) {
void Ditherbox::getParameterDisplay(VstInt32 index, char *text) {
switch (index) {
- case kParamA: switch((VstInt32)( A * 19.999 )) //0 to almost edge of # of params
+ case kParamA: switch((VstInt32)( A * 24.999 )) //0 to almost edge of # of params
{
case 0: vst_strncpy (text, "Trunc", kVstMaxParamStrLen); break;
case 1: vst_strncpy (text, "Flat", kVstMaxParamStrLen); break;
case 2: vst_strncpy (text, "TPDF", kVstMaxParamStrLen); break;
- case 4: vst_strncpy (text, "HiGloss", kVstMaxParamStrLen); break;
- case 5: vst_strncpy (text, "Vinyl", kVstMaxParamStrLen); break;
- case 6: vst_strncpy (text, "Spatial", kVstMaxParamStrLen); break;
- case 7: vst_strncpy (text, "Natural", kVstMaxParamStrLen); break;
- case 8: vst_strncpy (text, "NJAD", kVstMaxParamStrLen); break;
- case 9: vst_strncpy (text, "Trunc", kVstMaxParamStrLen); break;
- case 10: vst_strncpy (text, "Flat", kVstMaxParamStrLen); break;
- case 11: vst_strncpy (text, "TPDF", kVstMaxParamStrLen); break;
- case 12: vst_strncpy (text, "HiGloss", kVstMaxParamStrLen); break;
- case 13: vst_strncpy (text, "Vinyl", kVstMaxParamStrLen); break;
- case 14: vst_strncpy (text, "Spatial", kVstMaxParamStrLen); break;
- case 15: vst_strncpy (text, "Natural", kVstMaxParamStrLen); break;
- case 16: vst_strncpy (text, "NJAD", kVstMaxParamStrLen); break;
- case 17: vst_strncpy (text, "SlewOnl", kVstMaxParamStrLen); break;
- case 18: vst_strncpy (text, "SubsOnl", kVstMaxParamStrLen); break;
- case 19: vst_strncpy (text, "Silhoue", kVstMaxParamStrLen); break;
+ case 3: vst_strncpy (text, "Paul", kVstMaxParamStrLen); break;
+ case 4: vst_strncpy (text, "DbPaul", kVstMaxParamStrLen); break;
+ case 5: vst_strncpy (text, "Tape", kVstMaxParamStrLen); break;
+ case 6: vst_strncpy (text, "HiGloss", kVstMaxParamStrLen); break;
+ case 7: vst_strncpy (text, "Vinyl", kVstMaxParamStrLen); break;
+ case 8: vst_strncpy (text, "Spatial", kVstMaxParamStrLen); break;
+ case 9: vst_strncpy (text, "Natural", kVstMaxParamStrLen); break;
+ case 10: vst_strncpy (text, "NJAD", kVstMaxParamStrLen); break;
+ case 11: vst_strncpy (text, "Trunc", kVstMaxParamStrLen); break;
+ case 12: vst_strncpy (text, "Flat", kVstMaxParamStrLen); break;
+ case 13: vst_strncpy (text, "TPDF", kVstMaxParamStrLen); break;
+ case 14: vst_strncpy (text, "Paul", kVstMaxParamStrLen); break;
+ case 15: vst_strncpy (text, "DbPaul", kVstMaxParamStrLen); break;
+ case 16: vst_strncpy (text, "Tape", kVstMaxParamStrLen); break;
+ case 17: vst_strncpy (text, "HiGloss", kVstMaxParamStrLen); break;
+ case 18: vst_strncpy (text, "Vinyl", kVstMaxParamStrLen); break;
+ case 19: vst_strncpy (text, "Spatial", kVstMaxParamStrLen); break;
+ case 20: vst_strncpy (text, "Natural", kVstMaxParamStrLen); break;
+ case 21: vst_strncpy (text, "NJAD", kVstMaxParamStrLen); break;
+ case 22: vst_strncpy (text, "SlewOnl", kVstMaxParamStrLen); break;
+ case 23: vst_strncpy (text, "SubsOnl", kVstMaxParamStrLen); break;
+ case 24: vst_strncpy (text, "Silhoue", kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
} break;
default: break; // unknown parameter, shouldn't happen!
@@ -240,27 +248,33 @@ void Ditherbox::getParameterDisplay(VstInt32 index, char *text) {
void Ditherbox::getParameterLabel(VstInt32 index, char *text) {
switch (index) {
- case kParamA: switch((VstInt32)( A * 19.999 )) //0 to almost edge of # of params
+ case kParamA: switch((VstInt32)( A * 24.999 )) //0 to almost edge of # of params
{
case 0: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
case 1: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
case 2: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
+ case 3: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
case 4: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
case 5: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
case 6: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
case 7: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
case 8: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
- case 9: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
- case 10: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
+ case 9: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
+ case 10: vst_strncpy (text, "16", kVstMaxParamStrLen); break;
case 11: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
case 12: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
case 13: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
case 14: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
case 15: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
case 16: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
- case 17: vst_strncpy (text, "y", kVstMaxParamStrLen); break;
- case 18: vst_strncpy (text, "y", kVstMaxParamStrLen); break;
- case 19: vst_strncpy (text, "tte", kVstMaxParamStrLen); break;
+ case 17: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
+ case 18: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
+ case 19: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
+ case 20: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
+ case 21: vst_strncpy (text, "24", kVstMaxParamStrLen); break;
+ case 22: vst_strncpy (text, "y", kVstMaxParamStrLen); break;
+ case 23: vst_strncpy (text, "y", kVstMaxParamStrLen); break;
+ case 24: vst_strncpy (text, "tte", kVstMaxParamStrLen); break;
default: break; // unknown parameter, shouldn't happen!
} break;
default: break; // unknown parameter, shouldn't happen!
diff --git a/plugins/MacVST/Ditherbox/source/Ditherbox.h b/plugins/MacVST/Ditherbox/source/Ditherbox.h
index baf5bb1..fa54082 100755
--- a/plugins/MacVST/Ditherbox/source/Ditherbox.h
+++ b/plugins/MacVST/Ditherbox/source/Ditherbox.h
@@ -58,6 +58,8 @@ private:
long double noiseShapingR;
double contingentErrL;
double contingentErrR;
+ double currentDitherL;
+ double currentDitherR;
int Position;
bool flip;
double NSOddL;
diff --git a/plugins/MacVST/Ditherbox/source/DitherboxProc.cpp b/plugins/MacVST/Ditherbox/source/DitherboxProc.cpp
index feb5874..4115687 100755
--- a/plugins/MacVST/Ditherbox/source/DitherboxProc.cpp
+++ b/plugins/MacVST/Ditherbox/source/DitherboxProc.cpp
@@ -14,7 +14,7 @@ void Ditherbox::processReplacing(float **inputs, float **outputs, VstInt32 sampl
float* out1 = outputs[0];
float* out2 = outputs[1];
- int dtype = (int)(A * 19.999); // +1 for Reaper bug workaround
+ int dtype = (int)(A * 24.999)+1; // +1 for Reaper bug workaround
long double overallscale = 1.0;
overallscale /= 44100.0;
overallscale *= getSampleRate();
@@ -42,14 +42,52 @@ void Ditherbox::processReplacing(float **inputs, float **outputs, VstInt32 sampl
long double trim = 2.302585092994045684017991; //natural logarithm of 10
bool highRes = false;
bool dithering = true;
- if (dtype > 8){highRes = true; dtype -= 8;}
- if (dtype > 8){dithering = false; highRes = false;}
+ if (dtype > 11){highRes = true; dtype -= 11;}
+ if (dtype > 11){dithering = false; highRes = false;}
//follow up by switching high res back off for the monitoring
while (--sampleFrames >= 0)
{
long double inputSampleL = *in1;
long double inputSampleR = *in2;
+ if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) {
+ static int noisesource = 0;
+ //this declares a variable before anything else is compiled. It won't keep assigning
+ //it to 0 for every sample, it's as if the declaration doesn't exist in this context,
+ //but it lets me add this denormalization fix in a single place rather than updating
+ //it in three different locations. The variable isn't thread-safe but this is only
+ //a random seed and we can share it with whatever.
+ noisesource = noisesource % 1700021; noisesource++;
+ int residue = noisesource * noisesource;
+ residue = residue % 170003; residue *= residue;
+ residue = residue % 17011; residue *= residue;
+ residue = residue % 1709; residue *= residue;
+ residue = residue % 173; residue *= residue;
+ residue = residue % 17;
+ double applyresidue = residue;
+ applyresidue *= 0.00000001;
+ applyresidue *= 0.00000001;
+ inputSampleL = applyresidue;
+ }
+ if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) {
+ static int noisesource = 0;
+ noisesource = noisesource % 1700021; noisesource++;
+ int residue = noisesource * noisesource;
+ residue = residue % 170003; residue *= residue;
+ residue = residue % 17011; residue *= residue;
+ residue = residue % 1709; residue *= residue;
+ residue = residue % 173; residue *= residue;
+ residue = residue % 17;
+ double applyresidue = residue;
+ applyresidue *= 0.00000001;
+ applyresidue *= 0.00000001;
+ inputSampleR = applyresidue;
+ //this denormalization routine produces a white noise at -300 dB which the noise
+ //shaping will interact with to produce a bipolar output, but the noise is actually
+ //all positive. That should stop any variables from going denormal, and the routine
+ //only kicks in if digital black is input. As a final touch, if you save to 24-bit
+ //the silence will return to being digital black again.
+ }
float drySampleL = inputSampleL;
float drySampleR = inputSampleR;
@@ -89,7 +127,95 @@ void Ditherbox::processReplacing(float **inputs, float **outputs, VstInt32 sampl
//TPDF dither
break;
- case 4:
+ case 4:
+ currentDitherL = (rand()/(double)RAND_MAX);
+ inputSampleL += currentDitherL;
+ inputSampleL -= lastSampleL;
+ inputSampleL = floor(inputSampleL);
+ lastSampleL = currentDitherL;
+ currentDitherR = (rand()/(double)RAND_MAX);
+ inputSampleR += currentDitherR;
+ inputSampleR -= lastSampleR;
+ inputSampleR = floor(inputSampleR);
+ lastSampleR = currentDitherR;
+ //Paul dither
+ break;
+
+ case 5:
+ nsL[9] = nsL[8]; nsL[8] = nsL[7]; nsL[7] = nsL[6]; nsL[6] = nsL[5];
+ nsL[5] = nsL[4]; nsL[4] = nsL[3]; nsL[3] = nsL[2]; nsL[2] = nsL[1];
+ nsL[1] = nsL[0]; nsL[0] = (rand()/(double)RAND_MAX);
+
+ currentDitherL = (nsL[0] * 0.061);
+ currentDitherL -= (nsL[1] * 0.11);
+ currentDitherL += (nsL[8] * 0.126);
+ currentDitherL -= (nsL[7] * 0.23);
+ currentDitherL += (nsL[2] * 0.25);
+ currentDitherL -= (nsL[3] * 0.43);
+ currentDitherL += (nsL[6] * 0.5);
+ currentDitherL -= nsL[5];
+ currentDitherL += nsL[4];
+ //this sounds different from doing it in order of sample position
+ //cumulative tiny errors seem to build up even at this buss depth
+ //considerably more pronounced at 32 bit float.
+ //Therefore we add the most significant components LAST.
+ //trying to keep values on like exponents of the floating point value.
+ inputSampleL += currentDitherL;
+
+ inputSampleL = floor(inputSampleL);
+ //done with L
+
+ nsR[9] = nsR[8]; nsR[8] = nsR[7]; nsR[7] = nsR[6]; nsR[6] = nsR[5];
+ nsR[5] = nsR[4]; nsR[4] = nsR[3]; nsR[3] = nsR[2]; nsR[2] = nsR[1];
+ nsR[1] = nsR[0]; nsR[0] = (rand()/(double)RAND_MAX);
+
+ currentDitherR = (nsR[0] * 0.061);
+ currentDitherR -= (nsR[1] * 0.11);
+ currentDitherR += (nsR[8] * 0.126);
+ currentDitherR -= (nsR[7] * 0.23);
+ currentDitherR += (nsR[2] * 0.25);
+ currentDitherR -= (nsR[3] * 0.43);
+ currentDitherR += (nsR[6] * 0.5);
+ currentDitherR -= nsR[5];
+ currentDitherR += nsR[4];
+ //this sounds different from doing it in order of sample position
+ //cumulative tiny errors seem to build up even at this buss depth
+ //considerably more pronounced at 32 bit float.
+ //Therefore we add the most significant components LAST.
+ //trying to keep values on like exponents of the floating point value.
+ inputSampleR += currentDitherR;
+
+ inputSampleR = floor(inputSampleR);
+ //done with R
+
+ //DoublePaul dither
+ break;
+
+ case 6:
+ currentDitherL = (rand()/(double)RAND_MAX);
+ currentDitherR = (rand()/(double)RAND_MAX);
+
+ inputSampleL += currentDitherL;
+ inputSampleR += currentDitherR;
+ inputSampleL -= nsL[4];
+ inputSampleR -= nsR[4];
+
+ inputSampleL = floor(inputSampleL);
+ inputSampleR = floor(inputSampleR);
+
+ nsL[4] = nsL[3];
+ nsL[3] = nsL[2];
+ nsL[2] = nsL[1];
+ nsL[1] = currentDitherL;
+
+ nsR[4] = nsR[3];
+ nsR[3] = nsR[2];
+ nsR[2] = nsR[1];
+ nsR[1] = currentDitherR;
+ //Tape dither
+ break;
+
+ case 7:
Position += 1;
//Note- uses integer overflow as a 'mod' operator
hotbinA = Position * Position;
@@ -111,7 +237,7 @@ void Ditherbox::processReplacing(float **inputs, float **outputs, VstInt32 sampl
//Quadratic dither
break;
- case 5:
+ case 8:
absSample = ((rand()/(double)RAND_MAX) - 0.5);
nsL[0] += absSample; nsL[0] /= 2; absSample -= nsL[0];
absSample += ((rand()/(double)RAND_MAX) - 0.5);
@@ -206,7 +332,7 @@ void Ditherbox::processReplacing(float **inputs, float **outputs, VstInt32 sampl
//TenNines dither R
break;
- case 6:
+ case 9:
if (inputSampleL > 0) inputSampleL += 0.383;
if (inputSampleL < 0) inputSampleL -= 0.383;
if (inputSampleR > 0) inputSampleR += 0.383;
@@ -246,7 +372,7 @@ void Ditherbox::processReplacing(float **inputs, float **outputs, VstInt32 sampl
//and does a teeny parallel-compression thing when almost at digital black.
break;
- case 7: //this one is the original Naturalize
+ case 10: //this one is the original Naturalize
if (inputSampleL > 0) inputSampleL += (0.3333333333);
if (inputSampleL < 0) inputSampleL -= (0.3333333333);
inputSampleL += (rand()/(double)RAND_MAX)*0.6666666666;
@@ -406,7 +532,7 @@ void Ditherbox::processReplacing(float **inputs, float **outputs, VstInt32 sampl
//end R
break;
- case 8: //this one is the Not Just Another Dither
+ case 11: //this one is the Not Just Another Dither
//begin L
benfordize = floor(inputSampleL);
@@ -571,7 +697,7 @@ void Ditherbox::processReplacing(float **inputs, float **outputs, VstInt32 sampl
//end R
break;
- case 9:
+ case 12:
//slew only
outputSampleL = (inputSampleL - lastSampleL)*trim;
outputSampleR = (inputSampleR - lastSampleR)*trim;
@@ -585,7 +711,7 @@ void Ditherbox::processReplacing(float **inputs, float **outputs, VstInt32 sampl
inputSampleR = outputSampleR;
break;
- case 10:
+ case 13:
//subs only
gain = gaintarget;
@@ -801,7 +927,7 @@ void Ditherbox::processReplacing(float **inputs, float **outputs, VstInt32 sampl
if (inputSampleR < -1.0) inputSampleR = -1.0;
break;
- case 11:
+ case 14:
//silhouette
//begin L
bridgerectifier = fabs(inputSampleL)*1.57079633;
@@ -893,7 +1019,7 @@ void Ditherbox::processDoubleReplacing(double **inputs, double **outputs, VstInt
double* out1 = outputs[0];
double* out2 = outputs[1];
- int dtype = (int)(A * 19.999); // +1 for Reaper bug workaround
+ int dtype = (int)(A * 24.999)+1; // +1 for Reaper bug workaround
long double overallscale = 1.0;
overallscale /= 44100.0;
overallscale *= getSampleRate();
@@ -921,14 +1047,52 @@ void Ditherbox::processDoubleReplacing(double **inputs, double **outputs, VstInt
long double trim = 2.302585092994045684017991; //natural logarithm of 10
bool highRes = false;
bool dithering = true;
- if (dtype > 8){highRes = true; dtype -= 8;}
- if (dtype > 8){dithering = false; highRes = false;}
+ if (dtype > 11){highRes = true; dtype -= 11;}
+ if (dtype > 11){dithering = false; highRes = false;}
//follow up by switching high res back off for the monitoring
while (--sampleFrames >= 0)
{
long double inputSampleL = *in1;
long double inputSampleR = *in2;
+ if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) {
+ static int noisesource = 0;
+ //this declares a variable before anything else is compiled. It won't keep assigning
+ //it to 0 for every sample, it's as if the declaration doesn't exist in this context,
+ //but it lets me add this denormalization fix in a single place rather than updating
+ //it in three different locations. The variable isn't thread-safe but this is only
+ //a random seed and we can share it with whatever.
+ noisesource = noisesource % 1700021; noisesource++;
+ int residue = noisesource * noisesource;
+ residue = residue % 170003; residue *= residue;
+ residue = residue % 17011; residue *= residue;
+ residue = residue % 1709; residue *= residue;
+ residue = residue % 173; residue *= residue;
+ residue = residue % 17;
+ double applyresidue = residue;
+ applyresidue *= 0.00000001;
+ applyresidue *= 0.00000001;
+ inputSampleL = applyresidue;
+ }
+ if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) {
+ static int noisesource = 0;
+ noisesource = noisesource % 1700021; noisesource++;
+ int residue = noisesource * noisesource;
+ residue = residue % 170003; residue *= residue;
+ residue = residue % 17011; residue *= residue;
+ residue = residue % 1709; residue *= residue;
+ residue = residue % 173; residue *= residue;
+ residue = residue % 17;
+ double applyresidue = residue;
+ applyresidue *= 0.00000001;
+ applyresidue *= 0.00000001;
+ inputSampleR = applyresidue;
+ //this denormalization routine produces a white noise at -300 dB which the noise
+ //shaping will interact with to produce a bipolar output, but the noise is actually
+ //all positive. That should stop any variables from going denormal, and the routine
+ //only kicks in if digital black is input. As a final touch, if you save to 24-bit
+ //the silence will return to being digital black again.
+ }
double drySampleL = inputSampleL;
double drySampleR = inputSampleR;
@@ -968,7 +1132,94 @@ void Ditherbox::processDoubleReplacing(double **inputs, double **outputs, VstInt
//TPDF dither
break;
- case 4:
+ case 4:
+ currentDitherL = (rand()/(double)RAND_MAX);
+ inputSampleL += currentDitherL;
+ inputSampleL -= lastSampleL;
+ inputSampleL = floor(inputSampleL);
+ lastSampleL = currentDitherL;
+ currentDitherR = (rand()/(double)RAND_MAX);
+ inputSampleR += currentDitherR;
+ inputSampleR -= lastSampleR;
+ inputSampleR = floor(inputSampleR);
+ lastSampleR = currentDitherR;
+ //Paul dither
+ break;
+
+ case 5:
+ nsL[9] = nsL[8]; nsL[8] = nsL[7]; nsL[7] = nsL[6]; nsL[6] = nsL[5];
+ nsL[5] = nsL[4]; nsL[4] = nsL[3]; nsL[3] = nsL[2]; nsL[2] = nsL[1];
+ nsL[1] = nsL[0]; nsL[0] = (rand()/(double)RAND_MAX);
+
+ currentDitherL = (nsL[0] * 0.061);
+ currentDitherL -= (nsL[1] * 0.11);
+ currentDitherL += (nsL[8] * 0.126);
+ currentDitherL -= (nsL[7] * 0.23);
+ currentDitherL += (nsL[2] * 0.25);
+ currentDitherL -= (nsL[3] * 0.43);
+ currentDitherL += (nsL[6] * 0.5);
+ currentDitherL -= nsL[5];
+ currentDitherL += nsL[4];
+ //this sounds different from doing it in order of sample position
+ //cumulative tiny errors seem to build up even at this buss depth
+ //considerably more pronounced at 32 bit float.
+ //Therefore we add the most significant components LAST.
+ //trying to keep values on like exponents of the floating point value.
+ inputSampleL += currentDitherL;
+
+ inputSampleL = floor(inputSampleL);
+ //done with L
+
+ nsR[9] = nsR[8]; nsR[8] = nsR[7]; nsR[7] = nsR[6]; nsR[6] = nsR[5];
+ nsR[5] = nsR[4]; nsR[4] = nsR[3]; nsR[3] = nsR[2]; nsR[2] = nsR[1];
+ nsR[1] = nsR[0]; nsR[0] = (rand()/(double)RAND_MAX);
+
+ currentDitherR = (nsR[0] * 0.061);
+ currentDitherR -= (nsR[1] * 0.11);
+ currentDitherR += (nsR[8] * 0.126);
+ currentDitherR -= (nsR[7] * 0.23);
+ currentDitherR += (nsR[2] * 0.25);
+ currentDitherR -= (nsR[3] * 0.43);
+ currentDitherR += (nsR[6] * 0.5);
+ currentDitherR -= nsR[5];
+ currentDitherR += nsR[4];
+ //this sounds different from doing it in order of sample position
+ //cumulative tiny errors seem to build up even at this buss depth
+ //considerably more pronounced at 32 bit float.
+ //Therefore we add the most significant components LAST.
+ //trying to keep values on like exponents of the floating point value.
+ inputSampleR += currentDitherR;
+
+ inputSampleR = floor(inputSampleR);
+ //done with R
+ //DoublePaul dither
+ break;
+
+ case 6:
+ currentDitherL = (rand()/(double)RAND_MAX);
+ currentDitherR = (rand()/(double)RAND_MAX);
+
+ inputSampleL += currentDitherL;
+ inputSampleR += currentDitherR;
+ inputSampleL -= nsL[4];
+ inputSampleR -= nsR[4];
+
+ inputSampleL = floor(inputSampleL);
+ inputSampleR = floor(inputSampleR);
+
+ nsL[4] = nsL[3];
+ nsL[3] = nsL[2];
+ nsL[2] = nsL[1];
+ nsL[1] = currentDitherL;
+
+ nsR[4] = nsR[3];
+ nsR[3] = nsR[2];
+ nsR[2] = nsR[1];
+ nsR[1] = currentDitherR;
+ //Tape dither
+ break;
+
+ case 7:
Position += 1;
//Note- uses integer overflow as a 'mod' operator
hotbinA = Position * Position;
@@ -990,7 +1241,7 @@ void Ditherbox::processDoubleReplacing(double **inputs, double **outputs, VstInt
//Quadratic dither
break;
- case 5:
+ case 8:
absSample = ((rand()/(double)RAND_MAX) - 0.5);
nsL[0] += absSample; nsL[0] /= 2; absSample -= nsL[0];
absSample += ((rand()/(double)RAND_MAX) - 0.5);
@@ -1085,7 +1336,7 @@ void Ditherbox::processDoubleReplacing(double **inputs, double **outputs, VstInt
//TenNines dither R
break;
- case 6:
+ case 9:
if (inputSampleL > 0) inputSampleL += 0.383;
if (inputSampleL < 0) inputSampleL -= 0.383;
if (inputSampleR > 0) inputSampleR += 0.383;
@@ -1125,7 +1376,7 @@ void Ditherbox::processDoubleReplacing(double **inputs, double **outputs, VstInt
//and does a teeny parallel-compression thing when almost at digital black.
break;
- case 7: //this one is the original Naturalize
+ case 10: //this one is the original Naturalize
if (inputSampleL > 0) inputSampleL += (0.3333333333);
if (inputSampleL < 0) inputSampleL -= (0.3333333333);
inputSampleL += (rand()/(double)RAND_MAX)*0.6666666666;
@@ -1285,7 +1536,7 @@ void Ditherbox::processDoubleReplacing(double **inputs, double **outputs, VstInt
//end R
break;
- case 8: //this one is the Not Just Another Dither
+ case 11: //this one is the Not Just Another Dither
//begin L
benfordize = floor(inputSampleL);
@@ -1450,7 +1701,7 @@ void Ditherbox::processDoubleReplacing(double **inputs, double **outputs, VstInt
//end R
break;
- case 9:
+ case 12:
//slew only
outputSampleL = (inputSampleL - lastSampleL)*trim;
outputSampleR = (inputSampleR - lastSampleR)*trim;
@@ -1464,7 +1715,7 @@ void Ditherbox::processDoubleReplacing(double **inputs, double **outputs, VstInt
inputSampleR = outputSampleR;
break;
- case 10:
+ case 13:
//subs only
gain = gaintarget;
@@ -1680,7 +1931,7 @@ void Ditherbox::processDoubleReplacing(double **inputs, double **outputs, VstInt
if (inputSampleR < -1.0) inputSampleR = -1.0;
break;
- case 11:
+ case 14:
//silhouette
//begin L
bridgerectifier = fabs(inputSampleL)*1.57079633;