aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/MacAU/Ditherbox/Ditherbox.cpp
diff options
context:
space:
mode:
authorChris Johnson <jinx6568@sover.net>2018-09-02 22:35:13 -0400
committerChris Johnson <jinx6568@sover.net>2018-09-02 22:35:13 -0400
commitb4f55328448d087a68e6f658638fb3d38d86be12 (patch)
tree217a6d4c9ecc1c34e15e3f9e3774cc9858e39bfa /plugins/MacAU/Ditherbox/Ditherbox.cpp
parentdea49efc0e05cdd55c00ce701aecef2bd742fc8c (diff)
downloadairwindows-lv2-port-b4f55328448d087a68e6f658638fb3d38d86be12.tar.gz
airwindows-lv2-port-b4f55328448d087a68e6f658638fb3d38d86be12.tar.bz2
airwindows-lv2-port-b4f55328448d087a68e6f658638fb3d38d86be12.zip
Ditherbox… and individual dithers
Diffstat (limited to 'plugins/MacAU/Ditherbox/Ditherbox.cpp')
-rwxr-xr-xplugins/MacAU/Ditherbox/Ditherbox.cpp754
1 files changed, 754 insertions, 0 deletions
diff --git a/plugins/MacAU/Ditherbox/Ditherbox.cpp b/plugins/MacAU/Ditherbox/Ditherbox.cpp
new file mode 100755
index 0000000..6cd002b
--- /dev/null
+++ b/plugins/MacAU/Ditherbox/Ditherbox.cpp
@@ -0,0 +1,754 @@
+/*
+* File: Ditherbox.cpp
+*
+* Version: 1.0
+*
+* Created: 1/1/09
+*
+* Copyright: Copyright © 2009 Airwindows, All Rights Reserved
+*
+* Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
+* consideration of your agreement to the following terms, and your use, installation, modification
+* or redistribution of this Apple software constitutes acceptance of these terms. If you do
+* not agree with these terms, please do not use, install, modify or redistribute this Apple
+* software.
+*
+* In consideration of your agreement to abide by the following terms, and subject to these terms,
+* Apple grants you a personal, non-exclusive license, under Apple's copyrights in this
+* original Apple software (the "Apple Software"), to use, reproduce, modify and redistribute the
+* Apple Software, with or without modifications, in source and/or binary forms; provided that if you
+* redistribute the Apple Software in its entirety and without modifications, you must retain this
+* notice and the following text and disclaimers in all such redistributions of the Apple Software.
+* Neither the name, trademarks, service marks or logos of Apple Computer, Inc. may be used to
+* endorse or promote products derived from the Apple Software without specific prior written
+* permission from Apple. Except as expressly stated in this notice, no other rights or
+* licenses, express or implied, are granted by Apple herein, including but not limited to any
+* patent rights that may be infringed by your derivative works or by other works in which the
+* Apple Software may be incorporated.
+*
+* The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR
+* IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY
+* AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE
+* OR IN COMBINATION WITH YOUR PRODUCTS.
+*
+* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
+* REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER
+* UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN
+* IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+/*=============================================================================
+ Ditherbox.h
+
+=============================================================================*/
+#include "Ditherbox.h"
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+COMPONENT_ENTRY(Ditherbox)
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Ditherbox::Ditherbox
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Ditherbox::Ditherbox(AudioUnit component)
+ : AUEffectBase(component)
+{
+ CreateElements();
+ Globals()->UseIndexedParameters(kNumberOfParameters);
+ SetParameter(kParam_One, kDefaultValue_ParamOne );
+
+#if AU_DEBUG_DISPATCHER
+ mDebugDispatcher = new AUDebugDispatcher (this);
+#endif
+
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Ditherbox::GetParameterValueStrings
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ComponentResult Ditherbox::GetParameterValueStrings(AudioUnitScope inScope,
+ 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_Truncate,
+ kMenuItem_Flat,
+ kMenuItem_TPDF,
+ kMenuItem_Quadratic,
+ kMenuItem_TenNines,
+ kMenuItem_Contingent,
+ kMenuItem_Naturalize,
+ kMenuItem_NJAD,
+ kMenuItem_TruncateHR,
+ kMenuItem_FlatHR,
+ kMenuItem_TPDFHR,
+ kMenuItem_QuadraticHR,
+ kMenuItem_TenNinesHR,
+ kMenuItem_ContingentHR,
+ kMenuItem_NaturalizeHR,
+ kMenuItem_NJADHR,
+ kMenuItem_SlewOnly,
+ kMenuItem_SubsOnly,
+ kMenuItem_Silhouette,
+ };
+ *outStrings = CFArrayCreate (
+ NULL,
+ (const void **) strings,
+ (sizeof (strings) / sizeof (strings [0])),
+ NULL
+ );
+ return noErr;
+ }
+ return kAudioUnitErr_InvalidProperty;
+}
+
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Ditherbox::GetParameterInfo
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ComponentResult Ditherbox::GetParameterInfo(AudioUnitScope inScope,
+ AudioUnitParameterID inParameterID,
+ AudioUnitParameterInfo &outParameterInfo )
+{
+ ComponentResult result = noErr;
+
+ outParameterInfo.flags = kAudioUnitParameterFlag_IsWritable
+ | kAudioUnitParameterFlag_IsReadable;
+
+ if (inScope == kAudioUnitScope_Global) {
+ switch(inParameterID)
+ {
+ case kParam_One:
+ AUBase::FillInParameterName (outParameterInfo, kParameterOneName, false);
+ outParameterInfo.unit = kAudioUnitParameterUnit_Indexed;
+ outParameterInfo.minValue = kTruncate;
+ outParameterInfo.maxValue = kSilhouette;
+ outParameterInfo.defaultValue = kDefaultValue_ParamOne;
+ break;
+ default:
+ result = kAudioUnitErr_InvalidParameter;
+ break;
+ }
+ } else {
+ result = kAudioUnitErr_InvalidParameter;
+ }
+
+
+
+ return result;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Ditherbox::GetPropertyInfo
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ComponentResult Ditherbox::GetPropertyInfo (AudioUnitPropertyID inID,
+ AudioUnitScope inScope,
+ AudioUnitElement inElement,
+ UInt32 & outDataSize,
+ Boolean & outWritable)
+{
+ return AUEffectBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Ditherbox::GetProperty
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ComponentResult Ditherbox::GetProperty( AudioUnitPropertyID inID,
+ AudioUnitScope inScope,
+ AudioUnitElement inElement,
+ void * outData )
+{
+ return AUEffectBase::GetProperty (inID, inScope, inElement, outData);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Ditherbox::Initialize
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ComponentResult Ditherbox::Initialize()
+{
+ ComponentResult result = AUEffectBase::Initialize();
+ if (result == noErr)
+ Reset(kAudioUnitScope_Global, 0);
+ return result;
+}
+
+#pragma mark ____DitherboxEffectKernel
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Ditherbox::DitherboxKernel::Reset()
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void Ditherbox::DitherboxKernel::Reset()
+{
+ Position = 99999999;
+ contingentErr = 0.0;
+ 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;
+ noiseShaping = 0.0;
+ NSOdd = 0.0;
+ NSEven = 0.0;
+ prev = 0.0;
+ ns[0] = 0;
+ ns[1] = 0;
+ ns[2] = 0;
+ ns[3] = 0;
+ ns[4] = 0;
+ ns[5] = 0;
+ ns[6] = 0;
+ ns[7] = 0;
+ ns[8] = 0;
+ ns[9] = 0;
+ ns[10] = 0;
+ ns[11] = 0;
+ ns[12] = 0;
+ ns[13] = 0;
+ ns[14] = 0;
+ ns[15] = 0;
+ lastSample = 0.0;
+ outSample = 0.0;
+ iirSampleA = 0.0;
+ iirSampleB = 0.0;
+ iirSampleC = 0.0;
+ iirSampleD = 0.0;
+ iirSampleE = 0.0;
+ iirSampleF = 0.0;
+ iirSampleG = 0.0;
+ iirSampleH = 0.0;
+ iirSampleI = 0.0;
+ iirSampleJ = 0.0;
+ iirSampleK = 0.0;
+ iirSampleL = 0.0;
+ iirSampleM = 0.0;
+ iirSampleN = 0.0;
+ iirSampleO = 0.0;
+ iirSampleP = 0.0;
+ iirSampleQ = 0.0;
+ iirSampleR = 0.0;
+ iirSampleS = 0.0;
+ iirSampleT = 0.0;
+ iirSampleU = 0.0;
+ iirSampleV = 0.0;
+ iirSampleW = 0.0;
+ iirSampleX = 0.0;
+ iirSampleY = 0.0;
+ iirSampleZ = 0.0;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Ditherbox::DitherboxKernel::Process
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+void Ditherbox::DitherboxKernel::Process( const Float32 *inSourceP,
+ Float32 *inDestP,
+ UInt32 inFramesToProcess,
+ UInt32 inNumChannels, // for version 2 AudioUnits inNumChannels is always 1
+ bool &ioSilence )
+{
+
+
+ UInt32 nSampleFrames = inFramesToProcess;
+ const Float32 *sourceP = inSourceP;
+ Float32 *destP = inDestP;
+ long double contingentRnd;
+ long double absSample;
+ long double contingent;
+ long double overallscale = 1.0;
+ overallscale /= 44100.0;
+ overallscale *= GetSampleRate();
+ long double iirAmount = 2250/44100.0;
+ long double gaintarget = 1.42;
+ long double gain;
+ iirAmount /= overallscale;
+ long double altAmount = 1.0 - iirAmount;
+ long double inputSample;
+ long double outputSample;
+ long double silhouette;
+ long double smoother;
+ long double bridgerectifier;
+ long double benfordize;
+ int hotbinA;
+ int hotbinB;
+ long double totalA;
+ long double totalB;
+ long double randyConstant = 1.61803398874989484820458683436563811772030917980576;
+ long double omegaConstant = 0.56714329040978387299996866221035554975381578718651;
+ long double expConstant = 0.06598803584531253707679018759684642493857704825279;
+ long double trim = 2.302585092994045684017991; //natural logarithm of 10
+ int dtype = (int) GetParameter( kParam_One ); // +1 for Reaper bug workaround
+ bool highRes = false;
+ bool dithering = true;
+
+ Float32 drySample; //should be the same as what the native DAW buss is
+
+ if (dtype > 8){highRes = true; dtype -= 8;}
+
+ if (dtype > 8){dithering = false; highRes = false;}
+ //follow up by switching high res back off for the monitoring
+
+ while (nSampleFrames-- > 0) {
+ drySample = inputSample = *sourceP;
+ sourceP += inNumChannels;
+
+ if (dtype == 8) inputSample -= noiseShaping;
+
+ if (dithering) inputSample *= 32768.0;
+ //denormalizing as way of controlling insane detail boosting
+ if (highRes) inputSample *= 256.0; //256 for 16/24 version
+
+ switch (dtype)
+ {
+ case 1:
+ inputSample = floor(inputSample);
+ //truncate
+ break;
+
+ case 2:
+ inputSample += (rand()/(double)RAND_MAX);
+ inputSample -= 0.5;
+ inputSample = floor(inputSample);
+ //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:
+ Position += 1;
+ //Note- uses integer overflow as a 'mod' operator
+ hotbinA = Position * Position;
+ hotbinA = hotbinA % 170003; //% is C++ mod operator
+ hotbinA *= hotbinA;
+ hotbinA = hotbinA % 17011; //% is C++ mod operator
+ hotbinA *= hotbinA;
+ hotbinA = hotbinA % 1709; //% is C++ mod operator
+ hotbinA *= hotbinA;
+ hotbinA = hotbinA % 173; //% is C++ mod operator
+ hotbinA *= hotbinA;
+ hotbinA = hotbinA % 17;
+ hotbinA *= 0.0635;
+ if (flip) hotbinA = -hotbinA;
+ inputSample += hotbinA;
+ inputSample = floor(inputSample);
+ //Quadratic dither
+ break;
+
+ case 5:
+ absSample = ((rand()/(double)RAND_MAX) - 0.5);
+ ns[0] += absSample; ns[0] /= 2; absSample -= ns[0];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[1] += absSample; ns[1] /= 2; absSample -= ns[1];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[2] += absSample; ns[2] /= 2; absSample -= ns[2];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[3] += absSample; ns[3] /= 2; absSample -= ns[3];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[4] += absSample; ns[4] /= 2; absSample -= ns[4];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[5] += absSample; ns[5] /= 2; absSample -= ns[5];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[6] += absSample; ns[6] /= 2; absSample -= ns[6];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[7] += absSample; ns[7] /= 2; absSample -= ns[7];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[8] += absSample; ns[8] /= 2; absSample -= ns[8];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[9] += absSample; ns[9] /= 2; absSample -= ns[9];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[10] += absSample; ns[10] /= 2; absSample -= ns[10];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[11] += absSample; ns[11] /= 2; absSample -= ns[11];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[12] += absSample; ns[12] /= 2; absSample -= ns[12];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[13] += absSample; ns[13] /= 2; absSample -= ns[13];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[14] += absSample; ns[14] /= 2; absSample -= ns[14];
+ absSample += ((rand()/(double)RAND_MAX) - 0.5);
+ ns[15] += absSample; ns[15] /= 2; absSample -= ns[15];
+ //install noise and then shape it
+ absSample += inputSample;
+
+ //NSOdd /= 1.0001; //NSDensity
+
+ if (NSOdd > 0) NSOdd -= 0.97;
+ if (NSOdd < 0) NSOdd += 0.97;
+
+ NSOdd -= (NSOdd * NSOdd * NSOdd * 0.475);
+
+ NSOdd += prev;
+ absSample += (NSOdd*0.475);
+ prev = floor(absSample) - inputSample;
+ inputSample = floor(absSample);
+ //TenNines dither
+ break;
+
+ case 6:
+ if (inputSample > 0) inputSample += 0.383;
+ if (inputSample < 0) inputSample -= 0.383;
+ //adjusting to permit more information drug outta the noisefloor
+ contingentRnd = (((rand()/(double)RAND_MAX)+(rand()/(double)RAND_MAX))-1.0) * randyConstant; //produce TPDF dist, scale
+ contingentRnd -= contingentErr*omegaConstant; //include err
+ absSample = fabs(inputSample);
+ contingentErr = absSample - floor(absSample); //get next err
+ contingent = contingentErr * 2.0; //scale of quantization levels
+ if (contingent > 1.0) contingent = ((-contingent+2.0)*omegaConstant) + expConstant;
+ else contingent = (contingent * omegaConstant) + expConstant;
+ //zero is next to a quantization level, one is exactly between them
+ if (flip) contingentRnd = (contingentRnd * (1.0-contingent)) + contingent + 0.5;
+ else contingentRnd = (contingentRnd * (1.0-contingent)) - contingent + 0.5;
+ inputSample += (contingentRnd * contingent);
+ //Contingent Dither
+ inputSample = floor(inputSample);
+ //note: this does not dither for values exactly the same as 16 bit values-
+ //which forces the dither to gate at 0.0. It goes to digital black,
+ //and does a teeny parallel-compression thing when almost at digital black.
+ break;
+
+ case 7:
+ if (inputSample > 0) inputSample += (0.3333333333);
+ if (inputSample < 0) inputSample -= (0.3333333333);
+
+ inputSample += (rand()/(double)RAND_MAX)*0.6666666666;
+
+ benfordize = floor(inputSample);
+ while (benfordize >= 1.0) {benfordize /= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ if (benfordize < 1.0) {benfordize *= 10;}
+ hotbinA = floor(benfordize);
+ //hotbin becomes the Benford bin value for this number floored
+ totalA = 0;
+ if ((hotbinA > 0) && (hotbinA < 10))
+ {
+ 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;
+ } 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;}
+ hotbinB = floor(benfordize);
+ //hotbin becomes the Benford bin value for this number ceiled
+ 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;
+ } 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);
+ }
+ //assign the relevant one to the delay line
+ //and floor/ceil signal accordingly
+
+ 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;
+ 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
+ break;
+
+ case 8: //this one is the Not Just Another 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);
+ //hotbin becomes the Benford bin value for this number floored
+ 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;
+ } 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);
+ //hotbin becomes the Benford bin value for this number ceiled
+ 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;
+ } 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);
+ }
+ //assign the relevant one to the delay line
+ //and floor/ceil signal accordingly
+
+ 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;
+ 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
+ break;
+
+ case 9:
+ //slew only
+ outputSample = (inputSample - lastSample)*trim;
+ lastSample = inputSample;
+ if (outputSample > 1.0) outputSample = 1.0;
+ if (outputSample < -1.0) outputSample = -1.0;
+ inputSample = outputSample;
+ break;
+
+ case 10:
+ //subs only
+ gain = gaintarget;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ iirSampleA = (iirSampleA * altAmount) + (inputSample * iirAmount); inputSample = iirSampleA;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleB = (iirSampleB * altAmount) + (inputSample * iirAmount); inputSample = iirSampleB;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleC = (iirSampleC * altAmount) + (inputSample * iirAmount); inputSample = iirSampleC;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleD = (iirSampleD * altAmount) + (inputSample * iirAmount); inputSample = iirSampleD;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleE = (iirSampleE * altAmount) + (inputSample * iirAmount); inputSample = iirSampleE;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleF = (iirSampleF * altAmount) + (inputSample * iirAmount); inputSample = iirSampleF;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleG = (iirSampleG * altAmount) + (inputSample * iirAmount); inputSample = iirSampleG;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleH = (iirSampleH * altAmount) + (inputSample * iirAmount); inputSample = iirSampleH;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleI = (iirSampleI * altAmount) + (inputSample * iirAmount); inputSample = iirSampleI;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleJ = (iirSampleJ * altAmount) + (inputSample * iirAmount); inputSample = iirSampleJ;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleK = (iirSampleK * altAmount) + (inputSample * iirAmount); inputSample = iirSampleK;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleL = (iirSampleL * altAmount) + (inputSample * iirAmount); inputSample = iirSampleL;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleM = (iirSampleM * altAmount) + (inputSample * iirAmount); inputSample = iirSampleM;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleN = (iirSampleN * altAmount) + (inputSample * iirAmount); inputSample = iirSampleN;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleO = (iirSampleO * altAmount) + (inputSample * iirAmount); inputSample = iirSampleO;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleP = (iirSampleP * altAmount) + (inputSample * iirAmount); inputSample = iirSampleP;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleQ = (iirSampleQ * altAmount) + (inputSample * iirAmount); inputSample = iirSampleQ;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleR = (iirSampleR * altAmount) + (inputSample * iirAmount); inputSample = iirSampleR;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleS = (iirSampleS * altAmount) + (inputSample * iirAmount); inputSample = iirSampleS;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleT = (iirSampleT * altAmount) + (inputSample * iirAmount); inputSample = iirSampleT;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleU = (iirSampleU * altAmount) + (inputSample * iirAmount); inputSample = iirSampleU;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleV = (iirSampleV * altAmount) + (inputSample * iirAmount); inputSample = iirSampleV;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleW = (iirSampleW * altAmount) + (inputSample * iirAmount); inputSample = iirSampleW;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleX = (iirSampleX * altAmount) + (inputSample * iirAmount); inputSample = iirSampleX;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleY = (iirSampleY * altAmount) + (inputSample * iirAmount); inputSample = iirSampleY;
+ inputSample *= gain; gain = ((gain-1)*0.75)+1;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ iirSampleZ = (iirSampleZ * altAmount) + (inputSample * iirAmount); inputSample = iirSampleZ;
+ if (inputSample > 1.0) inputSample = 1.0;
+ if (inputSample < -1.0) inputSample = -1.0;
+ break;
+
+ case 11:
+ //silhouette
+ bridgerectifier = fabs(inputSample)*1.57079633;
+ if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633;
+ bridgerectifier = 1.0-cos(bridgerectifier);
+ if (inputSample > 0.0) inputSample = bridgerectifier;
+ else inputSample = -bridgerectifier;
+
+ silhouette = rand()/(double)RAND_MAX;
+ silhouette -= 0.5;
+ silhouette *= 2.0;
+ silhouette *= fabs(inputSample);
+
+ smoother = rand()/(double)RAND_MAX;
+ smoother -= 0.5;
+ smoother *= 2.0;
+ smoother *= fabs(lastSample);
+ lastSample = inputSample;
+
+ silhouette += smoother;
+
+ bridgerectifier = fabs(silhouette)*1.57079633;
+ if (bridgerectifier > 1.57079633) bridgerectifier = 1.57079633;
+ bridgerectifier = sin(bridgerectifier);
+ if (silhouette > 0.0) silhouette = bridgerectifier;
+ else silhouette = -bridgerectifier;
+
+ inputSample = (silhouette + outSample) / 2.0;
+ outSample = silhouette;
+ break;
+ }
+
+ flip = !flip;
+ //several dithers use this
+ if (highRes) inputSample /= 256.0; //256 for 16/24 version
+ if (dithering) inputSample /= 32768.0;
+
+ if (dtype == 8) noiseShaping += inputSample - drySample;
+
+ *destP = inputSample;
+ destP += inNumChannels;
+ }
+}
+