blob: 28c4385a1c2febb48ca8156cee24a0e7673e4e6e (
plain) (
tree)
|
|
/* ========================================
* NotJustAnotherCD - NotJustAnotherCD.h
* Copyright (c) 2016 airwindows, All rights reserved
* ======================================== */
#ifndef __NotJustAnotherCD_H
#include "NotJustAnotherCD.h"
#endif
void NotJustAnotherCD::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames)
{
float* in1 = inputs[0];
float* in2 = inputs[1];
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;
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;
inputSampleL *= 32768.0;
inputSampleR *= 32768.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);
//hotbin becomes the Benford bin value for this number floored
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;
} 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);
//hotbin becomes the Benford bin value for this number ceiled
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;
} 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);
}
//assign the relevant one to the delay line
//and floor/ceil signal accordingly
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;
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
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;}
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;
} 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;}
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;
} 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);
}
//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;
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
inputSampleL /= 32768.0;
inputSampleR /= 32768.0;
noiseShapingL += inputSampleL - drySampleL;
noiseShapingR += inputSampleR - drySampleR;
*out1 = inputSampleL;
*out2 = inputSampleR;
*in1++;
*in2++;
*out1++;
*out2++;
}
}
void NotJustAnotherCD::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames)
{
double* in1 = inputs[0];
double* in2 = inputs[1];
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;
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;
inputSampleL *= 32768.0;
inputSampleR *= 32768.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);
//hotbin becomes the Benford bin value for this number floored
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;
} 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);
//hotbin becomes the Benford bin value for this number ceiled
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;
} 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);
}
//assign the relevant one to the delay line
//and floor/ceil signal accordingly
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;
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
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;}
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;
} 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;}
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;
} 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);
}
//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;
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
inputSampleL /= 32768.0;
inputSampleR /= 32768.0;
noiseShapingL += inputSampleL - drySampleL;
noiseShapingR += inputSampleR - drySampleR;
*out1 = inputSampleL;
*out2 = inputSampleR;
*in1++;
*in2++;
*out1++;
*out2++;
}
}
|