diff options
author | Chris Johnson <jinx6568@sover.net> | 2018-09-03 16:35:36 -0400 |
---|---|---|
committer | Chris Johnson <jinx6568@sover.net> | 2018-09-03 16:35:36 -0400 |
commit | 3dd30d920a374ba31994f784fadd5ee130752247 (patch) | |
tree | 4a8350099d829390fc1e75234875ff76a82ec9e9 /plugins/MacAU/Ditherbox/Ditherbox.cpp | |
parent | b4f55328448d087a68e6f658638fb3d38d86be12 (diff) | |
download | airwindows-lv2-port-3dd30d920a374ba31994f784fadd5ee130752247.tar.gz airwindows-lv2-port-3dd30d920a374ba31994f784fadd5ee130752247.tar.bz2 airwindows-lv2-port-3dd30d920a374ba31994f784fadd5ee130752247.zip |
Ditherbox update
Diffstat (limited to 'plugins/MacAU/Ditherbox/Ditherbox.cpp')
-rwxr-xr-x | plugins/MacAU/Ditherbox/Ditherbox.cpp | 118 |
1 files changed, 98 insertions, 20 deletions
diff --git a/plugins/MacAU/Ditherbox/Ditherbox.cpp b/plugins/MacAU/Ditherbox/Ditherbox.cpp index 6cd002b..a4b1edf 100755 --- a/plugins/MacAU/Ditherbox/Ditherbox.cpp +++ b/plugins/MacAU/Ditherbox/Ditherbox.cpp @@ -83,6 +83,9 @@ ComponentResult Ditherbox::GetParameterValueStrings(AudioUnitScope inScope, kMenuItem_Truncate, kMenuItem_Flat, kMenuItem_TPDF, + kMenuItem_Paul, + kMenuItem_DoublePaul, + kMenuItem_Tape, kMenuItem_Quadratic, kMenuItem_TenNines, kMenuItem_Contingent, @@ -91,6 +94,9 @@ ComponentResult Ditherbox::GetParameterValueStrings(AudioUnitScope inScope, kMenuItem_TruncateHR, kMenuItem_FlatHR, kMenuItem_TPDFHR, + kMenuItem_PaulHR, + kMenuItem_DoublePaulHR, + kMenuItem_TapeHR, kMenuItem_QuadraticHR, kMenuItem_TenNinesHR, kMenuItem_ContingentHR, @@ -298,13 +304,39 @@ void Ditherbox::DitherboxKernel::Process( const Float32 *inSourceP, Float32 drySample; //should be the same as what the native DAW buss is - if (dtype > 8){highRes = true; dtype -= 8;} + if (dtype > 11){highRes = true; dtype -= 11;} - if (dtype > 8){dithering = false; highRes = false;} + if (dtype > 11){dithering = false; highRes = false;} //follow up by switching high res back off for the monitoring while (nSampleFrames-- > 0) { - drySample = inputSample = *sourceP; + 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; + sourceP += inNumChannels; if (dtype == 8) inputSample -= noiseShaping; @@ -327,16 +359,62 @@ void Ditherbox::DitherboxKernel::Process( const Float32 *inSourceP, //flat dither break; - case 3: - inputSample += (rand()/(double)RAND_MAX); - inputSample += (rand()/(double)RAND_MAX); - inputSample -= 1.0; - inputSample = floor(inputSample); - //TPDF dither - break; - - - case 4: + case 3: + inputSample += (rand()/(double)RAND_MAX); + inputSample += (rand()/(double)RAND_MAX); + inputSample -= 1.0; + inputSample = floor(inputSample); + //TPDF dither + break; + + case 4: + currentDither = (rand()/(double)RAND_MAX); + inputSample += currentDither; + inputSample -= lastSample; + inputSample = floor(inputSample); + lastSample = currentDither; + //Paul dither + break; + + case 5: + ns[9] = ns[8]; ns[8] = ns[7]; ns[7] = ns[6]; ns[6] = ns[5]; + ns[5] = ns[4]; ns[4] = ns[3]; ns[3] = ns[2]; ns[2] = ns[1]; + ns[1] = ns[0]; ns[0] = (rand()/(double)RAND_MAX); + + currentDither = (ns[0] * 0.061); + currentDither -= (ns[1] * 0.11); + currentDither += (ns[8] * 0.126); + currentDither -= (ns[7] * 0.23); + currentDither += (ns[2] * 0.25); + currentDither -= (ns[3] * 0.43); + currentDither += (ns[6] * 0.5); + currentDither -= ns[5]; + currentDither += ns[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. + inputSample += currentDither; + + inputSample = floor(inputSample); + //DoublePaul dither + break; + + case 6: + currentDither = (rand()/(double)RAND_MAX); + inputSample += currentDither; + inputSample -= ns[4]; + inputSample = floor(inputSample); + ns[4] = ns[3]; + ns[3] = ns[2]; + ns[2] = ns[1]; + ns[1] = currentDither; + //Tape dither + break; + + + case 7: Position += 1; //Note- uses integer overflow as a 'mod' operator hotbinA = Position * Position; @@ -356,7 +434,7 @@ void Ditherbox::DitherboxKernel::Process( const Float32 *inSourceP, //Quadratic dither break; - case 5: + case 8: absSample = ((rand()/(double)RAND_MAX) - 0.5); ns[0] += absSample; ns[0] /= 2; absSample -= ns[0]; absSample += ((rand()/(double)RAND_MAX) - 0.5); @@ -406,7 +484,7 @@ void Ditherbox::DitherboxKernel::Process( const Float32 *inSourceP, //TenNines dither break; - case 6: + case 9: if (inputSample > 0) inputSample += 0.383; if (inputSample < 0) inputSample -= 0.383; //adjusting to permit more information drug outta the noisefloor @@ -428,7 +506,7 @@ void Ditherbox::DitherboxKernel::Process( const Float32 *inSourceP, //and does a teeny parallel-compression thing when almost at digital black. break; - case 7: + case 10: if (inputSample > 0) inputSample += (0.3333333333); if (inputSample < 0) inputSample -= (0.3333333333); @@ -508,7 +586,7 @@ void Ditherbox::DitherboxKernel::Process( const Float32 *inSourceP, byn[10] /= 2; //catchall for garbage data break; - case 8: //this one is the Not Just Another Dither + case 11: //this one is the Not Just Another Dither benfordize = floor(inputSample); while (benfordize >= 1.0) {benfordize /= 10;} @@ -590,7 +668,7 @@ void Ditherbox::DitherboxKernel::Process( const Float32 *inSourceP, byn[10] /= 2; //catchall for garbage data break; - case 9: + case 12: //slew only outputSample = (inputSample - lastSample)*trim; lastSample = inputSample; @@ -599,7 +677,7 @@ void Ditherbox::DitherboxKernel::Process( const Float32 *inSourceP, inputSample = outputSample; break; - case 10: + case 13: //subs only gain = gaintarget; inputSample *= gain; gain = ((gain-1)*0.75)+1; @@ -708,7 +786,7 @@ void Ditherbox::DitherboxKernel::Process( const Float32 *inSourceP, if (inputSample < -1.0) inputSample = -1.0; break; - case 11: + case 14: //silhouette bridgerectifier = fabs(inputSample)*1.57079633; if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633; |