mirror of
https://github.com/airwindows/airwindows.git
synced 2026-05-15 14:16:00 -06:00
Srsly3
This commit is contained in:
parent
04874c800b
commit
59635ea5d9
43 changed files with 6200 additions and 1319 deletions
|
|
@ -39,7 +39,7 @@ Reverb: Galactic3, kCathedral3, CreamCoat, kPlateD, kPlateB, kPlateA, kPlateC, C
|
|||
|
||||
Saturation: Creature, Huge, NCSeventeen, Tube2, Tube, Spiral2, PurestDrive, Focus, Mojo, Dyno, Spiral, UnBox, Desk4, Righteous4
|
||||
|
||||
Stereo: Srsly, Srsly2, Wider, StereoFX, ToVinyl4, AutoPan, LRFlipTimer, MSFlipTimer, Sidepass, SideDull
|
||||
Stereo: Srsly3, Srsly2, Srsly, Wider, StereoFX, ToVinyl4, AutoPan, LRFlipTimer, MSFlipTimer, Sidepass, SideDull
|
||||
|
||||
Subtlety: Discontinuity, Hype, Shape, Inflamer, Sweeten, PurestWarm2, PurestWarm, Coils2, Interstage, PhaseNudge, Remap, SingleEndedTriode, Coils, Desk, TransDesk, TubeDesk
|
||||
|
||||
|
|
@ -4189,6 +4189,18 @@ But. But. BUT. What I was asked for, was to accomplish a particular effect, wher
|
|||
|
||||
That’s my hope, anyhow. Hope you like it! I know I’ll be using it on stuff.
|
||||
|
||||
############ Srsly3 is Srsly2, with a Nonlin control to analogify the filters.
|
||||
|
||||
Those who are familiar with Airwindows know that Srsly is a sort of take on a famous stereo processor, the Hughes SRS. The first version, Srsly, uses a bank of very tight resonant filters to adjust space psychoacoustically and simulate the sound of ambience around human ears (based on illustrations that ran in Popular Mechanics). The second, Srsly2, took that and added aggressive mid/side processing to more closely resemble existing SRS boxes, thanks to a Crate SRS box I was able to get by way of example.
|
||||
|
||||
Srsly3 is the same thing as Srsly2, except all those filters are replaced with the kinds of biquad filter found in Airwindows BiquadNonlin. That's the one where I figured out how to apply the filter modulating used in Capacitor2, which simulates nonlinearity in cutoff frequency of ceramic capacitors (specifically Murata capacitors made of barium titanate), but applied to biquad filters which are a lot more adaptable than Capacitor was.
|
||||
|
||||
You don't have to understand any of that, it's just the way I got to this result.
|
||||
|
||||
It means you get a Nonlin control, where setting it to 0 means you have Srsly2 again. And then when you turn it up, especially when you have your filters at a higher Q setting (sharper resonances), the filters get modulated by the voltage pressures they themselves see from the signal passing through. And it fuzzes them out in a way that makes Srsly3 sound more analog than it's ever sounded before, with more of a vibe and texture to the vivid stereo sounds it can make.
|
||||
|
||||
I would say play with it and see what kinds of settings sound good to you. And if you liked Srsly2 and found it useful, now you've got this which starts where Srsly2 left off, and then takes it to new places. BiquadNonLin really sounds most interesting on tight resonant peaks, which is what Srsly is made out of, so with a bit of luck this will really click for Srsly enjoyers. Hope you like it!
|
||||
|
||||
############ StarChild is a weird digital ambience/echo plugin.
|
||||
|
||||
For all that we try to make plugins have natural, acoustic or electric, retro vibe qualities, sometimes there’s a thing which breaks the rules by creating a distinctive voice that has nothing to do with naturalness. I’ve got an old Alesis reverb like that: very primitive, but deep as anything. There have always been odd little boxes with a style all their own, like the Delta Labs Effectron, which is low-fi but uses delta-sigma modulation like an SACD (but much more crudely!)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ Mastering::Mastering(audioMasterCallback audioMaster) :
|
|||
G = 0.5;
|
||||
H = 0.5;
|
||||
I = 0.0;
|
||||
J = 1.0;
|
||||
|
||||
for (int x = 0; x < air_total; x++) air[x] = 0.0;
|
||||
for (int x = 0; x < kal_total; x++) {kalM[x] = 0.0;kalS[x] = 0.0;}
|
||||
|
|
@ -36,6 +37,62 @@ Mastering::Mastering(audioMasterCallback audioMaster) :
|
|||
wasNegClipR = false;
|
||||
for (int x = 0; x < 16; x++) {intermediateL[x] = 0.0; intermediateR[x] = 0.0;}
|
||||
|
||||
quantA = 0;
|
||||
quantB = 1;
|
||||
expectedSlew = 0.0;
|
||||
testA = 0.0;
|
||||
testB = 0.0;
|
||||
correction = 0.0;
|
||||
shapedSampleL = 0.0;
|
||||
shapedSampleR = 0.0;
|
||||
currentDither = 0.0;
|
||||
ditherL = 0.0;
|
||||
ditherR = 0.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
hotbinA = 0;
|
||||
hotbinB = 0;
|
||||
benfordize = 0.0;
|
||||
totalA = 0.0;
|
||||
totalB = 0.0;
|
||||
outputSample = 0.0;
|
||||
expon = 0; //internal dither variables
|
||||
//these didn't like to be defined inside a case statement
|
||||
|
||||
NSOddL = 0.0; NSEvenL = 0.0; prevShapeL = 0.0;
|
||||
NSOddR = 0.0; NSEvenR = 0.0; prevShapeR = 0.0;
|
||||
flip = true; //Ten Nines
|
||||
for(int count = 0; count < 99; count++) {
|
||||
darkSampleL[count] = 0;
|
||||
darkSampleR[count] = 0;
|
||||
} //Dark
|
||||
previousDitherL = 0.0;
|
||||
previousDitherR = 0.0; //PaulWide
|
||||
bynL[0] = 1000.0;
|
||||
bynL[1] = 301.0;
|
||||
bynL[2] = 176.0;
|
||||
bynL[3] = 125.0;
|
||||
bynL[4] = 97.0;
|
||||
bynL[5] = 79.0;
|
||||
bynL[6] = 67.0;
|
||||
bynL[7] = 58.0;
|
||||
bynL[8] = 51.0;
|
||||
bynL[9] = 46.0;
|
||||
bynL[10] = 1000.0;
|
||||
noiseShapingL = 0.0;
|
||||
bynR[0] = 1000.0;
|
||||
bynR[1] = 301.0;
|
||||
bynR[2] = 176.0;
|
||||
bynR[3] = 125.0;
|
||||
bynR[4] = 97.0;
|
||||
bynR[5] = 79.0;
|
||||
bynR[6] = 67.0;
|
||||
bynR[7] = 58.0;
|
||||
bynR[8] = 51.0;
|
||||
bynR[9] = 46.0;
|
||||
bynR[10] = 1000.0;
|
||||
noiseShapingR = 0.0; //NJAD
|
||||
|
||||
fpdL = 1.0; while (fpdL < 16386) fpdL = rand()*UINT32_MAX;
|
||||
fpdR = 1.0; while (fpdR < 16386) fpdR = rand()*UINT32_MAX;
|
||||
//this is reset: values being initialized only once. Startup values, whatever they are.
|
||||
|
|
@ -78,6 +135,7 @@ VstInt32 Mastering::getChunk (void** data, bool isPreset)
|
|||
chunkData[6] = G;
|
||||
chunkData[7] = H;
|
||||
chunkData[8] = I;
|
||||
chunkData[9] = J;
|
||||
/* 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. */
|
||||
|
|
@ -98,6 +156,7 @@ VstInt32 Mastering::setChunk (void* data, VstInt32 byteSize, bool isPreset)
|
|||
G = pinParameter(chunkData[6]);
|
||||
H = pinParameter(chunkData[7]);
|
||||
I = pinParameter(chunkData[8]);
|
||||
J = pinParameter(chunkData[9]);
|
||||
/* We're ignoring byteSize as we found it to be a filthy liar */
|
||||
|
||||
/* calculate any other fields you need here - you could copy in
|
||||
|
|
@ -116,6 +175,7 @@ void Mastering::setParameter(VstInt32 index, float value) {
|
|||
case kParamG: G = value; break;
|
||||
case kParamH: H = value; break;
|
||||
case kParamI: I = value; break;
|
||||
case kParamJ: J = value; break;
|
||||
default: throw; // unknown parameter, shouldn't happen!
|
||||
}
|
||||
}
|
||||
|
|
@ -131,6 +191,7 @@ float Mastering::getParameter(VstInt32 index) {
|
|||
case kParamG: return G; break;
|
||||
case kParamH: return H; break;
|
||||
case kParamI: return I; break;
|
||||
case kParamJ: return J; break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} return 0.0; //we only need to update the relevant name, this is simple to manage
|
||||
}
|
||||
|
|
@ -146,6 +207,7 @@ void Mastering::getParameterName(VstInt32 index, char *text) {
|
|||
case kParamG: vst_strncpy (text, "Zoom", kVstMaxParamStrLen); break;
|
||||
case kParamH: vst_strncpy (text, "DarkF", kVstMaxParamStrLen); break;
|
||||
case kParamI: vst_strncpy (text, "Ratio", kVstMaxParamStrLen); break;
|
||||
case kParamJ: vst_strncpy (text, "Dither", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} //this is our labels for displaying in the VST host
|
||||
}
|
||||
|
|
@ -161,6 +223,15 @@ void Mastering::getParameterDisplay(VstInt32 index, char *text) {
|
|||
case kParamG: float2string (G, text, kVstMaxParamStrLen); break;
|
||||
case kParamH: float2string (H, text, kVstMaxParamStrLen); break;
|
||||
case kParamI: float2string (I, text, kVstMaxParamStrLen); break;
|
||||
case kParamJ: switch((VstInt32)( J * 5.999 )) //0 to almost edge of # of params
|
||||
{ case 0: vst_strncpy (text, "Dark", kVstMaxParamStrLen); break;
|
||||
case 1: vst_strncpy (text, "TenNines", kVstMaxParamStrLen); break;
|
||||
case 2: vst_strncpy (text, "TPDFWde", kVstMaxParamStrLen); break;
|
||||
case 3: vst_strncpy (text, "PaulWde", kVstMaxParamStrLen); break;
|
||||
case 4: vst_strncpy (text, "NJAD", kVstMaxParamStrLen); break;
|
||||
case 5: vst_strncpy (text, "Bypass", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} break; //completed consoletype 'popup' parameter, exit
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} //this displays the values and handles 'popups' where it's discrete choices
|
||||
}
|
||||
|
|
@ -176,6 +247,7 @@ void Mastering::getParameterLabel(VstInt32 index, char *text) {
|
|||
case kParamG: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamH: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamI: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamJ: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ enum {
|
|||
kParamG =6,
|
||||
kParamH =7,
|
||||
kParamI =8,
|
||||
kNumParameters = 9
|
||||
kParamJ =9,
|
||||
kNumParameters = 10
|
||||
}; //
|
||||
|
||||
const int kNumPrograms = 0;
|
||||
|
|
@ -69,6 +70,7 @@ private:
|
|||
float G;
|
||||
float H;
|
||||
float I;
|
||||
float J;
|
||||
|
||||
enum {
|
||||
pvAL1,
|
||||
|
|
@ -151,6 +153,41 @@ private:
|
|||
bool wasPosClipR;
|
||||
bool wasNegClipR; //Stereo ClipOnly2
|
||||
|
||||
int quantA;
|
||||
int quantB;
|
||||
float expectedSlew;
|
||||
float testA;
|
||||
float testB;
|
||||
double correction;
|
||||
double shapedSampleL;
|
||||
double shapedSampleR;
|
||||
double currentDither;
|
||||
double ditherL;
|
||||
double ditherR;
|
||||
bool cutbinsL;
|
||||
bool cutbinsR;
|
||||
int hotbinA;
|
||||
int hotbinB;
|
||||
double benfordize;
|
||||
double totalA;
|
||||
double totalB;
|
||||
double outputSample;
|
||||
int expon; //internal dither variables
|
||||
|
||||
double NSOddL; //dither section!
|
||||
double NSEvenL;
|
||||
double prevShapeL;
|
||||
double NSOddR;
|
||||
double NSEvenR;
|
||||
double prevShapeR;
|
||||
bool flip; //VinylDither
|
||||
double darkSampleL[100];
|
||||
double darkSampleR[100]; //Dark
|
||||
double previousDitherL;
|
||||
double previousDitherR; //PaulWide
|
||||
double bynL[13], bynR[13];
|
||||
double noiseShapingL, noiseShapingR; //NJAD
|
||||
|
||||
uint32_t fpdL;
|
||||
uint32_t fpdR;
|
||||
//default stuff
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ void Mastering::processReplacing(float **inputs, float **outputs, VstInt32 sampl
|
|||
double depthSinew = I;
|
||||
int spacing = floor(overallscale); //should give us working basic scaling, usually 2 or 4
|
||||
if (spacing < 1) spacing = 1; if (spacing > 16) spacing = 16;
|
||||
int dither = (int) ( J * 5.999 )+1;
|
||||
int depth = (int)(17.0*overallscale);
|
||||
if (depth < 3) depth = 3;
|
||||
if (depth > 98) depth = 98; //for Dark
|
||||
|
||||
while (--sampleFrames >= 0)
|
||||
{
|
||||
|
|
@ -270,14 +274,388 @@ void Mastering::processReplacing(float **inputs, float **outputs, VstInt32 sampl
|
|||
inputSampleR = (inputSampleR * (1.0-depthSinew))+(lastSinewR*depthSinew);
|
||||
//run Sinew to stop excess slews, but run a dry/wet to allow a range of brights
|
||||
|
||||
//begin 32 bit stereo floating point dither
|
||||
int expon; frexpf((float)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
frexpf((float)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit stereo floating point dither
|
||||
|
||||
switch (dither) {
|
||||
case 1:
|
||||
//begin Dark
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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
|
||||
quantA = floor(inputSampleL);
|
||||
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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark 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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark right
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Dark (Monitoring2)
|
||||
case 2:
|
||||
//begin Dark for Ten Nines
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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 L
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddL = (NSOddL * 0.9999999999) + prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) - prevShapeL;
|
||||
correction = NSOddL;
|
||||
} else {
|
||||
NSOddL = (NSOddL * 0.9999999999) - prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) + prevShapeL;
|
||||
correction = NSEvenL;
|
||||
}
|
||||
shapedSampleL = inputSampleL+correction;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin Dark L
|
||||
quantA = floor(shapedSampleL);
|
||||
quantB = floor(shapedSampleL+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark L
|
||||
|
||||
prevShapeL = (floor(shapedSampleL) - inputSampleL)*0.9999999999;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin R
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddR = (NSOddR * 0.9999999999) + prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) - prevShapeR;
|
||||
correction = NSOddR;
|
||||
} else {
|
||||
NSOddR = (NSOddR * 0.9999999999) - prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) + prevShapeR;
|
||||
correction = NSEvenR;
|
||||
}
|
||||
shapedSampleR = inputSampleR+correction;
|
||||
//end Ten Nines R
|
||||
|
||||
//begin Dark R
|
||||
quantA = floor(shapedSampleR);
|
||||
quantB = floor(shapedSampleR+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark R
|
||||
|
||||
prevShapeR = (floor(shapedSampleR) - inputSampleR)*0.9999999999;
|
||||
//end Ten Nines
|
||||
flip = !flip;
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Ten Nines (which goes into Dark in Monitoring3)
|
||||
case 3:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //TPDFWide (a good neutral with the width enhancement)
|
||||
case 4:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
//Paul Frindle: It's true that the dither itself can sound different
|
||||
//if it's given a different freq response and you get to hear it.
|
||||
//The one we use most is triangular single pole high pass dither.
|
||||
//It's not freq bent enough to sound odd, but is slightly less audible than
|
||||
//flat dither. It can also be easily made by taking one sample of dither
|
||||
//away from the previous one - this gives you the triangular PDF and the
|
||||
//filtering in one go :-)
|
||||
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //PaulWide (brighter neutral that's still TPDF and wide)
|
||||
case 5:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
drySampleL = inputSampleL;//re-using in NJAD
|
||||
inputSampleL -= noiseShapingL;
|
||||
//NJAD L
|
||||
benfordize = floor(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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);
|
||||
inputSampleL /= 8388608.0;
|
||||
if (inputSampleL > 1.0) inputSampleL = 1.0;
|
||||
if (inputSampleL < -1.0) inputSampleL = -1.0;
|
||||
//finished NJAD L
|
||||
|
||||
//NJAD R
|
||||
drySampleR = inputSampleR;
|
||||
inputSampleR -= noiseShapingR;
|
||||
benfordize = floor(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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
|
||||
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);
|
||||
inputSampleR /= 8388608.0;
|
||||
if (inputSampleR > 1.0) inputSampleR = 1.0;
|
||||
if (inputSampleR < -1.0) inputSampleR = -1.0;
|
||||
break; //NJAD (Monitoring. Brightest)
|
||||
case 6:
|
||||
//begin 32 bit stereo floating point dither
|
||||
frexpf((float)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
frexpf((float)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit stereo floating point dither
|
||||
break; //Bypass for saving floating point files directly
|
||||
}
|
||||
|
||||
*out1 = inputSampleL;
|
||||
*out2 = inputSampleR;
|
||||
|
|
@ -318,7 +696,11 @@ void Mastering::processDoubleReplacing(double **inputs, double **outputs, VstInt
|
|||
double depthSinew = I;
|
||||
int spacing = floor(overallscale); //should give us working basic scaling, usually 2 or 4
|
||||
if (spacing < 1) spacing = 1; if (spacing > 16) spacing = 16;
|
||||
|
||||
int dither = (int) ( J * 5.999 )+1;
|
||||
int depth = (int)(17.0*overallscale);
|
||||
if (depth < 3) depth = 3;
|
||||
if (depth > 98) depth = 98; //for Dark
|
||||
|
||||
while (--sampleFrames >= 0)
|
||||
{
|
||||
double inputSampleL = *in1;
|
||||
|
|
@ -552,14 +934,388 @@ void Mastering::processDoubleReplacing(double **inputs, double **outputs, VstInt
|
|||
inputSampleR = (inputSampleR * (1.0-depthSinew))+(lastSinewR*depthSinew);
|
||||
//run Sinew to stop excess slews, but run a dry/wet to allow a range of brights
|
||||
|
||||
//begin 64 bit stereo floating point dither
|
||||
int expon; frexp((double)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
frexp((double)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
//end 64 bit stereo floating point dither
|
||||
|
||||
switch (dither) {
|
||||
case 1:
|
||||
//begin Dark
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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
|
||||
quantA = floor(inputSampleL);
|
||||
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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark 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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark right
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Dark (Monitoring2)
|
||||
case 2:
|
||||
//begin Dark for Ten Nines
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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 L
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddL = (NSOddL * 0.9999999999) + prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) - prevShapeL;
|
||||
correction = NSOddL;
|
||||
} else {
|
||||
NSOddL = (NSOddL * 0.9999999999) - prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) + prevShapeL;
|
||||
correction = NSEvenL;
|
||||
}
|
||||
shapedSampleL = inputSampleL+correction;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin Dark L
|
||||
quantA = floor(shapedSampleL);
|
||||
quantB = floor(shapedSampleL+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark L
|
||||
|
||||
prevShapeL = (floor(shapedSampleL) - inputSampleL)*0.9999999999;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin R
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddR = (NSOddR * 0.9999999999) + prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) - prevShapeR;
|
||||
correction = NSOddR;
|
||||
} else {
|
||||
NSOddR = (NSOddR * 0.9999999999) - prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) + prevShapeR;
|
||||
correction = NSEvenR;
|
||||
}
|
||||
shapedSampleR = inputSampleR+correction;
|
||||
//end Ten Nines R
|
||||
|
||||
//begin Dark R
|
||||
quantA = floor(shapedSampleR);
|
||||
quantB = floor(shapedSampleR+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark R
|
||||
|
||||
prevShapeR = (floor(shapedSampleR) - inputSampleR)*0.9999999999;
|
||||
//end Ten Nines
|
||||
flip = !flip;
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Ten Nines (which goes into Dark in Monitoring3)
|
||||
case 3:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //TPDFWide (a good neutral with the width enhancement)
|
||||
case 4:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
//Paul Frindle: It's true that the dither itself can sound different
|
||||
//if it's given a different freq response and you get to hear it.
|
||||
//The one we use most is triangular single pole high pass dither.
|
||||
//It's not freq bent enough to sound odd, but is slightly less audible than
|
||||
//flat dither. It can also be easily made by taking one sample of dither
|
||||
//away from the previous one - this gives you the triangular PDF and the
|
||||
//filtering in one go :-)
|
||||
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //PaulWide (brighter neutral that's still TPDF and wide)
|
||||
case 5:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
drySampleL = inputSampleL;//re-using in NJAD
|
||||
inputSampleL -= noiseShapingL;
|
||||
//NJAD L
|
||||
benfordize = floor(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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);
|
||||
inputSampleL /= 8388608.0;
|
||||
if (inputSampleL > 1.0) inputSampleL = 1.0;
|
||||
if (inputSampleL < -1.0) inputSampleL = -1.0;
|
||||
//finished NJAD L
|
||||
|
||||
//NJAD R
|
||||
drySampleR = inputSampleR;
|
||||
inputSampleR -= noiseShapingR;
|
||||
benfordize = floor(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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
|
||||
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);
|
||||
inputSampleR /= 8388608.0;
|
||||
if (inputSampleR > 1.0) inputSampleR = 1.0;
|
||||
if (inputSampleR < -1.0) inputSampleR = -1.0;
|
||||
break; //NJAD (Monitoring. Brightest)
|
||||
case 6:
|
||||
//begin 64 bit stereo floating point dither
|
||||
frexp((double)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
frexp((double)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
//end 64 bit stereo floating point dither
|
||||
break; //Bypass for saving floating point files directly
|
||||
}
|
||||
|
||||
*out1 = inputSampleL;
|
||||
*out2 = inputSampleR;
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -19,7 +19,7 @@
|
|||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>DthX</string>
|
||||
<string>Dthr</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Version: 1.0
|
||||
*
|
||||
* Created: 10/8/24
|
||||
* Created: 10/21/24
|
||||
*
|
||||
* Copyright: Copyright © 2024 Airwindows, Airwindows uses the MIT license
|
||||
*
|
||||
|
|
@ -68,6 +68,7 @@ Mastering::Mastering(AudioUnit component)
|
|||
SetParameter(kParam_G, kDefaultValue_ParamG );
|
||||
SetParameter(kParam_H, kDefaultValue_ParamH );
|
||||
SetParameter(kParam_I, kDefaultValue_ParamI );
|
||||
SetParameter(kParam_J, kDefaultValue_ParamJ );
|
||||
|
||||
#if AU_DEBUG_DISPATCHER
|
||||
mDebugDispatcher = new AUDebugDispatcher (this);
|
||||
|
|
@ -83,7 +84,26 @@ ComponentResult Mastering::GetParameterValueStrings(AudioUnitScope inScope,
|
|||
AudioUnitParameterID inParameterID,
|
||||
CFArrayRef * outStrings)
|
||||
{
|
||||
|
||||
if ((inScope == kAudioUnitScope_Global) && (inParameterID == kParam_J)) //ID must be actual name of parameter identifier, not number
|
||||
{
|
||||
if (outStrings == NULL) return noErr;
|
||||
CFStringRef strings [] =
|
||||
{
|
||||
kMenuItem_Dark,
|
||||
kMenuItem_TenNines,
|
||||
kMenuItem_TPDFWide,
|
||||
kMenuItem_PaulWide,
|
||||
kMenuItem_NJAD,
|
||||
kMenuItem_Bypass,
|
||||
};
|
||||
*outStrings = CFArrayCreate (
|
||||
NULL,
|
||||
(const void **) strings,
|
||||
(sizeof (strings) / sizeof (strings [0])),
|
||||
NULL
|
||||
);
|
||||
return noErr;
|
||||
}
|
||||
return kAudioUnitErr_InvalidProperty;
|
||||
}
|
||||
|
||||
|
|
@ -167,7 +187,14 @@ ComponentResult Mastering::GetParameterInfo(AudioUnitScope inScope,
|
|||
outParameterInfo.maxValue = 1.0;
|
||||
outParameterInfo.defaultValue = kDefaultValue_ParamI;
|
||||
break;
|
||||
default:
|
||||
case kParam_J:
|
||||
AUBase::FillInParameterName (outParameterInfo, kParameterJName, false);
|
||||
outParameterInfo.unit = kAudioUnitParameterUnit_Indexed;
|
||||
outParameterInfo.minValue = kDark;
|
||||
outParameterInfo.maxValue = kBypass;
|
||||
outParameterInfo.defaultValue = kDefaultValue_ParamJ;
|
||||
break;
|
||||
default:
|
||||
result = kAudioUnitErr_InvalidParameter;
|
||||
break;
|
||||
}
|
||||
|
|
@ -192,6 +219,21 @@ ComponentResult Mastering::GetPropertyInfo (AudioUnitPropertyID inID,
|
|||
return AUEffectBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// state that plugin supports only stereo-in/stereo-out processing
|
||||
UInt32 Mastering::SupportedNumChannels(const AUChannelInfo ** outInfo)
|
||||
{
|
||||
if (outInfo != NULL)
|
||||
{
|
||||
static AUChannelInfo info;
|
||||
info.inChannels = 2;
|
||||
info.outChannels = 2;
|
||||
*outInfo = &info;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Mastering::GetProperty
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -220,31 +262,96 @@ ComponentResult Mastering::Initialize()
|
|||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Mastering::MasteringKernel::Reset()
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
void Mastering::MasteringKernel::Reset()
|
||||
ComponentResult Mastering::Reset(AudioUnitScope inScope, AudioUnitElement inElement)
|
||||
{
|
||||
for (int x = 0; x < air_total; x++) air[x] = 0.0;
|
||||
for (int x = 0; x < kal_total; x++) {kalM[x] = 0.0;kalS[x] = 0.0;}
|
||||
|
||||
lastSinewL = 0.0;
|
||||
lastSample = 0.0;
|
||||
wasPosClip = false;
|
||||
wasNegClip = false;
|
||||
for (int x = 0; x < 16; x++) {intermediate[x] = 0.0;}
|
||||
|
||||
fpd = 1.0; while (fpd < 16386) fpd = rand()*UINT32_MAX;
|
||||
lastSinewR = 0.0;
|
||||
|
||||
lastSampleL = 0.0;
|
||||
wasPosClipL = false;
|
||||
wasNegClipL = false;
|
||||
lastSampleR = 0.0;
|
||||
wasPosClipR = false;
|
||||
wasNegClipR = false;
|
||||
for (int x = 0; x < 16; x++) {intermediateL[x] = 0.0; intermediateR[x] = 0.0;}
|
||||
|
||||
quantA = 0;
|
||||
quantB = 1;
|
||||
expectedSlew = 0.0;
|
||||
testA = 0.0;
|
||||
testB = 0.0;
|
||||
correction = 0.0;
|
||||
shapedSampleL = 0.0;
|
||||
shapedSampleR = 0.0;
|
||||
currentDither = 0.0;
|
||||
ditherL = 0.0;
|
||||
ditherR = 0.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
hotbinA = 0;
|
||||
hotbinB = 0;
|
||||
benfordize = 0.0;
|
||||
totalA = 0.0;
|
||||
totalB = 0.0;
|
||||
outputSample = 0.0;
|
||||
expon = 0; //internal dither variables
|
||||
//these didn't like to be defined inside a case statement
|
||||
|
||||
NSOddL = 0.0; NSEvenL = 0.0; prevShapeL = 0.0;
|
||||
NSOddR = 0.0; NSEvenR = 0.0; prevShapeR = 0.0;
|
||||
flip = true; //Ten Nines
|
||||
for(int count = 0; count < 99; count++) {
|
||||
darkSampleL[count] = 0;
|
||||
darkSampleR[count] = 0;
|
||||
} //Dark
|
||||
previousDitherL = 0.0;
|
||||
previousDitherR = 0.0; //PaulWide
|
||||
bynL[0] = 1000.0;
|
||||
bynL[1] = 301.0;
|
||||
bynL[2] = 176.0;
|
||||
bynL[3] = 125.0;
|
||||
bynL[4] = 97.0;
|
||||
bynL[5] = 79.0;
|
||||
bynL[6] = 67.0;
|
||||
bynL[7] = 58.0;
|
||||
bynL[8] = 51.0;
|
||||
bynL[9] = 46.0;
|
||||
bynL[10] = 1000.0;
|
||||
noiseShapingL = 0.0;
|
||||
bynR[0] = 1000.0;
|
||||
bynR[1] = 301.0;
|
||||
bynR[2] = 176.0;
|
||||
bynR[3] = 125.0;
|
||||
bynR[4] = 97.0;
|
||||
bynR[5] = 79.0;
|
||||
bynR[6] = 67.0;
|
||||
bynR[7] = 58.0;
|
||||
bynR[8] = 51.0;
|
||||
bynR[9] = 46.0;
|
||||
bynR[10] = 1000.0;
|
||||
noiseShapingR = 0.0; //NJAD
|
||||
|
||||
fpdL = 1.0; while (fpdL < 16386) fpdL = rand()*UINT32_MAX;
|
||||
fpdR = 1.0; while (fpdR < 16386) fpdR = rand()*UINT32_MAX;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Mastering::MasteringKernel::Process
|
||||
// Mastering::ProcessBufferLists
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
||||
Float32 *inDestP,
|
||||
UInt32 inFramesToProcess,
|
||||
UInt32 inNumChannels,
|
||||
bool &ioSilence )
|
||||
OSStatus Mastering::ProcessBufferLists(AudioUnitRenderActionFlags & ioActionFlags,
|
||||
const AudioBufferList & inBuffer,
|
||||
AudioBufferList & outBuffer,
|
||||
UInt32 inFramesToProcess)
|
||||
{
|
||||
Float32 * inputL = (Float32*)(inBuffer.mBuffers[0].mData);
|
||||
Float32 * inputR = (Float32*)(inBuffer.mBuffers[1].mData);
|
||||
Float32 * outputL = (Float32*)(outBuffer.mBuffers[0].mData);
|
||||
Float32 * outputR = (Float32*)(outBuffer.mBuffers[1].mData);
|
||||
UInt32 nSampleFrames = inFramesToProcess;
|
||||
const Float32 *sourceP = inSourceP;
|
||||
Float32 *destP = inDestP;
|
||||
double overallscale = 1.0;
|
||||
overallscale /= 44100.0;
|
||||
overallscale *= GetSampleRate();
|
||||
|
|
@ -267,11 +374,18 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
double depthSinew = GetParameter( kParam_I );
|
||||
int spacing = floor(overallscale); //should give us working basic scaling, usually 2 or 4
|
||||
if (spacing < 1) spacing = 1; if (spacing > 16) spacing = 16;
|
||||
int dither = (int) GetParameter( kParam_J );
|
||||
int depth = (int)(17.0*overallscale);
|
||||
if (depth < 3) depth = 3;
|
||||
if (depth > 98) depth = 98; //for Dark
|
||||
|
||||
while (nSampleFrames-- > 0) {
|
||||
long double inputSampleL = *sourceP;
|
||||
if (fabs(inputSampleL)<1.18e-23) inputSampleL = fpd * 1.18e-17;
|
||||
double inputSampleL = *inputL;
|
||||
double inputSampleR = *inputR;
|
||||
if (fabs(inputSampleL)<1.18e-23) inputSampleL = fpdL * 1.18e-17;
|
||||
if (fabs(inputSampleR)<1.18e-23) inputSampleR = fpdR * 1.18e-17;
|
||||
double drySampleL = inputSampleL;
|
||||
double drySampleR = inputSampleR;
|
||||
|
||||
//begin Air3L
|
||||
air[pvSL4] = air[pvAL4] - air[pvAL3]; air[pvSL3] = air[pvAL3] - air[pvAL2];
|
||||
|
|
@ -286,10 +400,25 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
air[pvAL2] = air[pvAL1]; air[pvAL1] = (air[gainAL] * air[outAL]) + drySampleL;
|
||||
long double midL = drySampleL - ((air[outAL]*0.5)+(drySampleL*(0.457-(0.017*overallscale))));
|
||||
long double temp = (midL + air[gndavgL])*0.5; air[gndavgL] = midL; midL = temp;
|
||||
//we have a single averaging stage to smooth stuff out
|
||||
long double trebleL = drySampleL-midL;
|
||||
//end Air3L
|
||||
|
||||
//begin Air3R
|
||||
air[pvSR4] = air[pvAR4] - air[pvAR3]; air[pvSR3] = air[pvAR3] - air[pvAR2];
|
||||
air[pvSR2] = air[pvAR2] - air[pvAR1]; air[pvSR1] = air[pvAR1] - inputSampleR;
|
||||
air[accSR3] = air[pvSR4] - air[pvSR3]; air[accSR2] = air[pvSR3] - air[pvSR2];
|
||||
air[accSR1] = air[pvSR2] - air[pvSR1];
|
||||
air[acc2SR2] = air[accSR3] - air[accSR2]; air[acc2SR1] = air[accSR2] - air[accSR1];
|
||||
air[outAR] = -(air[pvAR1] + air[pvSR3] + air[acc2SR2] - ((air[acc2SR2] + air[acc2SR1])*0.5));
|
||||
air[gainAR] *= 0.5; air[gainAR] += fabs(drySampleR-air[outAR])*0.5;
|
||||
if (air[gainAR] > 0.3*sqrt(overallscale)) air[gainAR] = 0.3*sqrt(overallscale);
|
||||
air[pvAR4] = air[pvAR3]; air[pvAR3] = air[pvAR2];
|
||||
air[pvAR2] = air[pvAR1]; air[pvAR1] = (air[gainAR] * air[outAR]) + drySampleR;
|
||||
long double midR = drySampleR - ((air[outAR]*0.5)+(drySampleR*(0.457-(0.017*overallscale))));
|
||||
temp = (midR + air[gndavgR])*0.5; air[gndavgR] = midR; midR = temp;
|
||||
long double trebleR = drySampleR-midR;
|
||||
//end Air3R
|
||||
|
||||
//begin KalmanML
|
||||
temp = midL;
|
||||
kalM[prevSlewL3] += kalM[prevSampL3] - kalM[prevSampL2]; kalM[prevSlewL3] *= 0.5;
|
||||
|
|
@ -302,7 +431,7 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
kalM[accSlewL3] += (kalM[accSlewL2] - kalM[accSlewL1]); kalM[accSlewL3] *= 0.5;
|
||||
//entering the abyss, what even is this
|
||||
kalM[kalOutL] += kalM[prevSampL1] + kalM[prevSlewL2] + kalM[accSlewL3]; kalM[kalOutL] *= 0.5;
|
||||
|
||||
|
||||
//resynthesizing predicted result (all iir smoothed)
|
||||
kalM[kalGainL] += fabs(temp-kalM[kalOutL])*kalMid*8.0; kalM[kalGainL] *= 0.5;
|
||||
//madness takes its toll. Kalman Gain: how much dry to retain
|
||||
|
|
@ -318,6 +447,34 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
midL -= bassL;
|
||||
//end KalmanML
|
||||
|
||||
//begin KalmanMR
|
||||
temp = midR;
|
||||
kalM[prevSlewR3] += kalM[prevSampR3] - kalM[prevSampR2]; kalM[prevSlewR3] *= 0.5;
|
||||
kalM[prevSlewR2] += kalM[prevSampR2] - kalM[prevSampR1]; kalM[prevSlewR2] *= 0.5;
|
||||
kalM[prevSlewR1] += kalM[prevSampR1] - midR; kalM[prevSlewR1] *= 0.5;
|
||||
//make slews from each set of samples used
|
||||
kalM[accSlewR2] += kalM[prevSlewR3] - kalM[prevSlewR2]; kalM[accSlewR2] *= 0.5;
|
||||
kalM[accSlewR1] += kalM[prevSlewR2] - kalM[prevSlewR1]; kalM[accSlewR1] *= 0.5;
|
||||
//differences between slews: rate of change of rate of change
|
||||
kalM[accSlewR3] += (kalM[accSlewR2] - kalM[accSlewR1]); kalM[accSlewR3] *= 0.5;
|
||||
//entering the abyss, what even is this
|
||||
kalM[kalOutR] += kalM[prevSampR1] + kalM[prevSlewR2] + kalM[accSlewR3]; kalM[kalOutR] *= 0.5;
|
||||
|
||||
//resynthesizing predicted result (all iir smoothed)
|
||||
kalM[kalGainR] += fabs(temp-kalM[kalOutR])*kalMid*8.0; kalM[kalGainR] *= 0.5;
|
||||
//madness takes its toll. Kalman Gain: how much dry to retain
|
||||
if (kalM[kalGainR] > kalMid*0.5) kalM[kalGainR] = kalMid*0.5;
|
||||
//attempts to avoid explosions
|
||||
kalM[kalOutR] += (temp*(1.0-(0.68+(kalMid*0.157))));
|
||||
//this is for tuning a really complete cancellation up around Nyquist
|
||||
kalM[prevSampR3] = kalM[prevSampR2]; kalM[prevSampR2] = kalM[prevSampR1];
|
||||
kalM[prevSampR1] = (kalM[kalGainR] * kalM[kalOutR]) + ((1.0-kalM[kalGainR])*temp);
|
||||
//feed the chain of previous samples
|
||||
long double bassR = (kalM[kalOutR]+kalM[kalAvgR])*0.5;
|
||||
kalM[kalAvgR] = kalM[kalOutR];
|
||||
midR -= bassR;
|
||||
//end KalmanMR
|
||||
|
||||
//begin KalmanSL
|
||||
temp = bassL;
|
||||
kalS[prevSlewL3] += kalS[prevSampL3] - kalS[prevSampL2]; kalS[prevSlewL3] *= 0.5;
|
||||
|
|
@ -345,44 +502,100 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
bassL -= subL;
|
||||
//end KalmanSL
|
||||
|
||||
//begin KalmanSR
|
||||
temp = bassR;
|
||||
kalS[prevSlewR3] += kalS[prevSampR3] - kalS[prevSampR2]; kalS[prevSlewR3] *= 0.5;
|
||||
kalS[prevSlewR2] += kalS[prevSampR2] - kalS[prevSampR1]; kalS[prevSlewR2] *= 0.5;
|
||||
kalS[prevSlewR1] += kalS[prevSampR1] - bassR; kalS[prevSlewR1] *= 0.5;
|
||||
//make slews from each set of samples used
|
||||
kalS[accSlewR2] += kalS[prevSlewR3] - kalS[prevSlewR2]; kalS[accSlewR2] *= 0.5;
|
||||
kalS[accSlewR1] += kalS[prevSlewR2] - kalS[prevSlewR1]; kalS[accSlewR1] *= 0.5;
|
||||
//differences between slews: rate of change of rate of change
|
||||
kalS[accSlewR3] += (kalS[accSlewR2] - kalS[accSlewR1]); kalS[accSlewR3] *= 0.5;
|
||||
//entering the abyss, what even is this
|
||||
kalS[kalOutR] += kalS[prevSampR1] + kalS[prevSlewR2] + kalS[accSlewR3]; kalS[kalOutR] *= 0.5;
|
||||
//resynthesizing predicted result (all iir smoothed)
|
||||
kalS[kalGainR] += fabs(temp-kalS[kalOutR])*kalSub*8.0; kalS[kalGainR] *= 0.5;
|
||||
//madness takes its toll. Kalman Gain: how much dry to retain
|
||||
if (kalS[kalGainR] > kalSub*0.5) kalS[kalGainR] = kalSub*0.5;
|
||||
//attempts to avoid explosions
|
||||
kalS[kalOutR] += (temp*(1.0-(0.68+(kalSub*0.157))));
|
||||
//this is for tuning a really complete cancellation up around Nyquist
|
||||
kalS[prevSampR3] = kalS[prevSampR2]; kalS[prevSampR2] = kalS[prevSampR1];
|
||||
kalS[prevSampR1] = (kalS[kalGainR] * kalS[kalOutR]) + ((1.0-kalS[kalGainR])*temp);
|
||||
//feed the chain of previous samples
|
||||
long double subR = (kalS[kalOutR]+kalS[kalAvgR])*0.5;
|
||||
kalS[kalAvgR] = kalS[kalOutR];
|
||||
bassR -= subR;
|
||||
//end KalmanSR
|
||||
|
||||
inputSampleL = (subL*subGain);
|
||||
inputSampleL += (bassL*bassGain);
|
||||
inputSampleL += (midL*midGain);
|
||||
inputSampleL += (trebleL*trebleGain);
|
||||
inputSampleR = (subR*subGain);
|
||||
inputSampleR += (bassR*bassGain);
|
||||
inputSampleR += (midR*midGain);
|
||||
inputSampleR += (trebleR*trebleGain);
|
||||
|
||||
for (int count = 0; count < zoomStages; count++) {
|
||||
if (zoom > 0.0) {
|
||||
long double closer = inputSampleL * 1.57079633;
|
||||
double closer = inputSampleL * 1.57079633;
|
||||
if (closer > 1.57079633) closer = 1.57079633;
|
||||
if (closer < -1.57079633) closer = -1.57079633;
|
||||
inputSampleL = (inputSampleL*(1.0-zoom))+(sin(closer)*zoom);
|
||||
closer = inputSampleR * 1.57079633;
|
||||
if (closer > 1.57079633) closer = 1.57079633;
|
||||
if (closer < -1.57079633) closer = -1.57079633;
|
||||
inputSampleR = (inputSampleR*(1.0-zoom))+(sin(closer)*zoom);
|
||||
} //zooming in will make the body of the sound louder: it's just Density
|
||||
if (zoom < 0.0) {
|
||||
long double farther = fabs(inputSampleL) * 1.57079633;
|
||||
double farther = fabs(inputSampleL) * 1.57079633;
|
||||
if (farther > 1.57079633) farther = 1.0;
|
||||
else farther = 1.0-cos(farther);
|
||||
if (inputSampleL > 0.0) inputSampleL = (inputSampleL*(1.0+zoom))-(farther*zoom*1.57079633);
|
||||
if (inputSampleL < 0.0) inputSampleL = (inputSampleL*(1.0+zoom))+(farther*zoom*1.57079633);
|
||||
farther = fabs(inputSampleR) * 1.57079633;
|
||||
if (farther > 1.57079633) farther = 1.0;
|
||||
else farther = 1.0-cos(farther);
|
||||
if (inputSampleR > 0.0) inputSampleR = (inputSampleR*(1.0+zoom))-(farther*zoom*1.57079633);
|
||||
if (inputSampleR < 0.0) inputSampleR = (inputSampleR*(1.0+zoom))+(farther*zoom*1.57079633);
|
||||
} //zooming out boosts the hottest peaks but cuts back softer stuff
|
||||
}
|
||||
|
||||
//begin ClipOnly2 as a little, compressed chunk that can be dropped into code
|
||||
//begin ClipOnly2 stereo as a little, compressed chunk that can be dropped into code
|
||||
if (inputSampleL > 4.0) inputSampleL = 4.0; if (inputSampleL < -4.0) inputSampleL = -4.0;
|
||||
if (wasPosClip == true) { //current will be over
|
||||
if (inputSampleL<lastSample) lastSample=0.7058208+(inputSampleL*0.2609148);
|
||||
else lastSample = 0.2491717+(lastSample*0.7390851);
|
||||
} wasPosClip = false;
|
||||
if (inputSampleL>0.9549925859) {wasPosClip=true;inputSampleL=0.7058208+(lastSample*0.2609148);}
|
||||
if (wasNegClip == true) { //current will be -over
|
||||
if (inputSampleL > lastSample) lastSample=-0.7058208+(inputSampleL*0.2609148);
|
||||
else lastSample=-0.2491717+(lastSample*0.7390851);
|
||||
} wasNegClip = false;
|
||||
if (inputSampleL<-0.9549925859) {wasNegClip=true;inputSampleL=-0.7058208+(lastSample*0.2609148);}
|
||||
intermediate[spacing] = inputSampleL;
|
||||
inputSampleL = lastSample; //Latency is however many samples equals one 44.1k sample
|
||||
for (int x = spacing; x > 0; x--) intermediate[x-1] = intermediate[x];
|
||||
lastSample = intermediate[0]; //run a little buffer to handle this
|
||||
//end ClipOnly2 as a little, compressed chunk that can be dropped into code
|
||||
if (wasPosClipL == true) { //current will be over
|
||||
if (inputSampleL<lastSampleL) lastSampleL=0.7058208+(inputSampleL*0.2609148);
|
||||
else lastSampleL = 0.2491717+(lastSampleL*0.7390851);
|
||||
} wasPosClipL = false;
|
||||
if (inputSampleL>0.9549925859) {wasPosClipL=true;inputSampleL=0.7058208+(lastSampleL*0.2609148);}
|
||||
if (wasNegClipL == true) { //current will be -over
|
||||
if (inputSampleL > lastSampleL) lastSampleL=-0.7058208+(inputSampleL*0.2609148);
|
||||
else lastSampleL=-0.2491717+(lastSampleL*0.7390851);
|
||||
} wasNegClipL = false;
|
||||
if (inputSampleL<-0.9549925859) {wasNegClipL=true;inputSampleL=-0.7058208+(lastSampleL*0.2609148);}
|
||||
intermediateL[spacing] = inputSampleL;
|
||||
inputSampleL = lastSampleL; //Latency is however many samples equals one 44.1k sample
|
||||
for (int x = spacing; x > 0; x--) intermediateL[x-1] = intermediateL[x];
|
||||
lastSampleL = intermediateL[0]; //run a little buffer to handle this
|
||||
|
||||
if (inputSampleR > 4.0) inputSampleR = 4.0; if (inputSampleR < -4.0) inputSampleR = -4.0;
|
||||
if (wasPosClipR == true) { //current will be over
|
||||
if (inputSampleR<lastSampleR) lastSampleR=0.7058208+(inputSampleR*0.2609148);
|
||||
else lastSampleR = 0.2491717+(lastSampleR*0.7390851);
|
||||
} wasPosClipR = false;
|
||||
if (inputSampleR>0.9549925859) {wasPosClipR=true;inputSampleR=0.7058208+(lastSampleR*0.2609148);}
|
||||
if (wasNegClipR == true) { //current will be -over
|
||||
if (inputSampleR > lastSampleR) lastSampleR=-0.7058208+(inputSampleR*0.2609148);
|
||||
else lastSampleR=-0.2491717+(lastSampleR*0.7390851);
|
||||
} wasNegClipR = false;
|
||||
if (inputSampleR<-0.9549925859) {wasNegClipR=true;inputSampleR=-0.7058208+(lastSampleR*0.2609148);}
|
||||
intermediateR[spacing] = inputSampleR;
|
||||
inputSampleR = lastSampleR; //Latency is however many samples equals one 44.1k sample
|
||||
for (int x = spacing; x > 0; x--) intermediateR[x-1] = intermediateR[x];
|
||||
lastSampleR = intermediateR[0]; //run a little buffer to handle this
|
||||
//end ClipOnly2 stereo as a little, compressed chunk that can be dropped into code
|
||||
|
||||
temp = inputSampleL;
|
||||
long double sinew = threshSinew * cos(lastSinewL*lastSinewL);
|
||||
|
|
@ -390,17 +603,405 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
if (-(inputSampleL - lastSinewL) > sinew) temp = lastSinewL - sinew;
|
||||
lastSinewL = temp;
|
||||
inputSampleL = (inputSampleL * (1.0-depthSinew))+(lastSinewL*depthSinew);
|
||||
temp = inputSampleR;
|
||||
sinew = threshSinew * cos(lastSinewR*lastSinewR);
|
||||
if (inputSampleR - lastSinewR > sinew) temp = lastSinewR + sinew;
|
||||
if (-(inputSampleR - lastSinewR) > sinew) temp = lastSinewR - sinew;
|
||||
lastSinewR = temp;
|
||||
inputSampleR = (inputSampleR * (1.0-depthSinew))+(lastSinewR*depthSinew);
|
||||
//run Sinew to stop excess slews, but run a dry/wet to allow a range of brights
|
||||
|
||||
//begin 32 bit floating point dither
|
||||
int expon; frexpf((float)inputSampleL, &expon);
|
||||
fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5;
|
||||
inputSampleL += ((double(fpd)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit floating point dither
|
||||
switch (dither) {
|
||||
case 1:
|
||||
//begin Dark
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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
|
||||
quantA = floor(inputSampleL);
|
||||
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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark 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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark right
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Dark (Monitoring2)
|
||||
case 2:
|
||||
//begin Dark for Ten Nines
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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 L
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddL = (NSOddL * 0.9999999999) + prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) - prevShapeL;
|
||||
correction = NSOddL;
|
||||
} else {
|
||||
NSOddL = (NSOddL * 0.9999999999) - prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) + prevShapeL;
|
||||
correction = NSEvenL;
|
||||
}
|
||||
shapedSampleL = inputSampleL+correction;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin Dark L
|
||||
quantA = floor(shapedSampleL);
|
||||
quantB = floor(shapedSampleL+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark L
|
||||
|
||||
prevShapeL = (floor(shapedSampleL) - inputSampleL)*0.9999999999;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin R
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddR = (NSOddR * 0.9999999999) + prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) - prevShapeR;
|
||||
correction = NSOddR;
|
||||
} else {
|
||||
NSOddR = (NSOddR * 0.9999999999) - prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) + prevShapeR;
|
||||
correction = NSEvenR;
|
||||
}
|
||||
shapedSampleR = inputSampleR+correction;
|
||||
//end Ten Nines R
|
||||
|
||||
//begin Dark R
|
||||
quantA = floor(shapedSampleR);
|
||||
quantB = floor(shapedSampleR+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark R
|
||||
|
||||
prevShapeR = (floor(shapedSampleR) - inputSampleR)*0.9999999999;
|
||||
//end Ten Nines
|
||||
flip = !flip;
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Ten Nines (which goes into Dark in Monitoring3)
|
||||
case 3:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //TPDFWide (a good neutral with the width enhancement)
|
||||
case 4:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
//Paul Frindle: It's true that the dither itself can sound different
|
||||
//if it's given a different freq response and you get to hear it.
|
||||
//The one we use most is triangular single pole high pass dither.
|
||||
//It's not freq bent enough to sound odd, but is slightly less audible than
|
||||
//flat dither. It can also be easily made by taking one sample of dither
|
||||
//away from the previous one - this gives you the triangular PDF and the
|
||||
//filtering in one go :-)
|
||||
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //PaulWide (brighter neutral that's still TPDF and wide)
|
||||
case 5:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
drySampleL = inputSampleL;//re-using in NJAD
|
||||
inputSampleL -= noiseShapingL;
|
||||
//NJAD L
|
||||
benfordize = floor(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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);
|
||||
inputSampleL /= 8388608.0;
|
||||
if (inputSampleL > 1.0) inputSampleL = 1.0;
|
||||
if (inputSampleL < -1.0) inputSampleL = -1.0;
|
||||
//finished NJAD L
|
||||
|
||||
//NJAD R
|
||||
drySampleR = inputSampleR;
|
||||
inputSampleR -= noiseShapingR;
|
||||
benfordize = floor(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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
|
||||
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);
|
||||
inputSampleR /= 8388608.0;
|
||||
if (inputSampleR > 1.0) inputSampleR = 1.0;
|
||||
if (inputSampleR < -1.0) inputSampleR = -1.0;
|
||||
break; //NJAD (Monitoring. Brightest)
|
||||
case 6:
|
||||
//begin 32 bit stereo floating point dither
|
||||
frexpf((float)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
frexpf((float)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit stereo floating point dither
|
||||
break; //Bypass for saving floating point files directly
|
||||
}
|
||||
|
||||
*destP = inputSampleL;
|
||||
*outputL = inputSampleL;
|
||||
*outputR = inputSampleR;
|
||||
//direct stereo out
|
||||
|
||||
sourceP += inNumChannels; destP += inNumChannels;
|
||||
inputL += 1;
|
||||
inputR += 1;
|
||||
outputL += 1;
|
||||
outputR += 1;
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Version: 1.0
|
||||
*
|
||||
* Created: 10/8/24
|
||||
* Created: 10/21/24
|
||||
*
|
||||
* Copyright: Copyright © 2024 Airwindows, Airwindows uses the MIT license
|
||||
*
|
||||
|
|
@ -63,6 +63,20 @@ static const float kDefaultValue_ParamF = 0.5;
|
|||
static const float kDefaultValue_ParamG = 0.5;
|
||||
static const float kDefaultValue_ParamH = 0.5;
|
||||
static const float kDefaultValue_ParamI = 0.0;
|
||||
static const int kDark = 1;
|
||||
static const int kTenNines = 2;
|
||||
static const int kTPDFWide = 3;
|
||||
static const int kPaulWide = 4;
|
||||
static const int kNJAD = 5;
|
||||
static const int kBypass = 6;
|
||||
static const int kDefaultValue_ParamJ = kBypass;
|
||||
|
||||
static CFStringRef kMenuItem_Dark = CFSTR ("Dark");
|
||||
static CFStringRef kMenuItem_TenNines = CFSTR ("Ten Nines");
|
||||
static CFStringRef kMenuItem_TPDFWide = CFSTR ("TPDFWide");
|
||||
static CFStringRef kMenuItem_PaulWide = CFSTR ("PaulWide");
|
||||
static CFStringRef kMenuItem_NJAD = CFSTR ("NJAD");
|
||||
static CFStringRef kMenuItem_Bypass = CFSTR ("Bypass");
|
||||
|
||||
static CFStringRef kParameterAName = CFSTR("Air");
|
||||
static CFStringRef kParameterBName = CFSTR("Mid");
|
||||
|
|
@ -73,6 +87,7 @@ static CFStringRef kParameterFName = CFSTR("XvL-S");
|
|||
static CFStringRef kParameterGName = CFSTR("Zoom");
|
||||
static CFStringRef kParameterHName = CFSTR("DarkF");
|
||||
static CFStringRef kParameterIName = CFSTR("Ratio");
|
||||
static CFStringRef kParameterJName = CFSTR("Dither");
|
||||
|
||||
enum {
|
||||
kParam_A =0,
|
||||
|
|
@ -84,8 +99,9 @@ enum {
|
|||
kParam_G =6,
|
||||
kParam_H =7,
|
||||
kParam_I =8,
|
||||
kParam_J =9,
|
||||
//Add your parameters here...
|
||||
kNumberOfParameters=9
|
||||
kNumberOfParameters=10
|
||||
};
|
||||
|
||||
#pragma mark ____Mastering
|
||||
|
|
@ -97,8 +113,13 @@ public:
|
|||
virtual ~Mastering () { delete mDebugDispatcher; }
|
||||
#endif
|
||||
|
||||
virtual AUKernelBase * NewKernel() { return new MasteringKernel(this); }
|
||||
|
||||
virtual ComponentResult Reset(AudioUnitScope inScope, AudioUnitElement inElement);
|
||||
|
||||
virtual OSStatus ProcessBufferLists(AudioUnitRenderActionFlags & ioActionFlags,
|
||||
const AudioBufferList & inBuffer, AudioBufferList & outBuffer,
|
||||
UInt32 inFramesToProcess);
|
||||
virtual UInt32 SupportedNumChannels(const AUChannelInfo ** outInfo);
|
||||
|
||||
virtual ComponentResult GetParameterValueStrings(AudioUnitScope inScope,
|
||||
AudioUnitParameterID inParameterID,
|
||||
CFArrayRef * outStrings);
|
||||
|
|
@ -117,7 +138,7 @@ public:
|
|||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
void * outData);
|
||||
|
||||
|
||||
virtual ComponentResult Initialize();
|
||||
virtual bool SupportsTail () { return true; }
|
||||
virtual Float64 GetTailTime() {return (1.0/GetSampleRate())*0.0;} //in SECONDS! gsr * a number = in samples
|
||||
|
|
@ -126,78 +147,126 @@ public:
|
|||
/*! @method Version */
|
||||
virtual ComponentResult Version() { return kMasteringVersion; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
protected:
|
||||
class MasteringKernel : public AUKernelBase // most of the real work happens here
|
||||
{
|
||||
public:
|
||||
MasteringKernel(AUEffectBase *inAudioUnit )
|
||||
: AUKernelBase(inAudioUnit)
|
||||
{
|
||||
}
|
||||
|
||||
// *Required* overides for the process method for this effect
|
||||
// processes one channel of interleaved samples
|
||||
virtual void Process( const Float32 *inSourceP,
|
||||
Float32 *inDestP,
|
||||
UInt32 inFramesToProcess,
|
||||
UInt32 inNumChannels,
|
||||
bool &ioSilence);
|
||||
|
||||
virtual void Reset();
|
||||
|
||||
private:
|
||||
enum {
|
||||
pvAL1,
|
||||
pvSL1,
|
||||
accSL1,
|
||||
acc2SL1,
|
||||
pvAL2,
|
||||
pvSL2,
|
||||
accSL2,
|
||||
acc2SL2,
|
||||
pvAL3,
|
||||
pvSL3,
|
||||
accSL3,
|
||||
pvAL4,
|
||||
pvSL4,
|
||||
gndavgL,
|
||||
outAL,
|
||||
gainAL,
|
||||
air_total
|
||||
};
|
||||
double air[air_total];
|
||||
|
||||
enum {
|
||||
prevSampL1,
|
||||
prevSlewL1,
|
||||
accSlewL1,
|
||||
prevSampL2,
|
||||
prevSlewL2,
|
||||
accSlewL2,
|
||||
prevSampL3,
|
||||
prevSlewL3,
|
||||
accSlewL3,
|
||||
kalGainL,
|
||||
kalOutL,
|
||||
kalAvgL,
|
||||
kal_total
|
||||
};
|
||||
double kalM[kal_total];
|
||||
double kalS[kal_total];
|
||||
|
||||
long double lastSinewL;
|
||||
//this is overkill, used to run both Zoom and Sinew stages as they are after
|
||||
//the summing in StoneFire, which sums three doubles to a long double.
|
||||
|
||||
double lastSample; //this doesn't touch the audio unless it's clipping
|
||||
double intermediate[16];
|
||||
bool wasPosClip;
|
||||
bool wasNegClip;
|
||||
|
||||
uint32_t fpd;
|
||||
enum {
|
||||
pvAL1,
|
||||
pvSL1,
|
||||
accSL1,
|
||||
acc2SL1,
|
||||
pvAL2,
|
||||
pvSL2,
|
||||
accSL2,
|
||||
acc2SL2,
|
||||
pvAL3,
|
||||
pvSL3,
|
||||
accSL3,
|
||||
pvAL4,
|
||||
pvSL4,
|
||||
gndavgL,
|
||||
outAL,
|
||||
gainAL,
|
||||
pvAR1,
|
||||
pvSR1,
|
||||
accSR1,
|
||||
acc2SR1,
|
||||
pvAR2,
|
||||
pvSR2,
|
||||
accSR2,
|
||||
acc2SR2,
|
||||
pvAR3,
|
||||
pvSR3,
|
||||
accSR3,
|
||||
pvAR4,
|
||||
pvSR4,
|
||||
gndavgR,
|
||||
outAR,
|
||||
gainAR,
|
||||
air_total
|
||||
};
|
||||
double air[air_total];
|
||||
|
||||
enum {
|
||||
prevSampL1,
|
||||
prevSlewL1,
|
||||
accSlewL1,
|
||||
prevSampL2,
|
||||
prevSlewL2,
|
||||
accSlewL2,
|
||||
prevSampL3,
|
||||
prevSlewL3,
|
||||
accSlewL3,
|
||||
kalGainL,
|
||||
kalOutL,
|
||||
kalAvgL,
|
||||
prevSampR1,
|
||||
prevSlewR1,
|
||||
accSlewR1,
|
||||
prevSampR2,
|
||||
prevSlewR2,
|
||||
accSlewR2,
|
||||
prevSampR3,
|
||||
prevSlewR3,
|
||||
accSlewR3,
|
||||
kalGainR,
|
||||
kalOutR,
|
||||
kalAvgR,
|
||||
kal_total
|
||||
};
|
||||
double kalM[kal_total];
|
||||
double kalS[kal_total];
|
||||
|
||||
long double lastSinewL;
|
||||
long double lastSinewR;
|
||||
//this is overkill, used to run both Zoom and Sinew stages as they are after
|
||||
//the summing in StoneFire, which sums three doubles to a long double.
|
||||
|
||||
double lastSampleL;
|
||||
double intermediateL[16];
|
||||
bool wasPosClipL;
|
||||
bool wasNegClipL;
|
||||
double lastSampleR;
|
||||
double intermediateR[16];
|
||||
bool wasPosClipR;
|
||||
bool wasNegClipR; //Stereo ClipOnly2
|
||||
|
||||
int quantA;
|
||||
int quantB;
|
||||
float expectedSlew;
|
||||
float testA;
|
||||
float testB;
|
||||
double correction;
|
||||
double shapedSampleL;
|
||||
double shapedSampleR;
|
||||
double currentDither;
|
||||
double ditherL;
|
||||
double ditherR;
|
||||
bool cutbinsL;
|
||||
bool cutbinsR;
|
||||
int hotbinA;
|
||||
int hotbinB;
|
||||
double benfordize;
|
||||
double totalA;
|
||||
double totalB;
|
||||
double outputSample;
|
||||
int expon; //internal dither variables
|
||||
|
||||
double NSOddL; //dither section!
|
||||
double NSEvenL;
|
||||
double prevShapeL;
|
||||
double NSOddR;
|
||||
double NSEvenR;
|
||||
double prevShapeR;
|
||||
bool flip; //VinylDither
|
||||
double darkSampleL[100];
|
||||
double darkSampleR[100]; //Dark
|
||||
double previousDitherL;
|
||||
double previousDitherR; //PaulWide
|
||||
double bynL[13], bynR[13];
|
||||
double noiseShapingL, noiseShapingR; //NJAD
|
||||
|
||||
uint32_t fpdL;
|
||||
uint32_t fpdR;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Version: 1.0
|
||||
*
|
||||
* Created: 10/8/24
|
||||
* Created: 10/21/24
|
||||
*
|
||||
* Copyright: Copyright © 2024 Airwindows, Airwindows uses the MIT license
|
||||
*
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@
|
|||
<dict>
|
||||
<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
|
||||
<array>
|
||||
<real>186</real>
|
||||
<real>299</real>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
|
||||
<array>
|
||||
|
|
@ -264,19 +264,22 @@
|
|||
<array>
|
||||
<string>089C166AFE841209C02AAC07</string>
|
||||
<string>08FB77ADFE841716C02AAC07</string>
|
||||
<string>8BA05AEB0720742700365D66</string>
|
||||
<string>8BA05A7D072073D200365D66</string>
|
||||
<string>8BA05A7E072073D200365D66</string>
|
||||
<string>1C37FBAC04509CD000000102</string>
|
||||
<string>1C37FABC05509CD000000102</string>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
|
||||
<array>
|
||||
<array>
|
||||
<integer>20</integer>
|
||||
<integer>19</integer>
|
||||
<integer>6</integer>
|
||||
<integer>5</integer>
|
||||
<integer>4</integer>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
|
||||
<string>{{0, 0}, {186, 445}}</string>
|
||||
<string>{{0, 0}, {299, 445}}</string>
|
||||
</dict>
|
||||
<key>PBXTopSmartGroupGIDs</key>
|
||||
<array/>
|
||||
|
|
@ -288,19 +291,19 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {203, 463}}</string>
|
||||
<string>{{0, 0}, {316, 463}}</string>
|
||||
<key>GroupTreeTableConfiguration</key>
|
||||
<array>
|
||||
<string>MainColumn</string>
|
||||
<real>186</real>
|
||||
<real>299</real>
|
||||
</array>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>203 321 788 504 0 0 1440 878 </string>
|
||||
<string>18 337 788 504 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXSmartGroupTreeModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>203pt</string>
|
||||
<string>316pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Dock</key>
|
||||
|
|
@ -311,15 +314,13 @@
|
|||
<key>PBXProjectModuleGUID</key>
|
||||
<string>1CE0B20306471E060097A5F4</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MyNewFile14.java</string>
|
||||
<string><No Editor></string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>1CE0B20406471E060097A5F4</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MyNewFile14.java</string>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
<string>1</string>
|
||||
|
|
@ -330,14 +331,14 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {580, 269}}</string>
|
||||
<string>{{0, 0}, {467, 0}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>203 321 788 504 0 0 1440 878 </string>
|
||||
<string>18 337 788 504 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<key>Proportion</key>
|
||||
<string>269pt</string>
|
||||
<string>0pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>ContentConfiguration</key>
|
||||
|
|
@ -350,18 +351,18 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 274}, {580, 189}}</string>
|
||||
<string>{{0, 5}, {467, 458}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>203 321 788 504 0 0 1440 878 </string>
|
||||
<string>18 337 788 504 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>XCDetailModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>189pt</string>
|
||||
<string>458pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Proportion</key>
|
||||
<string>580pt</string>
|
||||
<string>467pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Name</key>
|
||||
|
|
@ -376,9 +377,9 @@
|
|||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>8B563EC9161B5E170067FE32</string>
|
||||
<string>8BDD47AA1A48BB8900FB2F61</string>
|
||||
<string>1CE0B1FE06471DED0097A5F4</string>
|
||||
<string>8B563ECA161B5E170067FE32</string>
|
||||
<string>8BDD47AB1A48BB8900FB2F61</string>
|
||||
<string>1CE0B20306471E060097A5F4</string>
|
||||
<string>1CE0B20506471E060097A5F4</string>
|
||||
</array>
|
||||
|
|
@ -517,10 +518,10 @@
|
|||
<key>WindowOrderList</key>
|
||||
<array>
|
||||
<string>8BD3CCBD148831C90062E48C</string>
|
||||
<string>/Developer/Library/Xcode/Project Templates/System Plug-in/Audio Unit Effect/Audio Unit Effect/StarterAU.xcodeproj</string>
|
||||
<string>/Developer/Library/Xcode/Project Templates/System Plug-in/Audio Unit Effect/Audio Unit Effect with Cocoa View/StarterAU.xcodeproj</string>
|
||||
</array>
|
||||
<key>WindowString</key>
|
||||
<string>203 321 788 504 0 0 1440 878 </string>
|
||||
<string>18 337 788 504 0 0 1440 878 </string>
|
||||
<key>WindowToolsV3</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
@ -597,7 +598,7 @@
|
|||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>8BD3CCBD148831C90062E48C</string>
|
||||
<string>8B563ECB161B5E170067FE32</string>
|
||||
<string>8BDD47AC1A48BB8900FB2F61</string>
|
||||
<string>1CD0528F0623707200166675</string>
|
||||
<string>XCMainBuildResultsModuleGUID</string>
|
||||
</array>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
|
||||
PBXFileTableDataSourceColumnWidthsKey = (
|
||||
20,
|
||||
292,
|
||||
364,
|
||||
20,
|
||||
48,
|
||||
43,
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
|
||||
PBXFileTableDataSourceColumnWidthsKey = (
|
||||
20,
|
||||
252,
|
||||
188,
|
||||
60,
|
||||
20,
|
||||
48,
|
||||
|
|
@ -49,14 +49,12 @@
|
|||
PBXFileDataSource_Warnings_ColumnID,
|
||||
);
|
||||
};
|
||||
PBXPerProjectTemplateStateSaveDate = 750255310;
|
||||
PBXWorkspaceStateSaveDate = 750255310;
|
||||
PBXPerProjectTemplateStateSaveDate = 751290936;
|
||||
PBXWorkspaceStateSaveDate = 751290936;
|
||||
};
|
||||
perUserProjectItems = {
|
||||
8BA3DC492CB5EC1900B899C2 /* PlistBookmark */ = 8BA3DC492CB5EC1900B899C2 /* PlistBookmark */;
|
||||
8BF17B272CB7FB4400FAAF3F /* PBXTextBookmark */ = 8BF17B272CB7FB4400FAAF3F /* PBXTextBookmark */;
|
||||
8BF17B702CB7FF3300FAAF3F /* PBXTextBookmark */ = 8BF17B702CB7FF3300FAAF3F /* PBXTextBookmark */;
|
||||
8BF17B712CB7FF3300FAAF3F /* PBXTextBookmark */ = 8BF17B712CB7FF3300FAAF3F /* PBXTextBookmark */;
|
||||
8BC4371D2CC70EE00098AE55 /* PBXTextBookmark */ = 8BC4371D2CC70EE00098AE55 /* PBXTextBookmark */;
|
||||
8BC437832CC7CCED0098AE55 /* PBXTextBookmark */ = 8BC437832CC7CCED0098AE55 /* PBXTextBookmark */;
|
||||
};
|
||||
sourceControlManager = 8BD3CCB8148830B20062E48C /* Source Control */;
|
||||
userBuildSettings = {
|
||||
|
|
@ -64,38 +62,53 @@
|
|||
};
|
||||
8BA05A660720730100365D66 /* Mastering.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {822, 7380}}";
|
||||
sepNavSelRange = "{17032, 0}";
|
||||
sepNavVisRange = "{15387, 90}";
|
||||
sepNavWindowFrame = "{{12, 53}, {1040, 821}}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {849, 18270}}";
|
||||
sepNavSelRange = "{31815, 0}";
|
||||
sepNavVisRange = "{31575, 221}";
|
||||
sepNavWindowFrame = "{{8, 49}, {1061, 821}}";
|
||||
};
|
||||
};
|
||||
8BA05A690720730100365D66 /* MasteringVersion.h */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1056, 1062}}";
|
||||
sepNavSelRange = "{2906, 0}";
|
||||
sepNavVisRange = "{1069, 1900}";
|
||||
sepNavWindowFrame = "{{15, 52}, {1040, 821}}";
|
||||
sepNavSelRange = "{2907, 0}";
|
||||
sepNavVisRange = "{1070, 1900}";
|
||||
sepNavWindowFrame = "{{15, 52}, {1061, 821}}";
|
||||
};
|
||||
};
|
||||
8BA3DC492CB5EC1900B899C2 /* PlistBookmark */ = {
|
||||
isa = PlistBookmark;
|
||||
fRef = 8D01CCD10486CAD60068D4B7 /* Info.plist */;
|
||||
fallbackIsa = PBXBookmark;
|
||||
isK = 0;
|
||||
kPath = (
|
||||
CFBundleName,
|
||||
);
|
||||
name = /Users/christopherjohnson/Desktop/Mastering/Info.plist;
|
||||
8BA05A7F072073D200365D66 /* AUBase.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {516, 23430}}";
|
||||
sepNavSelRange = "{0, 0}";
|
||||
sepNavVisRange = "{0, 1336}";
|
||||
};
|
||||
};
|
||||
8BC4371D2CC70EE00098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 8BA05A660720730100365D66 /* Mastering.cpp */;
|
||||
name = "Mastering.cpp: 693";
|
||||
rLen = 0;
|
||||
rLoc = 9223372036854775808;
|
||||
rLoc = 31815;
|
||||
rType = 0;
|
||||
vrLen = 252;
|
||||
vrLoc = 31544;
|
||||
};
|
||||
8BC437832CC7CCED0098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 8BA05A660720730100365D66 /* Mastering.cpp */;
|
||||
name = "Mastering.cpp: 693";
|
||||
rLen = 0;
|
||||
rLoc = 31815;
|
||||
rType = 0;
|
||||
vrLen = 221;
|
||||
vrLoc = 31575;
|
||||
};
|
||||
8BC6025B073B072D006C4272 /* Mastering.h */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1056, 3132}}";
|
||||
sepNavSelRange = "{3665, 0}";
|
||||
sepNavVisRange = "{2605, 1167}";
|
||||
sepNavWindowFrame = "{{38, 57}, {1040, 821}}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1146, 4950}}";
|
||||
sepNavSelRange = "{7725, 0}";
|
||||
sepNavVisRange = "{7429, 835}";
|
||||
sepNavWindowFrame = "{{26, 47}, {1061, 821}}";
|
||||
};
|
||||
};
|
||||
8BD3CCB8148830B20062E48C /* Source Control */ = {
|
||||
|
|
@ -112,36 +125,6 @@
|
|||
isa = PBXCodeSenseManager;
|
||||
indexTemplatePath = "";
|
||||
};
|
||||
8BF17B272CB7FB4400FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 8BA05A660720730100365D66 /* Mastering.cpp */;
|
||||
name = "Mastering.cpp: 347";
|
||||
rLen = 0;
|
||||
rLoc = 17032;
|
||||
rType = 0;
|
||||
vrLen = 38;
|
||||
vrLoc = 15492;
|
||||
};
|
||||
8BF17B702CB7FF3300FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 8BC6025B073B072D006C4272 /* Mastering.h */;
|
||||
name = "Mastering.h: 65";
|
||||
rLen = 0;
|
||||
rLoc = 3252;
|
||||
rType = 0;
|
||||
vrLen = 52;
|
||||
vrLoc = 3253;
|
||||
};
|
||||
8BF17B712CB7FF3300FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 8BA05A660720730100365D66 /* Mastering.cpp */;
|
||||
name = "Mastering.cpp: 347";
|
||||
rLen = 0;
|
||||
rLoc = 17032;
|
||||
rType = 0;
|
||||
vrLen = 90;
|
||||
vrLoc = 15387;
|
||||
};
|
||||
8D01CCC60486CAD60068D4B7 /* Mastering */ = {
|
||||
activeExec = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@
|
|||
<key>FavBarConfig</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8BD7274F1D46E5A5000176F0</string>
|
||||
<string>8BC435772CC6F8650098AE55</string>
|
||||
<key>XCBarModuleItemNames</key>
|
||||
<dict/>
|
||||
<key>XCBarModuleItems</key>
|
||||
|
|
@ -225,8 +225,8 @@
|
|||
<array/>
|
||||
<key>PerspectiveWidths</key>
|
||||
<array>
|
||||
<integer>841</integer>
|
||||
<integer>841</integer>
|
||||
<integer>810</integer>
|
||||
<integer>810</integer>
|
||||
</array>
|
||||
<key>Perspectives</key>
|
||||
<array>
|
||||
|
|
@ -282,7 +282,7 @@
|
|||
<dict>
|
||||
<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
|
||||
<array>
|
||||
<real>288</real>
|
||||
<real>185</real>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
|
||||
<array>
|
||||
|
|
@ -296,8 +296,6 @@
|
|||
<string>089C166AFE841209C02AAC07</string>
|
||||
<string>08FB77ADFE841716C02AAC07</string>
|
||||
<string>8BA05A56072072A900365D66</string>
|
||||
<string>089C167CFE841241C02AAC07</string>
|
||||
<string>1C37FBAC04509CD000000102</string>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
|
||||
<array>
|
||||
|
|
@ -309,7 +307,7 @@
|
|||
</array>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
|
||||
<string>{{0, 0}, {288, 595}}</string>
|
||||
<string>{{0, 0}, {185, 428}}</string>
|
||||
</dict>
|
||||
<key>PBXTopSmartGroupGIDs</key>
|
||||
<array/>
|
||||
|
|
@ -319,19 +317,19 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {305, 613}}</string>
|
||||
<string>{{0, 0}, {202, 446}}</string>
|
||||
<key>GroupTreeTableConfiguration</key>
|
||||
<array>
|
||||
<string>MainColumn</string>
|
||||
<real>288</real>
|
||||
<real>185</real>
|
||||
</array>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>8 177 841 654 0 0 1440 878 </string>
|
||||
<string>0 299 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXSmartGroupTreeModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>305pt</string>
|
||||
<string>202pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Dock</key>
|
||||
|
|
@ -340,7 +338,7 @@
|
|||
<key>ContentConfiguration</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8BD7274A1D46E5A5000176F0</string>
|
||||
<string>8BC435722CC6F8650098AE55</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>Mastering.cpp</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
|
|
@ -348,18 +346,16 @@
|
|||
<key>Split0</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8BD7274B1D46E5A5000176F0</string>
|
||||
<string>8BC435732CC6F8650098AE55</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>Mastering.cpp</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>8BF17B712CB7FF3300FAAF3F</string>
|
||||
<string>8BC437832CC7CCED0098AE55</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>8BA3DC492CB5EC1900B899C2</string>
|
||||
<string>8BF17B702CB7FF3300FAAF3F</string>
|
||||
<string>8BF17B272CB7FB4400FAAF3F</string>
|
||||
<string>8BC4371D2CC70EE00098AE55</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
|
|
@ -373,18 +369,18 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {531, 56}}</string>
|
||||
<string>{{0, 0}, {603, 86}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>8 177 841 654 0 0 1440 878 </string>
|
||||
<string>0 299 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<key>Proportion</key>
|
||||
<string>56pt</string>
|
||||
<string>86pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Proportion</key>
|
||||
<string>552pt</string>
|
||||
<string>355pt</string>
|
||||
<key>Tabs</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
@ -398,9 +394,9 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {531, 525}}</string>
|
||||
<string>{{10, 27}, {603, 328}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>8 177 841 654 0 0 1440 878 </string>
|
||||
<string>0 299 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>XCDetailModule</string>
|
||||
|
|
@ -454,7 +450,7 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {531, 507}}</string>
|
||||
<string>{{10, 27}, {603, 282}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXBuildResultsModule</string>
|
||||
|
|
@ -463,7 +459,7 @@
|
|||
</dict>
|
||||
</array>
|
||||
<key>Proportion</key>
|
||||
<string>531pt</string>
|
||||
<string>603pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Name</key>
|
||||
|
|
@ -482,11 +478,11 @@
|
|||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>8BF17B722CB7FF3300FAAF3F</string>
|
||||
<string>8BC437842CC7CCED0098AE55</string>
|
||||
<string>1CA23ED40692098700951B8B</string>
|
||||
<string>8BF17B732CB7FF3300FAAF3F</string>
|
||||
<string>8BD7274A1D46E5A5000176F0</string>
|
||||
<string>8BF17B742CB7FF3300FAAF3F</string>
|
||||
<string>8BC437852CC7CCED0098AE55</string>
|
||||
<string>8BC435722CC6F8650098AE55</string>
|
||||
<string>8BC437862CC7CCED0098AE55</string>
|
||||
<string>1CA23EDF0692099D00951B8B</string>
|
||||
<string>1CA23EE00692099D00951B8B</string>
|
||||
<string>1CA23EE10692099D00951B8B</string>
|
||||
|
|
@ -523,7 +519,7 @@
|
|||
<key>Identifier</key>
|
||||
<string>perspective.debug</string>
|
||||
<key>IsVertical</key>
|
||||
<true/>
|
||||
<integer>1</integer>
|
||||
<key>Layout</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
@ -542,7 +538,7 @@
|
|||
<key>Module</key>
|
||||
<string>PBXDebugCLIModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>0pt</string>
|
||||
<string>0%</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>ContentConfiguration</key>
|
||||
|
|
@ -561,8 +557,8 @@
|
|||
<string>yes</string>
|
||||
<key>sizes</key>
|
||||
<array>
|
||||
<string>{{0, 0}, {395, 214}}</string>
|
||||
<string>{{395, 0}, {415, 214}}</string>
|
||||
<string>{{0, 0}, {395, 213}}</string>
|
||||
<string>{{395, 0}, {415, 213}}</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>VerticalSplitView</key>
|
||||
|
|
@ -577,8 +573,8 @@
|
|||
<string>yes</string>
|
||||
<key>sizes</key>
|
||||
<array>
|
||||
<string>{{0, 0}, {810, 214}}</string>
|
||||
<string>{{0, 214}, {810, 227}}</string>
|
||||
<string>{{0, 0}, {810, 213}}</string>
|
||||
<string>{{0, 213}, {810, 225}}</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
|
|
@ -591,6 +587,8 @@
|
|||
</dict>
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>DebugConsoleDrawerSize</key>
|
||||
<string>{100, 120}</string>
|
||||
<key>DebugConsoleVisible</key>
|
||||
<string>None</string>
|
||||
<key>DebugConsoleWindowFrame</key>
|
||||
|
|
@ -598,54 +596,32 @@
|
|||
<key>DebugSTDIOWindowFrame</key>
|
||||
<string>{{200, 200}, {500, 300}}</string>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 5}, {810, 441}}</string>
|
||||
<key>PBXDebugSessionStackFrameViewKey</key>
|
||||
<dict>
|
||||
<key>DebugVariablesTableConfiguration</key>
|
||||
<array>
|
||||
<string>Name</string>
|
||||
<real>120</real>
|
||||
<string>Value</string>
|
||||
<real>85</real>
|
||||
<string>Summary</string>
|
||||
<real>185</real>
|
||||
</array>
|
||||
<key>Frame</key>
|
||||
<string>{{395, 0}, {415, 214}}</string>
|
||||
</dict>
|
||||
<string>{{0, 7}, {810, 438}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXDebugSessionModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>441pt</string>
|
||||
<string>443pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Name</key>
|
||||
<string>Debug</string>
|
||||
<key>ServiceClasses</key>
|
||||
<array>
|
||||
<string>XCModuleDock</string>
|
||||
<string>XCModuleDock</string>
|
||||
<string>PBXDebugCLIModule</string>
|
||||
<string>PBXDebugSessionModule</string>
|
||||
<string>PBXDebugProcessAndThreadModule</string>
|
||||
<string>PBXDebugProcessViewModule</string>
|
||||
<string>PBXDebugThreadViewModule</string>
|
||||
<string>PBXDebugStackFrameViewModule</string>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<string>XCConsole</string>
|
||||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>8BD727EC1D46ECF1000176F0</string>
|
||||
<string>1CC8E6A5069209BD00BB180A</string>
|
||||
<string>1CC8E6A6069209BD00BB180A</string>
|
||||
<string>1CCC7628064C1048000F2A68</string>
|
||||
<string>1CCC7629064C1048000F2A68</string>
|
||||
<string>8BD727ED1D46ECF1000176F0</string>
|
||||
<string>8BD727EE1D46ECF1000176F0</string>
|
||||
<string>8BD727EF1D46ECF1000176F0</string>
|
||||
<string>8BD727F01D46ECF1000176F0</string>
|
||||
<string>8BD727E71D46ECD9000176F0</string>
|
||||
<string>1CC8E6A7069209BD00BB180A</string>
|
||||
</array>
|
||||
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
||||
<string>2</string>
|
||||
<key>ToolbarConfiguration</key>
|
||||
<string>xcode.toolbar.config.debugV3</string>
|
||||
</dict>
|
||||
|
|
@ -659,7 +635,7 @@
|
|||
<key>StatusbarIsVisible</key>
|
||||
<true/>
|
||||
<key>TimeStamp</key>
|
||||
<real>750255923.53302801</real>
|
||||
<real>751291629.93373895</real>
|
||||
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
||||
<string>2</string>
|
||||
<key>ToolbarDisplayMode</key>
|
||||
|
|
@ -676,11 +652,11 @@
|
|||
<integer>5</integer>
|
||||
<key>WindowOrderList</key>
|
||||
<array>
|
||||
<string>8BF17B752CB7FF3300FAAF3F</string>
|
||||
<string>8BC437872CC7CCED0098AE55</string>
|
||||
<string>/Users/christopherjohnson/Desktop/airwindows/plugins/MacAU/Mastering/Mastering.xcodeproj</string>
|
||||
</array>
|
||||
<key>WindowString</key>
|
||||
<string>8 177 841 654 0 0 1440 878 </string>
|
||||
<string>0 299 810 487 0 0 1440 878 </string>
|
||||
<key>WindowToolsV3</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Version: 1.0
|
||||
*
|
||||
* Created: 10/8/24
|
||||
* Created: 10/21/24
|
||||
*
|
||||
* Copyright: Copyright © 2024 Airwindows, Airwindows uses the MIT license
|
||||
*
|
||||
|
|
|
|||
5
plugins/MacAU/Mastering/StarterAU_Prefix.pch
Executable file
5
plugins/MacAU/Mastering/StarterAU_Prefix.pch
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
//
|
||||
// Prefix header for all source files of the '«PROJECTNAMEASIDENTIFIER»' target in the '«PROJECTNAMEASIDENTIFIER»' project.
|
||||
//
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>DthX</string>
|
||||
<string>Dthr</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Version: 1.0
|
||||
*
|
||||
* Created: 10/8/24
|
||||
* Created: 10/21/24
|
||||
*
|
||||
* Copyright: Copyright © 2024 Airwindows, Airwindows uses the MIT license
|
||||
*
|
||||
|
|
@ -68,6 +68,7 @@ Mastering::Mastering(AudioUnit component)
|
|||
SetParameter(kParam_G, kDefaultValue_ParamG );
|
||||
SetParameter(kParam_H, kDefaultValue_ParamH );
|
||||
SetParameter(kParam_I, kDefaultValue_ParamI );
|
||||
SetParameter(kParam_J, kDefaultValue_ParamJ );
|
||||
|
||||
#if AU_DEBUG_DISPATCHER
|
||||
mDebugDispatcher = new AUDebugDispatcher (this);
|
||||
|
|
@ -83,7 +84,26 @@ ComponentResult Mastering::GetParameterValueStrings(AudioUnitScope inScope,
|
|||
AudioUnitParameterID inParameterID,
|
||||
CFArrayRef * outStrings)
|
||||
{
|
||||
|
||||
if ((inScope == kAudioUnitScope_Global) && (inParameterID == kParam_J)) //ID must be actual name of parameter identifier, not number
|
||||
{
|
||||
if (outStrings == NULL) return noErr;
|
||||
CFStringRef strings [] =
|
||||
{
|
||||
kMenuItem_Dark,
|
||||
kMenuItem_TenNines,
|
||||
kMenuItem_TPDFWide,
|
||||
kMenuItem_PaulWide,
|
||||
kMenuItem_NJAD,
|
||||
kMenuItem_Bypass,
|
||||
};
|
||||
*outStrings = CFArrayCreate (
|
||||
NULL,
|
||||
(const void **) strings,
|
||||
(sizeof (strings) / sizeof (strings [0])),
|
||||
NULL
|
||||
);
|
||||
return noErr;
|
||||
}
|
||||
return kAudioUnitErr_InvalidProperty;
|
||||
}
|
||||
|
||||
|
|
@ -167,7 +187,14 @@ ComponentResult Mastering::GetParameterInfo(AudioUnitScope inScope,
|
|||
outParameterInfo.maxValue = 1.0;
|
||||
outParameterInfo.defaultValue = kDefaultValue_ParamI;
|
||||
break;
|
||||
default:
|
||||
case kParam_J:
|
||||
AUBase::FillInParameterName (outParameterInfo, kParameterJName, false);
|
||||
outParameterInfo.unit = kAudioUnitParameterUnit_Indexed;
|
||||
outParameterInfo.minValue = kDark;
|
||||
outParameterInfo.maxValue = kBypass;
|
||||
outParameterInfo.defaultValue = kDefaultValue_ParamJ;
|
||||
break;
|
||||
default:
|
||||
result = kAudioUnitErr_InvalidParameter;
|
||||
break;
|
||||
}
|
||||
|
|
@ -192,6 +219,21 @@ ComponentResult Mastering::GetPropertyInfo (AudioUnitPropertyID inID,
|
|||
return AUEffectBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// state that plugin supports only stereo-in/stereo-out processing
|
||||
UInt32 Mastering::SupportedNumChannels(const AUChannelInfo ** outInfo)
|
||||
{
|
||||
if (outInfo != NULL)
|
||||
{
|
||||
static AUChannelInfo info;
|
||||
info.inChannels = 2;
|
||||
info.outChannels = 2;
|
||||
*outInfo = &info;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Mastering::GetProperty
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -220,31 +262,96 @@ ComponentResult Mastering::Initialize()
|
|||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Mastering::MasteringKernel::Reset()
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
void Mastering::MasteringKernel::Reset()
|
||||
ComponentResult Mastering::Reset(AudioUnitScope inScope, AudioUnitElement inElement)
|
||||
{
|
||||
for (int x = 0; x < air_total; x++) air[x] = 0.0;
|
||||
for (int x = 0; x < kal_total; x++) {kalM[x] = 0.0;kalS[x] = 0.0;}
|
||||
|
||||
lastSinewL = 0.0;
|
||||
lastSample = 0.0;
|
||||
wasPosClip = false;
|
||||
wasNegClip = false;
|
||||
for (int x = 0; x < 16; x++) {intermediate[x] = 0.0;}
|
||||
|
||||
fpd = 1.0; while (fpd < 16386) fpd = rand()*UINT32_MAX;
|
||||
lastSinewR = 0.0;
|
||||
|
||||
lastSampleL = 0.0;
|
||||
wasPosClipL = false;
|
||||
wasNegClipL = false;
|
||||
lastSampleR = 0.0;
|
||||
wasPosClipR = false;
|
||||
wasNegClipR = false;
|
||||
for (int x = 0; x < 16; x++) {intermediateL[x] = 0.0; intermediateR[x] = 0.0;}
|
||||
|
||||
quantA = 0;
|
||||
quantB = 1;
|
||||
expectedSlew = 0.0;
|
||||
testA = 0.0;
|
||||
testB = 0.0;
|
||||
correction = 0.0;
|
||||
shapedSampleL = 0.0;
|
||||
shapedSampleR = 0.0;
|
||||
currentDither = 0.0;
|
||||
ditherL = 0.0;
|
||||
ditherR = 0.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
hotbinA = 0;
|
||||
hotbinB = 0;
|
||||
benfordize = 0.0;
|
||||
totalA = 0.0;
|
||||
totalB = 0.0;
|
||||
outputSample = 0.0;
|
||||
expon = 0; //internal dither variables
|
||||
//these didn't like to be defined inside a case statement
|
||||
|
||||
NSOddL = 0.0; NSEvenL = 0.0; prevShapeL = 0.0;
|
||||
NSOddR = 0.0; NSEvenR = 0.0; prevShapeR = 0.0;
|
||||
flip = true; //Ten Nines
|
||||
for(int count = 0; count < 99; count++) {
|
||||
darkSampleL[count] = 0;
|
||||
darkSampleR[count] = 0;
|
||||
} //Dark
|
||||
previousDitherL = 0.0;
|
||||
previousDitherR = 0.0; //PaulWide
|
||||
bynL[0] = 1000.0;
|
||||
bynL[1] = 301.0;
|
||||
bynL[2] = 176.0;
|
||||
bynL[3] = 125.0;
|
||||
bynL[4] = 97.0;
|
||||
bynL[5] = 79.0;
|
||||
bynL[6] = 67.0;
|
||||
bynL[7] = 58.0;
|
||||
bynL[8] = 51.0;
|
||||
bynL[9] = 46.0;
|
||||
bynL[10] = 1000.0;
|
||||
noiseShapingL = 0.0;
|
||||
bynR[0] = 1000.0;
|
||||
bynR[1] = 301.0;
|
||||
bynR[2] = 176.0;
|
||||
bynR[3] = 125.0;
|
||||
bynR[4] = 97.0;
|
||||
bynR[5] = 79.0;
|
||||
bynR[6] = 67.0;
|
||||
bynR[7] = 58.0;
|
||||
bynR[8] = 51.0;
|
||||
bynR[9] = 46.0;
|
||||
bynR[10] = 1000.0;
|
||||
noiseShapingR = 0.0; //NJAD
|
||||
|
||||
fpdL = 1.0; while (fpdL < 16386) fpdL = rand()*UINT32_MAX;
|
||||
fpdR = 1.0; while (fpdR < 16386) fpdR = rand()*UINT32_MAX;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Mastering::MasteringKernel::Process
|
||||
// Mastering::ProcessBufferLists
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
||||
Float32 *inDestP,
|
||||
UInt32 inFramesToProcess,
|
||||
UInt32 inNumChannels,
|
||||
bool &ioSilence )
|
||||
OSStatus Mastering::ProcessBufferLists(AudioUnitRenderActionFlags & ioActionFlags,
|
||||
const AudioBufferList & inBuffer,
|
||||
AudioBufferList & outBuffer,
|
||||
UInt32 inFramesToProcess)
|
||||
{
|
||||
Float32 * inputL = (Float32*)(inBuffer.mBuffers[0].mData);
|
||||
Float32 * inputR = (Float32*)(inBuffer.mBuffers[1].mData);
|
||||
Float32 * outputL = (Float32*)(outBuffer.mBuffers[0].mData);
|
||||
Float32 * outputR = (Float32*)(outBuffer.mBuffers[1].mData);
|
||||
UInt32 nSampleFrames = inFramesToProcess;
|
||||
const Float32 *sourceP = inSourceP;
|
||||
Float32 *destP = inDestP;
|
||||
double overallscale = 1.0;
|
||||
overallscale /= 44100.0;
|
||||
overallscale *= GetSampleRate();
|
||||
|
|
@ -267,11 +374,18 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
double depthSinew = GetParameter( kParam_I );
|
||||
int spacing = floor(overallscale); //should give us working basic scaling, usually 2 or 4
|
||||
if (spacing < 1) spacing = 1; if (spacing > 16) spacing = 16;
|
||||
int dither = (int) GetParameter( kParam_J );
|
||||
int depth = (int)(17.0*overallscale);
|
||||
if (depth < 3) depth = 3;
|
||||
if (depth > 98) depth = 98; //for Dark
|
||||
|
||||
while (nSampleFrames-- > 0) {
|
||||
long double inputSampleL = *sourceP;
|
||||
if (fabs(inputSampleL)<1.18e-23) inputSampleL = fpd * 1.18e-17;
|
||||
double inputSampleL = *inputL;
|
||||
double inputSampleR = *inputR;
|
||||
if (fabs(inputSampleL)<1.18e-23) inputSampleL = fpdL * 1.18e-17;
|
||||
if (fabs(inputSampleR)<1.18e-23) inputSampleR = fpdR * 1.18e-17;
|
||||
double drySampleL = inputSampleL;
|
||||
double drySampleR = inputSampleR;
|
||||
|
||||
//begin Air3L
|
||||
air[pvSL4] = air[pvAL4] - air[pvAL3]; air[pvSL3] = air[pvAL3] - air[pvAL2];
|
||||
|
|
@ -286,10 +400,25 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
air[pvAL2] = air[pvAL1]; air[pvAL1] = (air[gainAL] * air[outAL]) + drySampleL;
|
||||
long double midL = drySampleL - ((air[outAL]*0.5)+(drySampleL*(0.457-(0.017*overallscale))));
|
||||
long double temp = (midL + air[gndavgL])*0.5; air[gndavgL] = midL; midL = temp;
|
||||
//we have a single averaging stage to smooth stuff out
|
||||
long double trebleL = drySampleL-midL;
|
||||
//end Air3L
|
||||
|
||||
//begin Air3R
|
||||
air[pvSR4] = air[pvAR4] - air[pvAR3]; air[pvSR3] = air[pvAR3] - air[pvAR2];
|
||||
air[pvSR2] = air[pvAR2] - air[pvAR1]; air[pvSR1] = air[pvAR1] - inputSampleR;
|
||||
air[accSR3] = air[pvSR4] - air[pvSR3]; air[accSR2] = air[pvSR3] - air[pvSR2];
|
||||
air[accSR1] = air[pvSR2] - air[pvSR1];
|
||||
air[acc2SR2] = air[accSR3] - air[accSR2]; air[acc2SR1] = air[accSR2] - air[accSR1];
|
||||
air[outAR] = -(air[pvAR1] + air[pvSR3] + air[acc2SR2] - ((air[acc2SR2] + air[acc2SR1])*0.5));
|
||||
air[gainAR] *= 0.5; air[gainAR] += fabs(drySampleR-air[outAR])*0.5;
|
||||
if (air[gainAR] > 0.3*sqrt(overallscale)) air[gainAR] = 0.3*sqrt(overallscale);
|
||||
air[pvAR4] = air[pvAR3]; air[pvAR3] = air[pvAR2];
|
||||
air[pvAR2] = air[pvAR1]; air[pvAR1] = (air[gainAR] * air[outAR]) + drySampleR;
|
||||
long double midR = drySampleR - ((air[outAR]*0.5)+(drySampleR*(0.457-(0.017*overallscale))));
|
||||
temp = (midR + air[gndavgR])*0.5; air[gndavgR] = midR; midR = temp;
|
||||
long double trebleR = drySampleR-midR;
|
||||
//end Air3R
|
||||
|
||||
//begin KalmanML
|
||||
temp = midL;
|
||||
kalM[prevSlewL3] += kalM[prevSampL3] - kalM[prevSampL2]; kalM[prevSlewL3] *= 0.5;
|
||||
|
|
@ -302,7 +431,7 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
kalM[accSlewL3] += (kalM[accSlewL2] - kalM[accSlewL1]); kalM[accSlewL3] *= 0.5;
|
||||
//entering the abyss, what even is this
|
||||
kalM[kalOutL] += kalM[prevSampL1] + kalM[prevSlewL2] + kalM[accSlewL3]; kalM[kalOutL] *= 0.5;
|
||||
|
||||
|
||||
//resynthesizing predicted result (all iir smoothed)
|
||||
kalM[kalGainL] += fabs(temp-kalM[kalOutL])*kalMid*8.0; kalM[kalGainL] *= 0.5;
|
||||
//madness takes its toll. Kalman Gain: how much dry to retain
|
||||
|
|
@ -318,6 +447,34 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
midL -= bassL;
|
||||
//end KalmanML
|
||||
|
||||
//begin KalmanMR
|
||||
temp = midR;
|
||||
kalM[prevSlewR3] += kalM[prevSampR3] - kalM[prevSampR2]; kalM[prevSlewR3] *= 0.5;
|
||||
kalM[prevSlewR2] += kalM[prevSampR2] - kalM[prevSampR1]; kalM[prevSlewR2] *= 0.5;
|
||||
kalM[prevSlewR1] += kalM[prevSampR1] - midR; kalM[prevSlewR1] *= 0.5;
|
||||
//make slews from each set of samples used
|
||||
kalM[accSlewR2] += kalM[prevSlewR3] - kalM[prevSlewR2]; kalM[accSlewR2] *= 0.5;
|
||||
kalM[accSlewR1] += kalM[prevSlewR2] - kalM[prevSlewR1]; kalM[accSlewR1] *= 0.5;
|
||||
//differences between slews: rate of change of rate of change
|
||||
kalM[accSlewR3] += (kalM[accSlewR2] - kalM[accSlewR1]); kalM[accSlewR3] *= 0.5;
|
||||
//entering the abyss, what even is this
|
||||
kalM[kalOutR] += kalM[prevSampR1] + kalM[prevSlewR2] + kalM[accSlewR3]; kalM[kalOutR] *= 0.5;
|
||||
|
||||
//resynthesizing predicted result (all iir smoothed)
|
||||
kalM[kalGainR] += fabs(temp-kalM[kalOutR])*kalMid*8.0; kalM[kalGainR] *= 0.5;
|
||||
//madness takes its toll. Kalman Gain: how much dry to retain
|
||||
if (kalM[kalGainR] > kalMid*0.5) kalM[kalGainR] = kalMid*0.5;
|
||||
//attempts to avoid explosions
|
||||
kalM[kalOutR] += (temp*(1.0-(0.68+(kalMid*0.157))));
|
||||
//this is for tuning a really complete cancellation up around Nyquist
|
||||
kalM[prevSampR3] = kalM[prevSampR2]; kalM[prevSampR2] = kalM[prevSampR1];
|
||||
kalM[prevSampR1] = (kalM[kalGainR] * kalM[kalOutR]) + ((1.0-kalM[kalGainR])*temp);
|
||||
//feed the chain of previous samples
|
||||
long double bassR = (kalM[kalOutR]+kalM[kalAvgR])*0.5;
|
||||
kalM[kalAvgR] = kalM[kalOutR];
|
||||
midR -= bassR;
|
||||
//end KalmanMR
|
||||
|
||||
//begin KalmanSL
|
||||
temp = bassL;
|
||||
kalS[prevSlewL3] += kalS[prevSampL3] - kalS[prevSampL2]; kalS[prevSlewL3] *= 0.5;
|
||||
|
|
@ -345,44 +502,100 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
bassL -= subL;
|
||||
//end KalmanSL
|
||||
|
||||
//begin KalmanSR
|
||||
temp = bassR;
|
||||
kalS[prevSlewR3] += kalS[prevSampR3] - kalS[prevSampR2]; kalS[prevSlewR3] *= 0.5;
|
||||
kalS[prevSlewR2] += kalS[prevSampR2] - kalS[prevSampR1]; kalS[prevSlewR2] *= 0.5;
|
||||
kalS[prevSlewR1] += kalS[prevSampR1] - bassR; kalS[prevSlewR1] *= 0.5;
|
||||
//make slews from each set of samples used
|
||||
kalS[accSlewR2] += kalS[prevSlewR3] - kalS[prevSlewR2]; kalS[accSlewR2] *= 0.5;
|
||||
kalS[accSlewR1] += kalS[prevSlewR2] - kalS[prevSlewR1]; kalS[accSlewR1] *= 0.5;
|
||||
//differences between slews: rate of change of rate of change
|
||||
kalS[accSlewR3] += (kalS[accSlewR2] - kalS[accSlewR1]); kalS[accSlewR3] *= 0.5;
|
||||
//entering the abyss, what even is this
|
||||
kalS[kalOutR] += kalS[prevSampR1] + kalS[prevSlewR2] + kalS[accSlewR3]; kalS[kalOutR] *= 0.5;
|
||||
//resynthesizing predicted result (all iir smoothed)
|
||||
kalS[kalGainR] += fabs(temp-kalS[kalOutR])*kalSub*8.0; kalS[kalGainR] *= 0.5;
|
||||
//madness takes its toll. Kalman Gain: how much dry to retain
|
||||
if (kalS[kalGainR] > kalSub*0.5) kalS[kalGainR] = kalSub*0.5;
|
||||
//attempts to avoid explosions
|
||||
kalS[kalOutR] += (temp*(1.0-(0.68+(kalSub*0.157))));
|
||||
//this is for tuning a really complete cancellation up around Nyquist
|
||||
kalS[prevSampR3] = kalS[prevSampR2]; kalS[prevSampR2] = kalS[prevSampR1];
|
||||
kalS[prevSampR1] = (kalS[kalGainR] * kalS[kalOutR]) + ((1.0-kalS[kalGainR])*temp);
|
||||
//feed the chain of previous samples
|
||||
long double subR = (kalS[kalOutR]+kalS[kalAvgR])*0.5;
|
||||
kalS[kalAvgR] = kalS[kalOutR];
|
||||
bassR -= subR;
|
||||
//end KalmanSR
|
||||
|
||||
inputSampleL = (subL*subGain);
|
||||
inputSampleL += (bassL*bassGain);
|
||||
inputSampleL += (midL*midGain);
|
||||
inputSampleL += (trebleL*trebleGain);
|
||||
inputSampleR = (subR*subGain);
|
||||
inputSampleR += (bassR*bassGain);
|
||||
inputSampleR += (midR*midGain);
|
||||
inputSampleR += (trebleR*trebleGain);
|
||||
|
||||
for (int count = 0; count < zoomStages; count++) {
|
||||
if (zoom > 0.0) {
|
||||
long double closer = inputSampleL * 1.57079633;
|
||||
double closer = inputSampleL * 1.57079633;
|
||||
if (closer > 1.57079633) closer = 1.57079633;
|
||||
if (closer < -1.57079633) closer = -1.57079633;
|
||||
inputSampleL = (inputSampleL*(1.0-zoom))+(sin(closer)*zoom);
|
||||
closer = inputSampleR * 1.57079633;
|
||||
if (closer > 1.57079633) closer = 1.57079633;
|
||||
if (closer < -1.57079633) closer = -1.57079633;
|
||||
inputSampleR = (inputSampleR*(1.0-zoom))+(sin(closer)*zoom);
|
||||
} //zooming in will make the body of the sound louder: it's just Density
|
||||
if (zoom < 0.0) {
|
||||
long double farther = fabs(inputSampleL) * 1.57079633;
|
||||
double farther = fabs(inputSampleL) * 1.57079633;
|
||||
if (farther > 1.57079633) farther = 1.0;
|
||||
else farther = 1.0-cos(farther);
|
||||
if (inputSampleL > 0.0) inputSampleL = (inputSampleL*(1.0+zoom))-(farther*zoom*1.57079633);
|
||||
if (inputSampleL < 0.0) inputSampleL = (inputSampleL*(1.0+zoom))+(farther*zoom*1.57079633);
|
||||
farther = fabs(inputSampleR) * 1.57079633;
|
||||
if (farther > 1.57079633) farther = 1.0;
|
||||
else farther = 1.0-cos(farther);
|
||||
if (inputSampleR > 0.0) inputSampleR = (inputSampleR*(1.0+zoom))-(farther*zoom*1.57079633);
|
||||
if (inputSampleR < 0.0) inputSampleR = (inputSampleR*(1.0+zoom))+(farther*zoom*1.57079633);
|
||||
} //zooming out boosts the hottest peaks but cuts back softer stuff
|
||||
}
|
||||
|
||||
//begin ClipOnly2 as a little, compressed chunk that can be dropped into code
|
||||
//begin ClipOnly2 stereo as a little, compressed chunk that can be dropped into code
|
||||
if (inputSampleL > 4.0) inputSampleL = 4.0; if (inputSampleL < -4.0) inputSampleL = -4.0;
|
||||
if (wasPosClip == true) { //current will be over
|
||||
if (inputSampleL<lastSample) lastSample=0.7058208+(inputSampleL*0.2609148);
|
||||
else lastSample = 0.2491717+(lastSample*0.7390851);
|
||||
} wasPosClip = false;
|
||||
if (inputSampleL>0.9549925859) {wasPosClip=true;inputSampleL=0.7058208+(lastSample*0.2609148);}
|
||||
if (wasNegClip == true) { //current will be -over
|
||||
if (inputSampleL > lastSample) lastSample=-0.7058208+(inputSampleL*0.2609148);
|
||||
else lastSample=-0.2491717+(lastSample*0.7390851);
|
||||
} wasNegClip = false;
|
||||
if (inputSampleL<-0.9549925859) {wasNegClip=true;inputSampleL=-0.7058208+(lastSample*0.2609148);}
|
||||
intermediate[spacing] = inputSampleL;
|
||||
inputSampleL = lastSample; //Latency is however many samples equals one 44.1k sample
|
||||
for (int x = spacing; x > 0; x--) intermediate[x-1] = intermediate[x];
|
||||
lastSample = intermediate[0]; //run a little buffer to handle this
|
||||
//end ClipOnly2 as a little, compressed chunk that can be dropped into code
|
||||
if (wasPosClipL == true) { //current will be over
|
||||
if (inputSampleL<lastSampleL) lastSampleL=0.7058208+(inputSampleL*0.2609148);
|
||||
else lastSampleL = 0.2491717+(lastSampleL*0.7390851);
|
||||
} wasPosClipL = false;
|
||||
if (inputSampleL>0.9549925859) {wasPosClipL=true;inputSampleL=0.7058208+(lastSampleL*0.2609148);}
|
||||
if (wasNegClipL == true) { //current will be -over
|
||||
if (inputSampleL > lastSampleL) lastSampleL=-0.7058208+(inputSampleL*0.2609148);
|
||||
else lastSampleL=-0.2491717+(lastSampleL*0.7390851);
|
||||
} wasNegClipL = false;
|
||||
if (inputSampleL<-0.9549925859) {wasNegClipL=true;inputSampleL=-0.7058208+(lastSampleL*0.2609148);}
|
||||
intermediateL[spacing] = inputSampleL;
|
||||
inputSampleL = lastSampleL; //Latency is however many samples equals one 44.1k sample
|
||||
for (int x = spacing; x > 0; x--) intermediateL[x-1] = intermediateL[x];
|
||||
lastSampleL = intermediateL[0]; //run a little buffer to handle this
|
||||
|
||||
if (inputSampleR > 4.0) inputSampleR = 4.0; if (inputSampleR < -4.0) inputSampleR = -4.0;
|
||||
if (wasPosClipR == true) { //current will be over
|
||||
if (inputSampleR<lastSampleR) lastSampleR=0.7058208+(inputSampleR*0.2609148);
|
||||
else lastSampleR = 0.2491717+(lastSampleR*0.7390851);
|
||||
} wasPosClipR = false;
|
||||
if (inputSampleR>0.9549925859) {wasPosClipR=true;inputSampleR=0.7058208+(lastSampleR*0.2609148);}
|
||||
if (wasNegClipR == true) { //current will be -over
|
||||
if (inputSampleR > lastSampleR) lastSampleR=-0.7058208+(inputSampleR*0.2609148);
|
||||
else lastSampleR=-0.2491717+(lastSampleR*0.7390851);
|
||||
} wasNegClipR = false;
|
||||
if (inputSampleR<-0.9549925859) {wasNegClipR=true;inputSampleR=-0.7058208+(lastSampleR*0.2609148);}
|
||||
intermediateR[spacing] = inputSampleR;
|
||||
inputSampleR = lastSampleR; //Latency is however many samples equals one 44.1k sample
|
||||
for (int x = spacing; x > 0; x--) intermediateR[x-1] = intermediateR[x];
|
||||
lastSampleR = intermediateR[0]; //run a little buffer to handle this
|
||||
//end ClipOnly2 stereo as a little, compressed chunk that can be dropped into code
|
||||
|
||||
temp = inputSampleL;
|
||||
long double sinew = threshSinew * cos(lastSinewL*lastSinewL);
|
||||
|
|
@ -390,17 +603,405 @@ void Mastering::MasteringKernel::Process( const Float32 *inSourceP,
|
|||
if (-(inputSampleL - lastSinewL) > sinew) temp = lastSinewL - sinew;
|
||||
lastSinewL = temp;
|
||||
inputSampleL = (inputSampleL * (1.0-depthSinew))+(lastSinewL*depthSinew);
|
||||
temp = inputSampleR;
|
||||
sinew = threshSinew * cos(lastSinewR*lastSinewR);
|
||||
if (inputSampleR - lastSinewR > sinew) temp = lastSinewR + sinew;
|
||||
if (-(inputSampleR - lastSinewR) > sinew) temp = lastSinewR - sinew;
|
||||
lastSinewR = temp;
|
||||
inputSampleR = (inputSampleR * (1.0-depthSinew))+(lastSinewR*depthSinew);
|
||||
//run Sinew to stop excess slews, but run a dry/wet to allow a range of brights
|
||||
|
||||
//begin 32 bit floating point dither
|
||||
int expon; frexpf((float)inputSampleL, &expon);
|
||||
fpd ^= fpd << 13; fpd ^= fpd >> 17; fpd ^= fpd << 5;
|
||||
inputSampleL += ((double(fpd)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit floating point dither
|
||||
switch (dither) {
|
||||
case 1:
|
||||
//begin Dark
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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
|
||||
quantA = floor(inputSampleL);
|
||||
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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark 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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark right
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Dark (Monitoring2)
|
||||
case 2:
|
||||
//begin Dark for Ten Nines
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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 L
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddL = (NSOddL * 0.9999999999) + prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) - prevShapeL;
|
||||
correction = NSOddL;
|
||||
} else {
|
||||
NSOddL = (NSOddL * 0.9999999999) - prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) + prevShapeL;
|
||||
correction = NSEvenL;
|
||||
}
|
||||
shapedSampleL = inputSampleL+correction;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin Dark L
|
||||
quantA = floor(shapedSampleL);
|
||||
quantB = floor(shapedSampleL+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark L
|
||||
|
||||
prevShapeL = (floor(shapedSampleL) - inputSampleL)*0.9999999999;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin R
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddR = (NSOddR * 0.9999999999) + prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) - prevShapeR;
|
||||
correction = NSOddR;
|
||||
} else {
|
||||
NSOddR = (NSOddR * 0.9999999999) - prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) + prevShapeR;
|
||||
correction = NSEvenR;
|
||||
}
|
||||
shapedSampleR = inputSampleR+correction;
|
||||
//end Ten Nines R
|
||||
|
||||
//begin Dark R
|
||||
quantA = floor(shapedSampleR);
|
||||
quantB = floor(shapedSampleR+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark R
|
||||
|
||||
prevShapeR = (floor(shapedSampleR) - inputSampleR)*0.9999999999;
|
||||
//end Ten Nines
|
||||
flip = !flip;
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Ten Nines (which goes into Dark in Monitoring3)
|
||||
case 3:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //TPDFWide (a good neutral with the width enhancement)
|
||||
case 4:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
//Paul Frindle: It's true that the dither itself can sound different
|
||||
//if it's given a different freq response and you get to hear it.
|
||||
//The one we use most is triangular single pole high pass dither.
|
||||
//It's not freq bent enough to sound odd, but is slightly less audible than
|
||||
//flat dither. It can also be easily made by taking one sample of dither
|
||||
//away from the previous one - this gives you the triangular PDF and the
|
||||
//filtering in one go :-)
|
||||
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //PaulWide (brighter neutral that's still TPDF and wide)
|
||||
case 5:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
drySampleL = inputSampleL;//re-using in NJAD
|
||||
inputSampleL -= noiseShapingL;
|
||||
//NJAD L
|
||||
benfordize = floor(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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);
|
||||
inputSampleL /= 8388608.0;
|
||||
if (inputSampleL > 1.0) inputSampleL = 1.0;
|
||||
if (inputSampleL < -1.0) inputSampleL = -1.0;
|
||||
//finished NJAD L
|
||||
|
||||
//NJAD R
|
||||
drySampleR = inputSampleR;
|
||||
inputSampleR -= noiseShapingR;
|
||||
benfordize = floor(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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
|
||||
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);
|
||||
inputSampleR /= 8388608.0;
|
||||
if (inputSampleR > 1.0) inputSampleR = 1.0;
|
||||
if (inputSampleR < -1.0) inputSampleR = -1.0;
|
||||
break; //NJAD (Monitoring. Brightest)
|
||||
case 6:
|
||||
//begin 32 bit stereo floating point dither
|
||||
frexpf((float)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
frexpf((float)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit stereo floating point dither
|
||||
break; //Bypass for saving floating point files directly
|
||||
}
|
||||
|
||||
*destP = inputSampleL;
|
||||
*outputL = inputSampleL;
|
||||
*outputR = inputSampleR;
|
||||
//direct stereo out
|
||||
|
||||
sourceP += inNumChannels; destP += inNumChannels;
|
||||
inputL += 1;
|
||||
inputR += 1;
|
||||
outputL += 1;
|
||||
outputR += 1;
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Version: 1.0
|
||||
*
|
||||
* Created: 10/8/24
|
||||
* Created: 10/21/24
|
||||
*
|
||||
* Copyright: Copyright © 2024 Airwindows, Airwindows uses the MIT license
|
||||
*
|
||||
|
|
@ -63,6 +63,20 @@ static const float kDefaultValue_ParamF = 0.5;
|
|||
static const float kDefaultValue_ParamG = 0.5;
|
||||
static const float kDefaultValue_ParamH = 0.5;
|
||||
static const float kDefaultValue_ParamI = 0.0;
|
||||
static const int kDark = 1;
|
||||
static const int kTenNines = 2;
|
||||
static const int kTPDFWide = 3;
|
||||
static const int kPaulWide = 4;
|
||||
static const int kNJAD = 5;
|
||||
static const int kBypass = 6;
|
||||
static const int kDefaultValue_ParamJ = kBypass;
|
||||
|
||||
static CFStringRef kMenuItem_Dark = CFSTR ("Dark");
|
||||
static CFStringRef kMenuItem_TenNines = CFSTR ("Ten Nines");
|
||||
static CFStringRef kMenuItem_TPDFWide = CFSTR ("TPDFWide");
|
||||
static CFStringRef kMenuItem_PaulWide = CFSTR ("PaulWide");
|
||||
static CFStringRef kMenuItem_NJAD = CFSTR ("NJAD");
|
||||
static CFStringRef kMenuItem_Bypass = CFSTR ("Bypass");
|
||||
|
||||
static CFStringRef kParameterAName = CFSTR("Air");
|
||||
static CFStringRef kParameterBName = CFSTR("Mid");
|
||||
|
|
@ -73,6 +87,7 @@ static CFStringRef kParameterFName = CFSTR("XvL-S");
|
|||
static CFStringRef kParameterGName = CFSTR("Zoom");
|
||||
static CFStringRef kParameterHName = CFSTR("DarkF");
|
||||
static CFStringRef kParameterIName = CFSTR("Ratio");
|
||||
static CFStringRef kParameterJName = CFSTR("Dither");
|
||||
|
||||
enum {
|
||||
kParam_A =0,
|
||||
|
|
@ -84,8 +99,9 @@ enum {
|
|||
kParam_G =6,
|
||||
kParam_H =7,
|
||||
kParam_I =8,
|
||||
kParam_J =9,
|
||||
//Add your parameters here...
|
||||
kNumberOfParameters=9
|
||||
kNumberOfParameters=10
|
||||
};
|
||||
|
||||
#pragma mark ____Mastering
|
||||
|
|
@ -97,8 +113,13 @@ public:
|
|||
virtual ~Mastering () { delete mDebugDispatcher; }
|
||||
#endif
|
||||
|
||||
virtual AUKernelBase * NewKernel() { return new MasteringKernel(this); }
|
||||
|
||||
virtual ComponentResult Reset(AudioUnitScope inScope, AudioUnitElement inElement);
|
||||
|
||||
virtual OSStatus ProcessBufferLists(AudioUnitRenderActionFlags & ioActionFlags,
|
||||
const AudioBufferList & inBuffer, AudioBufferList & outBuffer,
|
||||
UInt32 inFramesToProcess);
|
||||
virtual UInt32 SupportedNumChannels(const AUChannelInfo ** outInfo);
|
||||
|
||||
virtual ComponentResult GetParameterValueStrings(AudioUnitScope inScope,
|
||||
AudioUnitParameterID inParameterID,
|
||||
CFArrayRef * outStrings);
|
||||
|
|
@ -117,7 +138,7 @@ public:
|
|||
AudioUnitScope inScope,
|
||||
AudioUnitElement inElement,
|
||||
void * outData);
|
||||
|
||||
|
||||
virtual ComponentResult Initialize();
|
||||
virtual bool SupportsTail () { return true; }
|
||||
virtual Float64 GetTailTime() {return (1.0/GetSampleRate())*0.0;} //in SECONDS! gsr * a number = in samples
|
||||
|
|
@ -126,78 +147,126 @@ public:
|
|||
/*! @method Version */
|
||||
virtual ComponentResult Version() { return kMasteringVersion; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
protected:
|
||||
class MasteringKernel : public AUKernelBase // most of the real work happens here
|
||||
{
|
||||
public:
|
||||
MasteringKernel(AUEffectBase *inAudioUnit )
|
||||
: AUKernelBase(inAudioUnit)
|
||||
{
|
||||
}
|
||||
|
||||
// *Required* overides for the process method for this effect
|
||||
// processes one channel of interleaved samples
|
||||
virtual void Process( const Float32 *inSourceP,
|
||||
Float32 *inDestP,
|
||||
UInt32 inFramesToProcess,
|
||||
UInt32 inNumChannels,
|
||||
bool &ioSilence);
|
||||
|
||||
virtual void Reset();
|
||||
|
||||
private:
|
||||
enum {
|
||||
pvAL1,
|
||||
pvSL1,
|
||||
accSL1,
|
||||
acc2SL1,
|
||||
pvAL2,
|
||||
pvSL2,
|
||||
accSL2,
|
||||
acc2SL2,
|
||||
pvAL3,
|
||||
pvSL3,
|
||||
accSL3,
|
||||
pvAL4,
|
||||
pvSL4,
|
||||
gndavgL,
|
||||
outAL,
|
||||
gainAL,
|
||||
air_total
|
||||
};
|
||||
double air[air_total];
|
||||
|
||||
enum {
|
||||
prevSampL1,
|
||||
prevSlewL1,
|
||||
accSlewL1,
|
||||
prevSampL2,
|
||||
prevSlewL2,
|
||||
accSlewL2,
|
||||
prevSampL3,
|
||||
prevSlewL3,
|
||||
accSlewL3,
|
||||
kalGainL,
|
||||
kalOutL,
|
||||
kalAvgL,
|
||||
kal_total
|
||||
};
|
||||
double kalM[kal_total];
|
||||
double kalS[kal_total];
|
||||
|
||||
long double lastSinewL;
|
||||
//this is overkill, used to run both Zoom and Sinew stages as they are after
|
||||
//the summing in StoneFire, which sums three doubles to a long double.
|
||||
|
||||
double lastSample; //this doesn't touch the audio unless it's clipping
|
||||
double intermediate[16];
|
||||
bool wasPosClip;
|
||||
bool wasNegClip;
|
||||
|
||||
uint32_t fpd;
|
||||
enum {
|
||||
pvAL1,
|
||||
pvSL1,
|
||||
accSL1,
|
||||
acc2SL1,
|
||||
pvAL2,
|
||||
pvSL2,
|
||||
accSL2,
|
||||
acc2SL2,
|
||||
pvAL3,
|
||||
pvSL3,
|
||||
accSL3,
|
||||
pvAL4,
|
||||
pvSL4,
|
||||
gndavgL,
|
||||
outAL,
|
||||
gainAL,
|
||||
pvAR1,
|
||||
pvSR1,
|
||||
accSR1,
|
||||
acc2SR1,
|
||||
pvAR2,
|
||||
pvSR2,
|
||||
accSR2,
|
||||
acc2SR2,
|
||||
pvAR3,
|
||||
pvSR3,
|
||||
accSR3,
|
||||
pvAR4,
|
||||
pvSR4,
|
||||
gndavgR,
|
||||
outAR,
|
||||
gainAR,
|
||||
air_total
|
||||
};
|
||||
double air[air_total];
|
||||
|
||||
enum {
|
||||
prevSampL1,
|
||||
prevSlewL1,
|
||||
accSlewL1,
|
||||
prevSampL2,
|
||||
prevSlewL2,
|
||||
accSlewL2,
|
||||
prevSampL3,
|
||||
prevSlewL3,
|
||||
accSlewL3,
|
||||
kalGainL,
|
||||
kalOutL,
|
||||
kalAvgL,
|
||||
prevSampR1,
|
||||
prevSlewR1,
|
||||
accSlewR1,
|
||||
prevSampR2,
|
||||
prevSlewR2,
|
||||
accSlewR2,
|
||||
prevSampR3,
|
||||
prevSlewR3,
|
||||
accSlewR3,
|
||||
kalGainR,
|
||||
kalOutR,
|
||||
kalAvgR,
|
||||
kal_total
|
||||
};
|
||||
double kalM[kal_total];
|
||||
double kalS[kal_total];
|
||||
|
||||
long double lastSinewL;
|
||||
long double lastSinewR;
|
||||
//this is overkill, used to run both Zoom and Sinew stages as they are after
|
||||
//the summing in StoneFire, which sums three doubles to a long double.
|
||||
|
||||
double lastSampleL;
|
||||
double intermediateL[16];
|
||||
bool wasPosClipL;
|
||||
bool wasNegClipL;
|
||||
double lastSampleR;
|
||||
double intermediateR[16];
|
||||
bool wasPosClipR;
|
||||
bool wasNegClipR; //Stereo ClipOnly2
|
||||
|
||||
int quantA;
|
||||
int quantB;
|
||||
float expectedSlew;
|
||||
float testA;
|
||||
float testB;
|
||||
double correction;
|
||||
double shapedSampleL;
|
||||
double shapedSampleR;
|
||||
double currentDither;
|
||||
double ditherL;
|
||||
double ditherR;
|
||||
bool cutbinsL;
|
||||
bool cutbinsR;
|
||||
int hotbinA;
|
||||
int hotbinB;
|
||||
double benfordize;
|
||||
double totalA;
|
||||
double totalB;
|
||||
double outputSample;
|
||||
int expon; //internal dither variables
|
||||
|
||||
double NSOddL; //dither section!
|
||||
double NSEvenL;
|
||||
double prevShapeL;
|
||||
double NSOddR;
|
||||
double NSEvenR;
|
||||
double prevShapeR;
|
||||
bool flip; //VinylDither
|
||||
double darkSampleL[100];
|
||||
double darkSampleR[100]; //Dark
|
||||
double previousDitherL;
|
||||
double previousDitherR; //PaulWide
|
||||
double bynL[13], bynR[13];
|
||||
double noiseShapingL, noiseShapingR; //NJAD
|
||||
|
||||
uint32_t fpdL;
|
||||
uint32_t fpdR;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Version: 1.0
|
||||
*
|
||||
* Created: 10/8/24
|
||||
* Created: 10/21/24
|
||||
*
|
||||
* Copyright: Copyright © 2024 Airwindows, Airwindows uses the MIT license
|
||||
*
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@
|
|||
<dict>
|
||||
<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
|
||||
<array>
|
||||
<real>186</real>
|
||||
<real>299</real>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
|
||||
<array>
|
||||
|
|
@ -264,19 +264,22 @@
|
|||
<array>
|
||||
<string>089C166AFE841209C02AAC07</string>
|
||||
<string>08FB77ADFE841716C02AAC07</string>
|
||||
<string>8BA05AEB0720742700365D66</string>
|
||||
<string>8BA05A7D072073D200365D66</string>
|
||||
<string>8BA05A7E072073D200365D66</string>
|
||||
<string>1C37FBAC04509CD000000102</string>
|
||||
<string>1C37FABC05509CD000000102</string>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
|
||||
<array>
|
||||
<array>
|
||||
<integer>20</integer>
|
||||
<integer>19</integer>
|
||||
<integer>6</integer>
|
||||
<integer>5</integer>
|
||||
<integer>4</integer>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
|
||||
<string>{{0, 0}, {186, 445}}</string>
|
||||
<string>{{0, 0}, {299, 445}}</string>
|
||||
</dict>
|
||||
<key>PBXTopSmartGroupGIDs</key>
|
||||
<array/>
|
||||
|
|
@ -288,19 +291,19 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {203, 463}}</string>
|
||||
<string>{{0, 0}, {316, 463}}</string>
|
||||
<key>GroupTreeTableConfiguration</key>
|
||||
<array>
|
||||
<string>MainColumn</string>
|
||||
<real>186</real>
|
||||
<real>299</real>
|
||||
</array>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>203 321 788 504 0 0 1440 878 </string>
|
||||
<string>18 337 788 504 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXSmartGroupTreeModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>203pt</string>
|
||||
<string>316pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Dock</key>
|
||||
|
|
@ -311,15 +314,13 @@
|
|||
<key>PBXProjectModuleGUID</key>
|
||||
<string>1CE0B20306471E060097A5F4</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MyNewFile14.java</string>
|
||||
<string><No Editor></string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>1CE0B20406471E060097A5F4</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MyNewFile14.java</string>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
<string>1</string>
|
||||
|
|
@ -330,14 +331,14 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {580, 269}}</string>
|
||||
<string>{{0, 0}, {467, 0}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>203 321 788 504 0 0 1440 878 </string>
|
||||
<string>18 337 788 504 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<key>Proportion</key>
|
||||
<string>269pt</string>
|
||||
<string>0pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>ContentConfiguration</key>
|
||||
|
|
@ -350,18 +351,18 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 274}, {580, 189}}</string>
|
||||
<string>{{0, 5}, {467, 458}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>203 321 788 504 0 0 1440 878 </string>
|
||||
<string>18 337 788 504 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>XCDetailModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>189pt</string>
|
||||
<string>458pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Proportion</key>
|
||||
<string>580pt</string>
|
||||
<string>467pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Name</key>
|
||||
|
|
@ -376,9 +377,9 @@
|
|||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>8B563EC9161B5E170067FE32</string>
|
||||
<string>8BDD47AA1A48BB8900FB2F61</string>
|
||||
<string>1CE0B1FE06471DED0097A5F4</string>
|
||||
<string>8B563ECA161B5E170067FE32</string>
|
||||
<string>8BDD47AB1A48BB8900FB2F61</string>
|
||||
<string>1CE0B20306471E060097A5F4</string>
|
||||
<string>1CE0B20506471E060097A5F4</string>
|
||||
</array>
|
||||
|
|
@ -517,10 +518,10 @@
|
|||
<key>WindowOrderList</key>
|
||||
<array>
|
||||
<string>8BD3CCBD148831C90062E48C</string>
|
||||
<string>/Developer/Library/Xcode/Project Templates/System Plug-in/Audio Unit Effect/Audio Unit Effect/StarterAU.xcodeproj</string>
|
||||
<string>/Developer/Library/Xcode/Project Templates/System Plug-in/Audio Unit Effect/Audio Unit Effect with Cocoa View/StarterAU.xcodeproj</string>
|
||||
</array>
|
||||
<key>WindowString</key>
|
||||
<string>203 321 788 504 0 0 1440 878 </string>
|
||||
<string>18 337 788 504 0 0 1440 878 </string>
|
||||
<key>WindowToolsV3</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
@ -597,7 +598,7 @@
|
|||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>8BD3CCBD148831C90062E48C</string>
|
||||
<string>8B563ECB161B5E170067FE32</string>
|
||||
<string>8BDD47AC1A48BB8900FB2F61</string>
|
||||
<string>1CD0528F0623707200166675</string>
|
||||
<string>XCMainBuildResultsModuleGUID</string>
|
||||
</array>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
|
||||
PBXFileTableDataSourceColumnWidthsKey = (
|
||||
20,
|
||||
292,
|
||||
364,
|
||||
20,
|
||||
48,
|
||||
43,
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
|
||||
PBXFileTableDataSourceColumnWidthsKey = (
|
||||
20,
|
||||
252,
|
||||
188,
|
||||
60,
|
||||
20,
|
||||
48,
|
||||
|
|
@ -49,14 +49,12 @@
|
|||
PBXFileDataSource_Warnings_ColumnID,
|
||||
);
|
||||
};
|
||||
PBXPerProjectTemplateStateSaveDate = 750255310;
|
||||
PBXWorkspaceStateSaveDate = 750255310;
|
||||
PBXPerProjectTemplateStateSaveDate = 751290936;
|
||||
PBXWorkspaceStateSaveDate = 751290936;
|
||||
};
|
||||
perUserProjectItems = {
|
||||
8BA3DC492CB5EC1900B899C2 /* PlistBookmark */ = 8BA3DC492CB5EC1900B899C2 /* PlistBookmark */;
|
||||
8BF17B272CB7FB4400FAAF3F /* PBXTextBookmark */ = 8BF17B272CB7FB4400FAAF3F /* PBXTextBookmark */;
|
||||
8BF17B702CB7FF3300FAAF3F /* PBXTextBookmark */ = 8BF17B702CB7FF3300FAAF3F /* PBXTextBookmark */;
|
||||
8BF17B712CB7FF3300FAAF3F /* PBXTextBookmark */ = 8BF17B712CB7FF3300FAAF3F /* PBXTextBookmark */;
|
||||
8BC4371D2CC70EE00098AE55 /* PBXTextBookmark */ = 8BC4371D2CC70EE00098AE55 /* PBXTextBookmark */;
|
||||
8BC437832CC7CCED0098AE55 /* PBXTextBookmark */ = 8BC437832CC7CCED0098AE55 /* PBXTextBookmark */;
|
||||
};
|
||||
sourceControlManager = 8BD3CCB8148830B20062E48C /* Source Control */;
|
||||
userBuildSettings = {
|
||||
|
|
@ -64,38 +62,53 @@
|
|||
};
|
||||
8BA05A660720730100365D66 /* Mastering.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {822, 7380}}";
|
||||
sepNavSelRange = "{17032, 0}";
|
||||
sepNavVisRange = "{15387, 90}";
|
||||
sepNavWindowFrame = "{{12, 53}, {1040, 821}}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {849, 18270}}";
|
||||
sepNavSelRange = "{31815, 0}";
|
||||
sepNavVisRange = "{31575, 221}";
|
||||
sepNavWindowFrame = "{{8, 49}, {1061, 821}}";
|
||||
};
|
||||
};
|
||||
8BA05A690720730100365D66 /* MasteringVersion.h */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1056, 1062}}";
|
||||
sepNavSelRange = "{2906, 0}";
|
||||
sepNavVisRange = "{1069, 1900}";
|
||||
sepNavWindowFrame = "{{15, 52}, {1040, 821}}";
|
||||
sepNavSelRange = "{2907, 0}";
|
||||
sepNavVisRange = "{1070, 1900}";
|
||||
sepNavWindowFrame = "{{15, 52}, {1061, 821}}";
|
||||
};
|
||||
};
|
||||
8BA3DC492CB5EC1900B899C2 /* PlistBookmark */ = {
|
||||
isa = PlistBookmark;
|
||||
fRef = 8D01CCD10486CAD60068D4B7 /* Info.plist */;
|
||||
fallbackIsa = PBXBookmark;
|
||||
isK = 0;
|
||||
kPath = (
|
||||
CFBundleName,
|
||||
);
|
||||
name = /Users/christopherjohnson/Desktop/Mastering/Info.plist;
|
||||
8BA05A7F072073D200365D66 /* AUBase.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {516, 23430}}";
|
||||
sepNavSelRange = "{0, 0}";
|
||||
sepNavVisRange = "{0, 1336}";
|
||||
};
|
||||
};
|
||||
8BC4371D2CC70EE00098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 8BA05A660720730100365D66 /* Mastering.cpp */;
|
||||
name = "Mastering.cpp: 693";
|
||||
rLen = 0;
|
||||
rLoc = 9223372036854775808;
|
||||
rLoc = 31815;
|
||||
rType = 0;
|
||||
vrLen = 252;
|
||||
vrLoc = 31544;
|
||||
};
|
||||
8BC437832CC7CCED0098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 8BA05A660720730100365D66 /* Mastering.cpp */;
|
||||
name = "Mastering.cpp: 693";
|
||||
rLen = 0;
|
||||
rLoc = 31815;
|
||||
rType = 0;
|
||||
vrLen = 221;
|
||||
vrLoc = 31575;
|
||||
};
|
||||
8BC6025B073B072D006C4272 /* Mastering.h */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1056, 3132}}";
|
||||
sepNavSelRange = "{3665, 0}";
|
||||
sepNavVisRange = "{2605, 1167}";
|
||||
sepNavWindowFrame = "{{38, 57}, {1040, 821}}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1146, 4950}}";
|
||||
sepNavSelRange = "{7725, 0}";
|
||||
sepNavVisRange = "{7429, 835}";
|
||||
sepNavWindowFrame = "{{26, 47}, {1061, 821}}";
|
||||
};
|
||||
};
|
||||
8BD3CCB8148830B20062E48C /* Source Control */ = {
|
||||
|
|
@ -112,36 +125,6 @@
|
|||
isa = PBXCodeSenseManager;
|
||||
indexTemplatePath = "";
|
||||
};
|
||||
8BF17B272CB7FB4400FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 8BA05A660720730100365D66 /* Mastering.cpp */;
|
||||
name = "Mastering.cpp: 347";
|
||||
rLen = 0;
|
||||
rLoc = 17032;
|
||||
rType = 0;
|
||||
vrLen = 38;
|
||||
vrLoc = 15492;
|
||||
};
|
||||
8BF17B702CB7FF3300FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 8BC6025B073B072D006C4272 /* Mastering.h */;
|
||||
name = "Mastering.h: 65";
|
||||
rLen = 0;
|
||||
rLoc = 3252;
|
||||
rType = 0;
|
||||
vrLen = 52;
|
||||
vrLoc = 3253;
|
||||
};
|
||||
8BF17B712CB7FF3300FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 8BA05A660720730100365D66 /* Mastering.cpp */;
|
||||
name = "Mastering.cpp: 347";
|
||||
rLen = 0;
|
||||
rLoc = 17032;
|
||||
rType = 0;
|
||||
vrLen = 90;
|
||||
vrLoc = 15387;
|
||||
};
|
||||
8D01CCC60486CAD60068D4B7 /* Mastering */ = {
|
||||
activeExec = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@
|
|||
<key>FavBarConfig</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8BD7274F1D46E5A5000176F0</string>
|
||||
<string>8BC435772CC6F8650098AE55</string>
|
||||
<key>XCBarModuleItemNames</key>
|
||||
<dict/>
|
||||
<key>XCBarModuleItems</key>
|
||||
|
|
@ -225,8 +225,8 @@
|
|||
<array/>
|
||||
<key>PerspectiveWidths</key>
|
||||
<array>
|
||||
<integer>841</integer>
|
||||
<integer>841</integer>
|
||||
<integer>810</integer>
|
||||
<integer>810</integer>
|
||||
</array>
|
||||
<key>Perspectives</key>
|
||||
<array>
|
||||
|
|
@ -282,7 +282,7 @@
|
|||
<dict>
|
||||
<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
|
||||
<array>
|
||||
<real>288</real>
|
||||
<real>185</real>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
|
||||
<array>
|
||||
|
|
@ -296,8 +296,6 @@
|
|||
<string>089C166AFE841209C02AAC07</string>
|
||||
<string>08FB77ADFE841716C02AAC07</string>
|
||||
<string>8BA05A56072072A900365D66</string>
|
||||
<string>089C167CFE841241C02AAC07</string>
|
||||
<string>1C37FBAC04509CD000000102</string>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
|
||||
<array>
|
||||
|
|
@ -309,7 +307,7 @@
|
|||
</array>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
|
||||
<string>{{0, 0}, {288, 595}}</string>
|
||||
<string>{{0, 0}, {185, 428}}</string>
|
||||
</dict>
|
||||
<key>PBXTopSmartGroupGIDs</key>
|
||||
<array/>
|
||||
|
|
@ -319,19 +317,19 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {305, 613}}</string>
|
||||
<string>{{0, 0}, {202, 446}}</string>
|
||||
<key>GroupTreeTableConfiguration</key>
|
||||
<array>
|
||||
<string>MainColumn</string>
|
||||
<real>288</real>
|
||||
<real>185</real>
|
||||
</array>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>8 177 841 654 0 0 1440 878 </string>
|
||||
<string>0 299 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXSmartGroupTreeModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>305pt</string>
|
||||
<string>202pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Dock</key>
|
||||
|
|
@ -340,7 +338,7 @@
|
|||
<key>ContentConfiguration</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8BD7274A1D46E5A5000176F0</string>
|
||||
<string>8BC435722CC6F8650098AE55</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>Mastering.cpp</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
|
|
@ -348,18 +346,16 @@
|
|||
<key>Split0</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8BD7274B1D46E5A5000176F0</string>
|
||||
<string>8BC435732CC6F8650098AE55</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>Mastering.cpp</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>8BF17B712CB7FF3300FAAF3F</string>
|
||||
<string>8BC437832CC7CCED0098AE55</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>8BA3DC492CB5EC1900B899C2</string>
|
||||
<string>8BF17B702CB7FF3300FAAF3F</string>
|
||||
<string>8BF17B272CB7FB4400FAAF3F</string>
|
||||
<string>8BC4371D2CC70EE00098AE55</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
|
|
@ -373,18 +369,18 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {531, 56}}</string>
|
||||
<string>{{0, 0}, {603, 86}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>8 177 841 654 0 0 1440 878 </string>
|
||||
<string>0 299 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<key>Proportion</key>
|
||||
<string>56pt</string>
|
||||
<string>86pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Proportion</key>
|
||||
<string>552pt</string>
|
||||
<string>355pt</string>
|
||||
<key>Tabs</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
@ -398,9 +394,9 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {531, 525}}</string>
|
||||
<string>{{10, 27}, {603, 328}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>8 177 841 654 0 0 1440 878 </string>
|
||||
<string>0 299 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>XCDetailModule</string>
|
||||
|
|
@ -454,7 +450,7 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {531, 507}}</string>
|
||||
<string>{{10, 27}, {603, 282}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXBuildResultsModule</string>
|
||||
|
|
@ -463,7 +459,7 @@
|
|||
</dict>
|
||||
</array>
|
||||
<key>Proportion</key>
|
||||
<string>531pt</string>
|
||||
<string>603pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Name</key>
|
||||
|
|
@ -482,11 +478,11 @@
|
|||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>8BF17B722CB7FF3300FAAF3F</string>
|
||||
<string>8BC437842CC7CCED0098AE55</string>
|
||||
<string>1CA23ED40692098700951B8B</string>
|
||||
<string>8BF17B732CB7FF3300FAAF3F</string>
|
||||
<string>8BD7274A1D46E5A5000176F0</string>
|
||||
<string>8BF17B742CB7FF3300FAAF3F</string>
|
||||
<string>8BC437852CC7CCED0098AE55</string>
|
||||
<string>8BC435722CC6F8650098AE55</string>
|
||||
<string>8BC437862CC7CCED0098AE55</string>
|
||||
<string>1CA23EDF0692099D00951B8B</string>
|
||||
<string>1CA23EE00692099D00951B8B</string>
|
||||
<string>1CA23EE10692099D00951B8B</string>
|
||||
|
|
@ -523,7 +519,7 @@
|
|||
<key>Identifier</key>
|
||||
<string>perspective.debug</string>
|
||||
<key>IsVertical</key>
|
||||
<true/>
|
||||
<integer>1</integer>
|
||||
<key>Layout</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
@ -542,7 +538,7 @@
|
|||
<key>Module</key>
|
||||
<string>PBXDebugCLIModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>0pt</string>
|
||||
<string>0%</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>ContentConfiguration</key>
|
||||
|
|
@ -561,8 +557,8 @@
|
|||
<string>yes</string>
|
||||
<key>sizes</key>
|
||||
<array>
|
||||
<string>{{0, 0}, {395, 214}}</string>
|
||||
<string>{{395, 0}, {415, 214}}</string>
|
||||
<string>{{0, 0}, {395, 213}}</string>
|
||||
<string>{{395, 0}, {415, 213}}</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>VerticalSplitView</key>
|
||||
|
|
@ -577,8 +573,8 @@
|
|||
<string>yes</string>
|
||||
<key>sizes</key>
|
||||
<array>
|
||||
<string>{{0, 0}, {810, 214}}</string>
|
||||
<string>{{0, 214}, {810, 227}}</string>
|
||||
<string>{{0, 0}, {810, 213}}</string>
|
||||
<string>{{0, 213}, {810, 225}}</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
|
|
@ -591,6 +587,8 @@
|
|||
</dict>
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>DebugConsoleDrawerSize</key>
|
||||
<string>{100, 120}</string>
|
||||
<key>DebugConsoleVisible</key>
|
||||
<string>None</string>
|
||||
<key>DebugConsoleWindowFrame</key>
|
||||
|
|
@ -598,54 +596,32 @@
|
|||
<key>DebugSTDIOWindowFrame</key>
|
||||
<string>{{200, 200}, {500, 300}}</string>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 5}, {810, 441}}</string>
|
||||
<key>PBXDebugSessionStackFrameViewKey</key>
|
||||
<dict>
|
||||
<key>DebugVariablesTableConfiguration</key>
|
||||
<array>
|
||||
<string>Name</string>
|
||||
<real>120</real>
|
||||
<string>Value</string>
|
||||
<real>85</real>
|
||||
<string>Summary</string>
|
||||
<real>185</real>
|
||||
</array>
|
||||
<key>Frame</key>
|
||||
<string>{{395, 0}, {415, 214}}</string>
|
||||
</dict>
|
||||
<string>{{0, 7}, {810, 438}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXDebugSessionModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>441pt</string>
|
||||
<string>443pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Name</key>
|
||||
<string>Debug</string>
|
||||
<key>ServiceClasses</key>
|
||||
<array>
|
||||
<string>XCModuleDock</string>
|
||||
<string>XCModuleDock</string>
|
||||
<string>PBXDebugCLIModule</string>
|
||||
<string>PBXDebugSessionModule</string>
|
||||
<string>PBXDebugProcessAndThreadModule</string>
|
||||
<string>PBXDebugProcessViewModule</string>
|
||||
<string>PBXDebugThreadViewModule</string>
|
||||
<string>PBXDebugStackFrameViewModule</string>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<string>XCConsole</string>
|
||||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>8BD727EC1D46ECF1000176F0</string>
|
||||
<string>1CC8E6A5069209BD00BB180A</string>
|
||||
<string>1CC8E6A6069209BD00BB180A</string>
|
||||
<string>1CCC7628064C1048000F2A68</string>
|
||||
<string>1CCC7629064C1048000F2A68</string>
|
||||
<string>8BD727ED1D46ECF1000176F0</string>
|
||||
<string>8BD727EE1D46ECF1000176F0</string>
|
||||
<string>8BD727EF1D46ECF1000176F0</string>
|
||||
<string>8BD727F01D46ECF1000176F0</string>
|
||||
<string>8BD727E71D46ECD9000176F0</string>
|
||||
<string>1CC8E6A7069209BD00BB180A</string>
|
||||
</array>
|
||||
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
||||
<string>2</string>
|
||||
<key>ToolbarConfiguration</key>
|
||||
<string>xcode.toolbar.config.debugV3</string>
|
||||
</dict>
|
||||
|
|
@ -659,7 +635,7 @@
|
|||
<key>StatusbarIsVisible</key>
|
||||
<true/>
|
||||
<key>TimeStamp</key>
|
||||
<real>750255923.53302801</real>
|
||||
<real>751291629.93373895</real>
|
||||
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
||||
<string>2</string>
|
||||
<key>ToolbarDisplayMode</key>
|
||||
|
|
@ -676,11 +652,11 @@
|
|||
<integer>5</integer>
|
||||
<key>WindowOrderList</key>
|
||||
<array>
|
||||
<string>8BF17B752CB7FF3300FAAF3F</string>
|
||||
<string>8BC437872CC7CCED0098AE55</string>
|
||||
<string>/Users/christopherjohnson/Desktop/airwindows/plugins/MacAU/Mastering/Mastering.xcodeproj</string>
|
||||
</array>
|
||||
<key>WindowString</key>
|
||||
<string>8 177 841 654 0 0 1440 878 </string>
|
||||
<string>0 299 810 487 0 0 1440 878 </string>
|
||||
<key>WindowToolsV3</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Version: 1.0
|
||||
*
|
||||
* Created: 10/8/24
|
||||
* Created: 10/21/24
|
||||
*
|
||||
* Copyright: Copyright © 2024 Airwindows, Airwindows uses the MIT license
|
||||
*
|
||||
|
|
|
|||
5
plugins/MacSignedAU/Mastering/StarterAU_Prefix.pch
Executable file
5
plugins/MacSignedAU/Mastering/StarterAU_Prefix.pch
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
//
|
||||
// Prefix header for all source files of the '«PROJECTNAMEASIDENTIFIER»' target in the '«PROJECTNAMEASIDENTIFIER»' project.
|
||||
//
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
Binary file not shown.
|
|
@ -51,13 +51,16 @@
|
|||
PBXFileDataSource_Warnings_ColumnID,
|
||||
);
|
||||
};
|
||||
PBXPerProjectTemplateStateSaveDate = 750255314;
|
||||
PBXWorkspaceStateSaveDate = 750255314;
|
||||
PBXPerProjectTemplateStateSaveDate = 751291914;
|
||||
PBXWorkspaceStateSaveDate = 751291914;
|
||||
};
|
||||
perUserProjectItems = {
|
||||
8BC437242CC70EF00098AE55 /* PBXTextBookmark */ = 8BC437242CC70EF00098AE55 /* PBXTextBookmark */;
|
||||
8BC4377F2CC7CCEC0098AE55 /* PBXTextBookmark */ = 8BC4377F2CC7CCEC0098AE55 /* PBXTextBookmark */;
|
||||
8BC437962CC7CE130098AE55 /* PBXBookmark */ = 8BC437962CC7CE130098AE55 /* PBXBookmark */;
|
||||
8BC437A32CC7CE520098AE55 /* PBXTextBookmark */ = 8BC437A32CC7CE520098AE55 /* PBXTextBookmark */;
|
||||
8BC437A92CC7CE520098AE55 /* PBXTextBookmark */ = 8BC437A92CC7CE520098AE55 /* PBXTextBookmark */;
|
||||
8BF17AF32CB7F7B000FAAF3F /* PBXTextBookmark */ = 8BF17AF32CB7F7B000FAAF3F /* PBXTextBookmark */;
|
||||
8BF17B6A2CB7FF3200FAAF3F /* PBXTextBookmark */ = 8BF17B6A2CB7FF3200FAAF3F /* PBXTextBookmark */;
|
||||
8BF17B6B2CB7FF3200FAAF3F /* PBXTextBookmark */ = 8BF17B6B2CB7FF3200FAAF3F /* PBXTextBookmark */;
|
||||
};
|
||||
sourceControlManager = 8B02375E1D42B1C400E1E8C8 /* Source Control */;
|
||||
userBuildSettings = {
|
||||
|
|
@ -65,17 +68,17 @@
|
|||
};
|
||||
2407DEB6089929BA00EB68BF /* Mastering.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {848, 3330}}";
|
||||
sepNavSelRange = "{5220, 0}";
|
||||
sepNavVisRange = "{5828, 1821}";
|
||||
sepNavWindowFrame = "{{702, 47}, {895, 831}}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {948, 4860}}";
|
||||
sepNavSelRange = "{7531, 13}";
|
||||
sepNavVisRange = "{739, 942}";
|
||||
sepNavWindowFrame = "{{545, 47}, {895, 831}}";
|
||||
};
|
||||
};
|
||||
245463B80991757100464AD3 /* Mastering.h */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1110, 2880}}";
|
||||
sepNavSelRange = "{3289, 0}";
|
||||
sepNavVisRange = "{3111, 702}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {554, 3600}}";
|
||||
sepNavSelRange = "{528, 0}";
|
||||
sepNavVisRange = "{0, 0}";
|
||||
sepNavWindowFrame = "{{545, 47}, {895, 831}}";
|
||||
};
|
||||
};
|
||||
|
|
@ -89,9 +92,9 @@
|
|||
};
|
||||
24D8286F09A914000093AEF8 /* MasteringProc.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {714, 10530}}";
|
||||
sepNavSelRange = "{16048, 0}";
|
||||
sepNavVisRange = "{15306, 97}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1056, 23598}}";
|
||||
sepNavSelRange = "{31210, 0}";
|
||||
sepNavVisRange = "{803, 1981}";
|
||||
sepNavWindowFrame = "{{543, 47}, {895, 831}}";
|
||||
};
|
||||
};
|
||||
|
|
@ -109,36 +112,60 @@
|
|||
isa = PBXCodeSenseManager;
|
||||
indexTemplatePath = "";
|
||||
};
|
||||
8BC437242CC70EF00098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */;
|
||||
name = "MasteringProc.cpp: 325";
|
||||
rLen = 0;
|
||||
rLoc = 31418;
|
||||
rType = 0;
|
||||
vrLen = 0;
|
||||
vrLoc = 0;
|
||||
};
|
||||
8BC4377F2CC7CCEC0098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 245463B80991757100464AD3 /* Mastering.h */;
|
||||
name = "Mastering.h: 29";
|
||||
rLen = 0;
|
||||
rLoc = 528;
|
||||
rType = 0;
|
||||
vrLen = 0;
|
||||
vrLoc = 0;
|
||||
};
|
||||
8BC437962CC7CE130098AE55 /* PBXBookmark */ = {
|
||||
isa = PBXBookmark;
|
||||
fRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */;
|
||||
};
|
||||
8BC437A32CC7CE520098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 245463B80991757100464AD3 /* Mastering.h */;
|
||||
name = "Mastering.h: 29";
|
||||
rLen = 0;
|
||||
rLoc = 528;
|
||||
rType = 0;
|
||||
vrLen = 0;
|
||||
vrLoc = 0;
|
||||
};
|
||||
8BC437A92CC7CE520098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */;
|
||||
name = "MasteringProc.cpp: 699";
|
||||
rLen = 0;
|
||||
rLoc = 31210;
|
||||
rType = 0;
|
||||
vrLen = 1981;
|
||||
vrLoc = 803;
|
||||
};
|
||||
8BF17AF32CB7F7B000FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 2407DEB6089929BA00EB68BF /* Mastering.cpp */;
|
||||
name = "Mastering.cpp: 29";
|
||||
rLen = 0;
|
||||
rLoc = 707;
|
||||
rLoc = 717;
|
||||
rType = 0;
|
||||
vrLen = 356;
|
||||
vrLoc = 5826;
|
||||
};
|
||||
8BF17B6A2CB7FF3200FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */;
|
||||
name = "MasteringProc.cpp: 325";
|
||||
rLen = 0;
|
||||
rLoc = 16048;
|
||||
rType = 0;
|
||||
vrLen = 126;
|
||||
vrLoc = 15253;
|
||||
};
|
||||
8BF17B6B2CB7FF3200FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */;
|
||||
name = "MasteringProc.cpp: 325";
|
||||
rLen = 0;
|
||||
rLoc = 16048;
|
||||
rType = 0;
|
||||
vrLen = 97;
|
||||
vrLoc = 15306;
|
||||
};
|
||||
8D01CCC60486CAD60068D4B7 /* Mastering */ = {
|
||||
activeExec = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -222,7 +222,48 @@
|
|||
</dict>
|
||||
</array>
|
||||
<key>OpenEditors</key>
|
||||
<array/>
|
||||
<array>
|
||||
<dict>
|
||||
<key>Content</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8BC437A72CC7CE520098AE55</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MasteringProc.cpp</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8BC437A82CC7CE520098AE55</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MasteringProc.cpp</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>8BC437A92CC7CE520098AE55</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>8BC437962CC7CE130098AE55</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
<key>StatusBarVisibility</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Geometry</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 20}, {895, 734}}</string>
|
||||
<key>PBXModuleWindowStatusBarHidden2</key>
|
||||
<false/>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>543 103 895 775 0 0 1440 878 </string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>PerspectiveWidths</key>
|
||||
<array>
|
||||
<integer>810</integer>
|
||||
|
|
@ -323,7 +364,7 @@
|
|||
<real>185</real>
|
||||
</array>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>579 290 810 487 0 0 1440 878 </string>
|
||||
<string>620 297 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXSmartGroupTreeModule</string>
|
||||
|
|
@ -339,7 +380,7 @@
|
|||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8B0237581D42B1C400E1E8C8</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MasteringProc.cpp</string>
|
||||
<string>Mastering.h</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
|
|
@ -347,15 +388,16 @@
|
|||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8B0237591D42B1C400E1E8C8</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MasteringProc.cpp</string>
|
||||
<string>Mastering.h</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>8BF17B6B2CB7FF3200FAAF3F</string>
|
||||
<string>8BC437A32CC7CE520098AE55</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>8BF17AF32CB7F7B000FAAF3F</string>
|
||||
<string>8BF17B6A2CB7FF3200FAAF3F</string>
|
||||
<string>8BC437242CC70EF00098AE55</string>
|
||||
<string>8BC4377F2CC7CCEC0098AE55</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
|
|
@ -369,18 +411,18 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {603, 86}}</string>
|
||||
<string>{{0, 0}, {603, 0}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>579 290 810 487 0 0 1440 878 </string>
|
||||
<string>620 297 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<key>Proportion</key>
|
||||
<string>86pt</string>
|
||||
<string>0pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Proportion</key>
|
||||
<string>355pt</string>
|
||||
<string>441pt</string>
|
||||
<key>Tabs</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
@ -394,9 +436,9 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {603, 328}}</string>
|
||||
<string>{{10, 27}, {603, 414}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>579 290 810 487 0 0 1440 878 </string>
|
||||
<string>620 297 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>XCDetailModule</string>
|
||||
|
|
@ -478,11 +520,11 @@
|
|||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>8BF17B6C2CB7FF3200FAAF3F</string>
|
||||
<string>8BC437A42CC7CE520098AE55</string>
|
||||
<string>1CA23ED40692098700951B8B</string>
|
||||
<string>8BF17B6D2CB7FF3200FAAF3F</string>
|
||||
<string>8BC437A52CC7CE520098AE55</string>
|
||||
<string>8B0237581D42B1C400E1E8C8</string>
|
||||
<string>8BF17B6E2CB7FF3200FAAF3F</string>
|
||||
<string>8BC437A62CC7CE520098AE55</string>
|
||||
<string>1CA23EDF0692099D00951B8B</string>
|
||||
<string>1CA23EE00692099D00951B8B</string>
|
||||
<string>1CA23EE10692099D00951B8B</string>
|
||||
|
|
@ -655,7 +697,7 @@
|
|||
<key>StatusbarIsVisible</key>
|
||||
<true/>
|
||||
<key>TimeStamp</key>
|
||||
<real>750255922.06214201</real>
|
||||
<real>751291986.86297703</real>
|
||||
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
||||
<string>2</string>
|
||||
<key>ToolbarDisplayMode</key>
|
||||
|
|
@ -672,11 +714,11 @@
|
|||
<integer>5</integer>
|
||||
<key>WindowOrderList</key>
|
||||
<array>
|
||||
<string>8BF17B6F2CB7FF3200FAAF3F</string>
|
||||
<string>/Users/christopherjohnson/Desktop/airwindows/plugins/MacVST/Mastering/Mastering.xcodeproj</string>
|
||||
<string>8BC437A72CC7CE520098AE55</string>
|
||||
</array>
|
||||
<key>WindowString</key>
|
||||
<string>579 290 810 487 0 0 1440 878 </string>
|
||||
<string>620 297 810 487 0 0 1440 878 </string>
|
||||
<key>WindowToolsV3</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@
|
|||
24CFB70407E7A0220081BD57 /* PkgInfo in Resources */ = {isa = PBXBuildFile; fileRef = 24CFB70307E7A0220081BD57 /* PkgInfo */; };
|
||||
24D8287009A914000093AEF8 /* MasteringProc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */; };
|
||||
24D8287F09A9164A0093AEF8 /* xcode_vst_prefix.h in Headers */ = {isa = PBXBuildFile; fileRef = 24D8287E09A9164A0093AEF8 /* xcode_vst_prefix.h */; };
|
||||
8B5A01292CB8542B00E1C37C /* vstfxstore.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B5A011D2CB8542B00E1C37C /* vstfxstore.h */; };
|
||||
8B5A012A2CB8542B00E1C37C /* aeffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B5A011E2CB8542B00E1C37C /* aeffect.h */; };
|
||||
8B5A012B2CB8542B00E1C37C /* aeffectx.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B5A011F2CB8542B00E1C37C /* aeffectx.h */; };
|
||||
8B5A012C2CB8542B00E1C37C /* audioeffectx.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B5A01232CB8542B00E1C37C /* audioeffectx.h */; };
|
||||
8B5A012D2CB8542B00E1C37C /* audioeffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8B5A01242CB8542B00E1C37C /* audioeffect.cpp */; };
|
||||
8B5A012E2CB8542B00E1C37C /* audioeffectx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8B5A01252CB8542B00E1C37C /* audioeffectx.cpp */; };
|
||||
8B5A012F2CB8542B00E1C37C /* aeffeditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B5A01262CB8542B00E1C37C /* aeffeditor.h */; };
|
||||
8B5A01302CB8542B00E1C37C /* vstplugmain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8B5A01272CB8542B00E1C37C /* vstplugmain.cpp */; };
|
||||
8B5A01312CB8542B00E1C37C /* audioeffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B5A01282CB8542B00E1C37C /* audioeffect.h */; };
|
||||
8B0FB94A2CC849930015BC09 /* vstfxstore.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B0FB93E2CC849930015BC09 /* vstfxstore.h */; };
|
||||
8B0FB94B2CC849930015BC09 /* aeffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B0FB93F2CC849930015BC09 /* aeffect.h */; };
|
||||
8B0FB94C2CC849930015BC09 /* aeffectx.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B0FB9402CC849930015BC09 /* aeffectx.h */; };
|
||||
8B0FB94D2CC849930015BC09 /* audioeffectx.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B0FB9442CC849930015BC09 /* audioeffectx.h */; };
|
||||
8B0FB94E2CC849930015BC09 /* audioeffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8B0FB9452CC849930015BC09 /* audioeffect.cpp */; };
|
||||
8B0FB94F2CC849930015BC09 /* audioeffectx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8B0FB9462CC849930015BC09 /* audioeffectx.cpp */; };
|
||||
8B0FB9502CC849930015BC09 /* aeffeditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B0FB9472CC849930015BC09 /* aeffeditor.h */; };
|
||||
8B0FB9512CC849930015BC09 /* vstplugmain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8B0FB9482CC849930015BC09 /* vstplugmain.cpp */; };
|
||||
8B0FB9522CC849930015BC09 /* audioeffect.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B0FB9492CC849930015BC09 /* audioeffect.h */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
|
|
@ -30,15 +30,15 @@
|
|||
24CFB70307E7A0220081BD57 /* PkgInfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = PkgInfo; path = mac/PkgInfo; sourceTree = "<group>"; };
|
||||
24D8286F09A914000093AEF8 /* MasteringProc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MasteringProc.cpp; path = source/MasteringProc.cpp; sourceTree = "<group>"; };
|
||||
24D8287E09A9164A0093AEF8 /* xcode_vst_prefix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = xcode_vst_prefix.h; path = mac/xcode_vst_prefix.h; sourceTree = SOURCE_ROOT; };
|
||||
8B5A011D2CB8542B00E1C37C /* vstfxstore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstfxstore.h; sourceTree = "<group>"; };
|
||||
8B5A011E2CB8542B00E1C37C /* aeffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffect.h; sourceTree = "<group>"; };
|
||||
8B5A011F2CB8542B00E1C37C /* aeffectx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffectx.h; sourceTree = "<group>"; };
|
||||
8B5A01232CB8542B00E1C37C /* audioeffectx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audioeffectx.h; sourceTree = "<group>"; };
|
||||
8B5A01242CB8542B00E1C37C /* audioeffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audioeffect.cpp; sourceTree = "<group>"; };
|
||||
8B5A01252CB8542B00E1C37C /* audioeffectx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audioeffectx.cpp; sourceTree = "<group>"; };
|
||||
8B5A01262CB8542B00E1C37C /* aeffeditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffeditor.h; sourceTree = "<group>"; };
|
||||
8B5A01272CB8542B00E1C37C /* vstplugmain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstplugmain.cpp; sourceTree = "<group>"; };
|
||||
8B5A01282CB8542B00E1C37C /* audioeffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audioeffect.h; sourceTree = "<group>"; };
|
||||
8B0FB93E2CC849930015BC09 /* vstfxstore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vstfxstore.h; sourceTree = "<group>"; };
|
||||
8B0FB93F2CC849930015BC09 /* aeffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffect.h; sourceTree = "<group>"; };
|
||||
8B0FB9402CC849930015BC09 /* aeffectx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffectx.h; sourceTree = "<group>"; };
|
||||
8B0FB9442CC849930015BC09 /* audioeffectx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audioeffectx.h; sourceTree = "<group>"; };
|
||||
8B0FB9452CC849930015BC09 /* audioeffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audioeffect.cpp; sourceTree = "<group>"; };
|
||||
8B0FB9462CC849930015BC09 /* audioeffectx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audioeffectx.cpp; sourceTree = "<group>"; };
|
||||
8B0FB9472CC849930015BC09 /* aeffeditor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aeffeditor.h; sourceTree = "<group>"; };
|
||||
8B0FB9482CC849930015BC09 /* vstplugmain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vstplugmain.cpp; sourceTree = "<group>"; };
|
||||
8B0FB9492CC849930015BC09 /* audioeffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audioeffect.h; sourceTree = "<group>"; };
|
||||
8D01CCD10486CAD60068D4B7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = mac/Info.plist; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
08FB77ADFE841716C02AAC07 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8B5A011A2CB8542B00E1C37C /* vstsdk2.4 */,
|
||||
8B0FB93B2CC849930015BC09 /* vstsdk2.4 */,
|
||||
2407DEB6089929BA00EB68BF /* Mastering.cpp */,
|
||||
24D8286F09A914000093AEF8 /* MasteringProc.cpp */,
|
||||
245463B80991757100464AD3 /* Mastering.h */,
|
||||
|
|
@ -82,59 +82,59 @@
|
|||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8B5A011A2CB8542B00E1C37C /* vstsdk2.4 */ = {
|
||||
8B0FB93B2CC849930015BC09 /* vstsdk2.4 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8B5A011B2CB8542B00E1C37C /* pluginterfaces */,
|
||||
8B5A01202CB8542B00E1C37C /* public.sdk */,
|
||||
8B0FB93C2CC849930015BC09 /* pluginterfaces */,
|
||||
8B0FB9412CC849930015BC09 /* public.sdk */,
|
||||
);
|
||||
name = vstsdk2.4;
|
||||
path = ../../../../vstsdk2.4;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8B5A011B2CB8542B00E1C37C /* pluginterfaces */ = {
|
||||
8B0FB93C2CC849930015BC09 /* pluginterfaces */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8B5A011C2CB8542B00E1C37C /* vst2.x */,
|
||||
8B0FB93D2CC849930015BC09 /* vst2.x */,
|
||||
);
|
||||
path = pluginterfaces;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8B5A011C2CB8542B00E1C37C /* vst2.x */ = {
|
||||
8B0FB93D2CC849930015BC09 /* vst2.x */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8B5A011D2CB8542B00E1C37C /* vstfxstore.h */,
|
||||
8B5A011E2CB8542B00E1C37C /* aeffect.h */,
|
||||
8B5A011F2CB8542B00E1C37C /* aeffectx.h */,
|
||||
8B0FB93E2CC849930015BC09 /* vstfxstore.h */,
|
||||
8B0FB93F2CC849930015BC09 /* aeffect.h */,
|
||||
8B0FB9402CC849930015BC09 /* aeffectx.h */,
|
||||
);
|
||||
path = vst2.x;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8B5A01202CB8542B00E1C37C /* public.sdk */ = {
|
||||
8B0FB9412CC849930015BC09 /* public.sdk */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8B5A01212CB8542B00E1C37C /* source */,
|
||||
8B0FB9422CC849930015BC09 /* source */,
|
||||
);
|
||||
path = public.sdk;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8B5A01212CB8542B00E1C37C /* source */ = {
|
||||
8B0FB9422CC849930015BC09 /* source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8B5A01222CB8542B00E1C37C /* vst2.x */,
|
||||
8B0FB9432CC849930015BC09 /* vst2.x */,
|
||||
);
|
||||
path = source;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8B5A01222CB8542B00E1C37C /* vst2.x */ = {
|
||||
8B0FB9432CC849930015BC09 /* vst2.x */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8B5A01232CB8542B00E1C37C /* audioeffectx.h */,
|
||||
8B5A01242CB8542B00E1C37C /* audioeffect.cpp */,
|
||||
8B5A01252CB8542B00E1C37C /* audioeffectx.cpp */,
|
||||
8B5A01262CB8542B00E1C37C /* aeffeditor.h */,
|
||||
8B5A01272CB8542B00E1C37C /* vstplugmain.cpp */,
|
||||
8B5A01282CB8542B00E1C37C /* audioeffect.h */,
|
||||
8B0FB9442CC849930015BC09 /* audioeffectx.h */,
|
||||
8B0FB9452CC849930015BC09 /* audioeffect.cpp */,
|
||||
8B0FB9462CC849930015BC09 /* audioeffectx.cpp */,
|
||||
8B0FB9472CC849930015BC09 /* aeffeditor.h */,
|
||||
8B0FB9482CC849930015BC09 /* vstplugmain.cpp */,
|
||||
8B0FB9492CC849930015BC09 /* audioeffect.h */,
|
||||
);
|
||||
path = vst2.x;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -146,14 +146,14 @@
|
|||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8B5A012F2CB8542B00E1C37C /* aeffeditor.h in Headers */,
|
||||
8B0FB9502CC849930015BC09 /* aeffeditor.h in Headers */,
|
||||
245463B90991757100464AD3 /* Mastering.h in Headers */,
|
||||
8B5A01312CB8542B00E1C37C /* audioeffect.h in Headers */,
|
||||
8B5A012A2CB8542B00E1C37C /* aeffect.h in Headers */,
|
||||
8B0FB9522CC849930015BC09 /* audioeffect.h in Headers */,
|
||||
8B0FB94B2CC849930015BC09 /* aeffect.h in Headers */,
|
||||
24D8287F09A9164A0093AEF8 /* xcode_vst_prefix.h in Headers */,
|
||||
8B5A012C2CB8542B00E1C37C /* audioeffectx.h in Headers */,
|
||||
8B5A01292CB8542B00E1C37C /* vstfxstore.h in Headers */,
|
||||
8B5A012B2CB8542B00E1C37C /* aeffectx.h in Headers */,
|
||||
8B0FB94D2CC849930015BC09 /* audioeffectx.h in Headers */,
|
||||
8B0FB94A2CC849930015BC09 /* vstfxstore.h in Headers */,
|
||||
8B0FB94C2CC849930015BC09 /* aeffectx.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -193,9 +193,9 @@
|
|||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
Base,
|
||||
en,
|
||||
fr,
|
||||
de,
|
||||
en,
|
||||
ja,
|
||||
);
|
||||
mainGroup = 089C166AFE841209C02AAC07 /* FM-Chopper */;
|
||||
|
|
@ -240,10 +240,10 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8B5A012E2CB8542B00E1C37C /* audioeffectx.cpp in Sources */,
|
||||
8B0FB94F2CC849930015BC09 /* audioeffectx.cpp in Sources */,
|
||||
2407DEB9089929BA00EB68BF /* Mastering.cpp in Sources */,
|
||||
8B5A012D2CB8542B00E1C37C /* audioeffect.cpp in Sources */,
|
||||
8B5A01302CB8542B00E1C37C /* vstplugmain.cpp in Sources */,
|
||||
8B0FB94E2CC849930015BC09 /* audioeffect.cpp in Sources */,
|
||||
8B0FB9512CC849930015BC09 /* vstplugmain.cpp in Sources */,
|
||||
24D8287009A914000093AEF8 /* MasteringProc.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -21,6 +21,7 @@ Mastering::Mastering(audioMasterCallback audioMaster) :
|
|||
G = 0.5;
|
||||
H = 0.5;
|
||||
I = 0.0;
|
||||
J = 1.0;
|
||||
|
||||
for (int x = 0; x < air_total; x++) air[x] = 0.0;
|
||||
for (int x = 0; x < kal_total; x++) {kalM[x] = 0.0;kalS[x] = 0.0;}
|
||||
|
|
@ -36,6 +37,62 @@ Mastering::Mastering(audioMasterCallback audioMaster) :
|
|||
wasNegClipR = false;
|
||||
for (int x = 0; x < 16; x++) {intermediateL[x] = 0.0; intermediateR[x] = 0.0;}
|
||||
|
||||
quantA = 0;
|
||||
quantB = 1;
|
||||
expectedSlew = 0.0;
|
||||
testA = 0.0;
|
||||
testB = 0.0;
|
||||
correction = 0.0;
|
||||
shapedSampleL = 0.0;
|
||||
shapedSampleR = 0.0;
|
||||
currentDither = 0.0;
|
||||
ditherL = 0.0;
|
||||
ditherR = 0.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
hotbinA = 0;
|
||||
hotbinB = 0;
|
||||
benfordize = 0.0;
|
||||
totalA = 0.0;
|
||||
totalB = 0.0;
|
||||
outputSample = 0.0;
|
||||
expon = 0; //internal dither variables
|
||||
//these didn't like to be defined inside a case statement
|
||||
|
||||
NSOddL = 0.0; NSEvenL = 0.0; prevShapeL = 0.0;
|
||||
NSOddR = 0.0; NSEvenR = 0.0; prevShapeR = 0.0;
|
||||
flip = true; //Ten Nines
|
||||
for(int count = 0; count < 99; count++) {
|
||||
darkSampleL[count] = 0;
|
||||
darkSampleR[count] = 0;
|
||||
} //Dark
|
||||
previousDitherL = 0.0;
|
||||
previousDitherR = 0.0; //PaulWide
|
||||
bynL[0] = 1000.0;
|
||||
bynL[1] = 301.0;
|
||||
bynL[2] = 176.0;
|
||||
bynL[3] = 125.0;
|
||||
bynL[4] = 97.0;
|
||||
bynL[5] = 79.0;
|
||||
bynL[6] = 67.0;
|
||||
bynL[7] = 58.0;
|
||||
bynL[8] = 51.0;
|
||||
bynL[9] = 46.0;
|
||||
bynL[10] = 1000.0;
|
||||
noiseShapingL = 0.0;
|
||||
bynR[0] = 1000.0;
|
||||
bynR[1] = 301.0;
|
||||
bynR[2] = 176.0;
|
||||
bynR[3] = 125.0;
|
||||
bynR[4] = 97.0;
|
||||
bynR[5] = 79.0;
|
||||
bynR[6] = 67.0;
|
||||
bynR[7] = 58.0;
|
||||
bynR[8] = 51.0;
|
||||
bynR[9] = 46.0;
|
||||
bynR[10] = 1000.0;
|
||||
noiseShapingR = 0.0; //NJAD
|
||||
|
||||
fpdL = 1.0; while (fpdL < 16386) fpdL = rand()*UINT32_MAX;
|
||||
fpdR = 1.0; while (fpdR < 16386) fpdR = rand()*UINT32_MAX;
|
||||
//this is reset: values being initialized only once. Startup values, whatever they are.
|
||||
|
|
@ -78,6 +135,7 @@ VstInt32 Mastering::getChunk (void** data, bool isPreset)
|
|||
chunkData[6] = G;
|
||||
chunkData[7] = H;
|
||||
chunkData[8] = I;
|
||||
chunkData[9] = J;
|
||||
/* 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. */
|
||||
|
|
@ -98,6 +156,7 @@ VstInt32 Mastering::setChunk (void* data, VstInt32 byteSize, bool isPreset)
|
|||
G = pinParameter(chunkData[6]);
|
||||
H = pinParameter(chunkData[7]);
|
||||
I = pinParameter(chunkData[8]);
|
||||
J = pinParameter(chunkData[9]);
|
||||
/* We're ignoring byteSize as we found it to be a filthy liar */
|
||||
|
||||
/* calculate any other fields you need here - you could copy in
|
||||
|
|
@ -116,6 +175,7 @@ void Mastering::setParameter(VstInt32 index, float value) {
|
|||
case kParamG: G = value; break;
|
||||
case kParamH: H = value; break;
|
||||
case kParamI: I = value; break;
|
||||
case kParamJ: J = value; break;
|
||||
default: throw; // unknown parameter, shouldn't happen!
|
||||
}
|
||||
}
|
||||
|
|
@ -131,6 +191,7 @@ float Mastering::getParameter(VstInt32 index) {
|
|||
case kParamG: return G; break;
|
||||
case kParamH: return H; break;
|
||||
case kParamI: return I; break;
|
||||
case kParamJ: return J; break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} return 0.0; //we only need to update the relevant name, this is simple to manage
|
||||
}
|
||||
|
|
@ -146,6 +207,7 @@ void Mastering::getParameterName(VstInt32 index, char *text) {
|
|||
case kParamG: vst_strncpy (text, "Zoom", kVstMaxParamStrLen); break;
|
||||
case kParamH: vst_strncpy (text, "DarkF", kVstMaxParamStrLen); break;
|
||||
case kParamI: vst_strncpy (text, "Ratio", kVstMaxParamStrLen); break;
|
||||
case kParamJ: vst_strncpy (text, "Dither", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} //this is our labels for displaying in the VST host
|
||||
}
|
||||
|
|
@ -161,6 +223,15 @@ void Mastering::getParameterDisplay(VstInt32 index, char *text) {
|
|||
case kParamG: float2string (G, text, kVstMaxParamStrLen); break;
|
||||
case kParamH: float2string (H, text, kVstMaxParamStrLen); break;
|
||||
case kParamI: float2string (I, text, kVstMaxParamStrLen); break;
|
||||
case kParamJ: switch((VstInt32)( J * 5.999 )) //0 to almost edge of # of params
|
||||
{ case 0: vst_strncpy (text, "Dark", kVstMaxParamStrLen); break;
|
||||
case 1: vst_strncpy (text, "TenNines", kVstMaxParamStrLen); break;
|
||||
case 2: vst_strncpy (text, "TPDFWde", kVstMaxParamStrLen); break;
|
||||
case 3: vst_strncpy (text, "PaulWde", kVstMaxParamStrLen); break;
|
||||
case 4: vst_strncpy (text, "NJAD", kVstMaxParamStrLen); break;
|
||||
case 5: vst_strncpy (text, "Bypass", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} break; //completed consoletype 'popup' parameter, exit
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} //this displays the values and handles 'popups' where it's discrete choices
|
||||
}
|
||||
|
|
@ -176,6 +247,7 @@ void Mastering::getParameterLabel(VstInt32 index, char *text) {
|
|||
case kParamG: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamH: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamI: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamJ: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ enum {
|
|||
kParamG =6,
|
||||
kParamH =7,
|
||||
kParamI =8,
|
||||
kNumParameters = 9
|
||||
kParamJ =9,
|
||||
kNumParameters = 10
|
||||
}; //
|
||||
|
||||
const int kNumPrograms = 0;
|
||||
|
|
@ -69,6 +70,7 @@ private:
|
|||
float G;
|
||||
float H;
|
||||
float I;
|
||||
float J;
|
||||
|
||||
enum {
|
||||
pvAL1,
|
||||
|
|
@ -151,6 +153,41 @@ private:
|
|||
bool wasPosClipR;
|
||||
bool wasNegClipR; //Stereo ClipOnly2
|
||||
|
||||
int quantA;
|
||||
int quantB;
|
||||
float expectedSlew;
|
||||
float testA;
|
||||
float testB;
|
||||
double correction;
|
||||
double shapedSampleL;
|
||||
double shapedSampleR;
|
||||
double currentDither;
|
||||
double ditherL;
|
||||
double ditherR;
|
||||
bool cutbinsL;
|
||||
bool cutbinsR;
|
||||
int hotbinA;
|
||||
int hotbinB;
|
||||
double benfordize;
|
||||
double totalA;
|
||||
double totalB;
|
||||
double outputSample;
|
||||
int expon; //internal dither variables
|
||||
|
||||
double NSOddL; //dither section!
|
||||
double NSEvenL;
|
||||
double prevShapeL;
|
||||
double NSOddR;
|
||||
double NSEvenR;
|
||||
double prevShapeR;
|
||||
bool flip; //VinylDither
|
||||
double darkSampleL[100];
|
||||
double darkSampleR[100]; //Dark
|
||||
double previousDitherL;
|
||||
double previousDitherR; //PaulWide
|
||||
double bynL[13], bynR[13];
|
||||
double noiseShapingL, noiseShapingR; //NJAD
|
||||
|
||||
uint32_t fpdL;
|
||||
uint32_t fpdR;
|
||||
//default stuff
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ void Mastering::processReplacing(float **inputs, float **outputs, VstInt32 sampl
|
|||
double depthSinew = I;
|
||||
int spacing = floor(overallscale); //should give us working basic scaling, usually 2 or 4
|
||||
if (spacing < 1) spacing = 1; if (spacing > 16) spacing = 16;
|
||||
int dither = (int) ( J * 5.999 )+1;
|
||||
int depth = (int)(17.0*overallscale);
|
||||
if (depth < 3) depth = 3;
|
||||
if (depth > 98) depth = 98; //for Dark
|
||||
|
||||
while (--sampleFrames >= 0)
|
||||
{
|
||||
|
|
@ -270,14 +274,388 @@ void Mastering::processReplacing(float **inputs, float **outputs, VstInt32 sampl
|
|||
inputSampleR = (inputSampleR * (1.0-depthSinew))+(lastSinewR*depthSinew);
|
||||
//run Sinew to stop excess slews, but run a dry/wet to allow a range of brights
|
||||
|
||||
//begin 32 bit stereo floating point dither
|
||||
int expon; frexpf((float)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
frexpf((float)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit stereo floating point dither
|
||||
|
||||
switch (dither) {
|
||||
case 1:
|
||||
//begin Dark
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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
|
||||
quantA = floor(inputSampleL);
|
||||
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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark 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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark right
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Dark (Monitoring2)
|
||||
case 2:
|
||||
//begin Dark for Ten Nines
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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 L
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddL = (NSOddL * 0.9999999999) + prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) - prevShapeL;
|
||||
correction = NSOddL;
|
||||
} else {
|
||||
NSOddL = (NSOddL * 0.9999999999) - prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) + prevShapeL;
|
||||
correction = NSEvenL;
|
||||
}
|
||||
shapedSampleL = inputSampleL+correction;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin Dark L
|
||||
quantA = floor(shapedSampleL);
|
||||
quantB = floor(shapedSampleL+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark L
|
||||
|
||||
prevShapeL = (floor(shapedSampleL) - inputSampleL)*0.9999999999;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin R
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddR = (NSOddR * 0.9999999999) + prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) - prevShapeR;
|
||||
correction = NSOddR;
|
||||
} else {
|
||||
NSOddR = (NSOddR * 0.9999999999) - prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) + prevShapeR;
|
||||
correction = NSEvenR;
|
||||
}
|
||||
shapedSampleR = inputSampleR+correction;
|
||||
//end Ten Nines R
|
||||
|
||||
//begin Dark R
|
||||
quantA = floor(shapedSampleR);
|
||||
quantB = floor(shapedSampleR+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark R
|
||||
|
||||
prevShapeR = (floor(shapedSampleR) - inputSampleR)*0.9999999999;
|
||||
//end Ten Nines
|
||||
flip = !flip;
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Ten Nines (which goes into Dark in Monitoring3)
|
||||
case 3:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //TPDFWide (a good neutral with the width enhancement)
|
||||
case 4:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
//Paul Frindle: It's true that the dither itself can sound different
|
||||
//if it's given a different freq response and you get to hear it.
|
||||
//The one we use most is triangular single pole high pass dither.
|
||||
//It's not freq bent enough to sound odd, but is slightly less audible than
|
||||
//flat dither. It can also be easily made by taking one sample of dither
|
||||
//away from the previous one - this gives you the triangular PDF and the
|
||||
//filtering in one go :-)
|
||||
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //PaulWide (brighter neutral that's still TPDF and wide)
|
||||
case 5:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
drySampleL = inputSampleL;//re-using in NJAD
|
||||
inputSampleL -= noiseShapingL;
|
||||
//NJAD L
|
||||
benfordize = floor(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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);
|
||||
inputSampleL /= 8388608.0;
|
||||
if (inputSampleL > 1.0) inputSampleL = 1.0;
|
||||
if (inputSampleL < -1.0) inputSampleL = -1.0;
|
||||
//finished NJAD L
|
||||
|
||||
//NJAD R
|
||||
drySampleR = inputSampleR;
|
||||
inputSampleR -= noiseShapingR;
|
||||
benfordize = floor(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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
|
||||
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);
|
||||
inputSampleR /= 8388608.0;
|
||||
if (inputSampleR > 1.0) inputSampleR = 1.0;
|
||||
if (inputSampleR < -1.0) inputSampleR = -1.0;
|
||||
break; //NJAD (Monitoring. Brightest)
|
||||
case 6:
|
||||
//begin 32 bit stereo floating point dither
|
||||
frexpf((float)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
frexpf((float)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit stereo floating point dither
|
||||
break; //Bypass for saving floating point files directly
|
||||
}
|
||||
|
||||
*out1 = inputSampleL;
|
||||
*out2 = inputSampleR;
|
||||
|
|
@ -318,7 +696,11 @@ void Mastering::processDoubleReplacing(double **inputs, double **outputs, VstInt
|
|||
double depthSinew = I;
|
||||
int spacing = floor(overallscale); //should give us working basic scaling, usually 2 or 4
|
||||
if (spacing < 1) spacing = 1; if (spacing > 16) spacing = 16;
|
||||
|
||||
int dither = (int) ( J * 5.999 )+1;
|
||||
int depth = (int)(17.0*overallscale);
|
||||
if (depth < 3) depth = 3;
|
||||
if (depth > 98) depth = 98; //for Dark
|
||||
|
||||
while (--sampleFrames >= 0)
|
||||
{
|
||||
double inputSampleL = *in1;
|
||||
|
|
@ -552,14 +934,388 @@ void Mastering::processDoubleReplacing(double **inputs, double **outputs, VstInt
|
|||
inputSampleR = (inputSampleR * (1.0-depthSinew))+(lastSinewR*depthSinew);
|
||||
//run Sinew to stop excess slews, but run a dry/wet to allow a range of brights
|
||||
|
||||
//begin 64 bit stereo floating point dither
|
||||
int expon; frexp((double)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
frexp((double)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
//end 64 bit stereo floating point dither
|
||||
|
||||
switch (dither) {
|
||||
case 1:
|
||||
//begin Dark
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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
|
||||
quantA = floor(inputSampleL);
|
||||
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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark 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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark right
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Dark (Monitoring2)
|
||||
case 2:
|
||||
//begin Dark for Ten Nines
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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 L
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddL = (NSOddL * 0.9999999999) + prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) - prevShapeL;
|
||||
correction = NSOddL;
|
||||
} else {
|
||||
NSOddL = (NSOddL * 0.9999999999) - prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) + prevShapeL;
|
||||
correction = NSEvenL;
|
||||
}
|
||||
shapedSampleL = inputSampleL+correction;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin Dark L
|
||||
quantA = floor(shapedSampleL);
|
||||
quantB = floor(shapedSampleL+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark L
|
||||
|
||||
prevShapeL = (floor(shapedSampleL) - inputSampleL)*0.9999999999;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin R
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddR = (NSOddR * 0.9999999999) + prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) - prevShapeR;
|
||||
correction = NSOddR;
|
||||
} else {
|
||||
NSOddR = (NSOddR * 0.9999999999) - prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) + prevShapeR;
|
||||
correction = NSEvenR;
|
||||
}
|
||||
shapedSampleR = inputSampleR+correction;
|
||||
//end Ten Nines R
|
||||
|
||||
//begin Dark R
|
||||
quantA = floor(shapedSampleR);
|
||||
quantB = floor(shapedSampleR+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark R
|
||||
|
||||
prevShapeR = (floor(shapedSampleR) - inputSampleR)*0.9999999999;
|
||||
//end Ten Nines
|
||||
flip = !flip;
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Ten Nines (which goes into Dark in Monitoring3)
|
||||
case 3:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //TPDFWide (a good neutral with the width enhancement)
|
||||
case 4:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
//Paul Frindle: It's true that the dither itself can sound different
|
||||
//if it's given a different freq response and you get to hear it.
|
||||
//The one we use most is triangular single pole high pass dither.
|
||||
//It's not freq bent enough to sound odd, but is slightly less audible than
|
||||
//flat dither. It can also be easily made by taking one sample of dither
|
||||
//away from the previous one - this gives you the triangular PDF and the
|
||||
//filtering in one go :-)
|
||||
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //PaulWide (brighter neutral that's still TPDF and wide)
|
||||
case 5:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
drySampleL = inputSampleL;//re-using in NJAD
|
||||
inputSampleL -= noiseShapingL;
|
||||
//NJAD L
|
||||
benfordize = floor(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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);
|
||||
inputSampleL /= 8388608.0;
|
||||
if (inputSampleL > 1.0) inputSampleL = 1.0;
|
||||
if (inputSampleL < -1.0) inputSampleL = -1.0;
|
||||
//finished NJAD L
|
||||
|
||||
//NJAD R
|
||||
drySampleR = inputSampleR;
|
||||
inputSampleR -= noiseShapingR;
|
||||
benfordize = floor(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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
|
||||
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);
|
||||
inputSampleR /= 8388608.0;
|
||||
if (inputSampleR > 1.0) inputSampleR = 1.0;
|
||||
if (inputSampleR < -1.0) inputSampleR = -1.0;
|
||||
break; //NJAD (Monitoring. Brightest)
|
||||
case 6:
|
||||
//begin 64 bit stereo floating point dither
|
||||
frexp((double)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
frexp((double)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
//end 64 bit stereo floating point dither
|
||||
break; //Bypass for saving floating point files directly
|
||||
}
|
||||
|
||||
*out1 = inputSampleL;
|
||||
*out2 = inputSampleR;
|
||||
|
|
|
|||
|
|
@ -51,13 +51,16 @@
|
|||
PBXFileDataSource_Warnings_ColumnID,
|
||||
);
|
||||
};
|
||||
PBXPerProjectTemplateStateSaveDate = 750255314;
|
||||
PBXWorkspaceStateSaveDate = 750255314;
|
||||
PBXPerProjectTemplateStateSaveDate = 751291914;
|
||||
PBXWorkspaceStateSaveDate = 751291914;
|
||||
};
|
||||
perUserProjectItems = {
|
||||
8BC437242CC70EF00098AE55 /* PBXTextBookmark */ = 8BC437242CC70EF00098AE55 /* PBXTextBookmark */;
|
||||
8BC4377F2CC7CCEC0098AE55 /* PBXTextBookmark */ = 8BC4377F2CC7CCEC0098AE55 /* PBXTextBookmark */;
|
||||
8BC437962CC7CE130098AE55 /* PBXBookmark */ = 8BC437962CC7CE130098AE55 /* PBXBookmark */;
|
||||
8BC437A32CC7CE520098AE55 /* PBXTextBookmark */ = 8BC437A32CC7CE520098AE55 /* PBXTextBookmark */;
|
||||
8BC437A92CC7CE520098AE55 /* PBXTextBookmark */ = 8BC437A92CC7CE520098AE55 /* PBXTextBookmark */;
|
||||
8BF17AF32CB7F7B000FAAF3F /* PBXTextBookmark */ = 8BF17AF32CB7F7B000FAAF3F /* PBXTextBookmark */;
|
||||
8BF17B6A2CB7FF3200FAAF3F /* PBXTextBookmark */ = 8BF17B6A2CB7FF3200FAAF3F /* PBXTextBookmark */;
|
||||
8BF17B6B2CB7FF3200FAAF3F /* PBXTextBookmark */ = 8BF17B6B2CB7FF3200FAAF3F /* PBXTextBookmark */;
|
||||
};
|
||||
sourceControlManager = 8B02375E1D42B1C400E1E8C8 /* Source Control */;
|
||||
userBuildSettings = {
|
||||
|
|
@ -65,17 +68,17 @@
|
|||
};
|
||||
2407DEB6089929BA00EB68BF /* Mastering.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {848, 3330}}";
|
||||
sepNavSelRange = "{5220, 0}";
|
||||
sepNavVisRange = "{5828, 1821}";
|
||||
sepNavWindowFrame = "{{702, 47}, {895, 831}}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {948, 4860}}";
|
||||
sepNavSelRange = "{7531, 13}";
|
||||
sepNavVisRange = "{739, 942}";
|
||||
sepNavWindowFrame = "{{545, 47}, {895, 831}}";
|
||||
};
|
||||
};
|
||||
245463B80991757100464AD3 /* Mastering.h */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1110, 2880}}";
|
||||
sepNavSelRange = "{3289, 0}";
|
||||
sepNavVisRange = "{3111, 702}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {554, 3600}}";
|
||||
sepNavSelRange = "{528, 0}";
|
||||
sepNavVisRange = "{0, 0}";
|
||||
sepNavWindowFrame = "{{545, 47}, {895, 831}}";
|
||||
};
|
||||
};
|
||||
|
|
@ -89,9 +92,9 @@
|
|||
};
|
||||
24D8286F09A914000093AEF8 /* MasteringProc.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {714, 10530}}";
|
||||
sepNavSelRange = "{16048, 0}";
|
||||
sepNavVisRange = "{15306, 97}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1056, 23598}}";
|
||||
sepNavSelRange = "{31210, 0}";
|
||||
sepNavVisRange = "{803, 1981}";
|
||||
sepNavWindowFrame = "{{543, 47}, {895, 831}}";
|
||||
};
|
||||
};
|
||||
|
|
@ -109,36 +112,60 @@
|
|||
isa = PBXCodeSenseManager;
|
||||
indexTemplatePath = "";
|
||||
};
|
||||
8BC437242CC70EF00098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */;
|
||||
name = "MasteringProc.cpp: 325";
|
||||
rLen = 0;
|
||||
rLoc = 31418;
|
||||
rType = 0;
|
||||
vrLen = 0;
|
||||
vrLoc = 0;
|
||||
};
|
||||
8BC4377F2CC7CCEC0098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 245463B80991757100464AD3 /* Mastering.h */;
|
||||
name = "Mastering.h: 29";
|
||||
rLen = 0;
|
||||
rLoc = 528;
|
||||
rType = 0;
|
||||
vrLen = 0;
|
||||
vrLoc = 0;
|
||||
};
|
||||
8BC437962CC7CE130098AE55 /* PBXBookmark */ = {
|
||||
isa = PBXBookmark;
|
||||
fRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */;
|
||||
};
|
||||
8BC437A32CC7CE520098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 245463B80991757100464AD3 /* Mastering.h */;
|
||||
name = "Mastering.h: 29";
|
||||
rLen = 0;
|
||||
rLoc = 528;
|
||||
rType = 0;
|
||||
vrLen = 0;
|
||||
vrLoc = 0;
|
||||
};
|
||||
8BC437A92CC7CE520098AE55 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */;
|
||||
name = "MasteringProc.cpp: 699";
|
||||
rLen = 0;
|
||||
rLoc = 31210;
|
||||
rType = 0;
|
||||
vrLen = 1981;
|
||||
vrLoc = 803;
|
||||
};
|
||||
8BF17AF32CB7F7B000FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 2407DEB6089929BA00EB68BF /* Mastering.cpp */;
|
||||
name = "Mastering.cpp: 29";
|
||||
rLen = 0;
|
||||
rLoc = 707;
|
||||
rLoc = 717;
|
||||
rType = 0;
|
||||
vrLen = 356;
|
||||
vrLoc = 5826;
|
||||
};
|
||||
8BF17B6A2CB7FF3200FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */;
|
||||
name = "MasteringProc.cpp: 325";
|
||||
rLen = 0;
|
||||
rLoc = 16048;
|
||||
rType = 0;
|
||||
vrLen = 126;
|
||||
vrLoc = 15253;
|
||||
};
|
||||
8BF17B6B2CB7FF3200FAAF3F /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 24D8286F09A914000093AEF8 /* MasteringProc.cpp */;
|
||||
name = "MasteringProc.cpp: 325";
|
||||
rLen = 0;
|
||||
rLoc = 16048;
|
||||
rType = 0;
|
||||
vrLen = 97;
|
||||
vrLoc = 15306;
|
||||
};
|
||||
8D01CCC60486CAD60068D4B7 /* Mastering */ = {
|
||||
activeExec = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -222,7 +222,48 @@
|
|||
</dict>
|
||||
</array>
|
||||
<key>OpenEditors</key>
|
||||
<array/>
|
||||
<array>
|
||||
<dict>
|
||||
<key>Content</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8BC437A72CC7CE520098AE55</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MasteringProc.cpp</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8BC437A82CC7CE520098AE55</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MasteringProc.cpp</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>8BC437A92CC7CE520098AE55</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>8BC437962CC7CE130098AE55</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
<key>StatusBarVisibility</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Geometry</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 20}, {895, 734}}</string>
|
||||
<key>PBXModuleWindowStatusBarHidden2</key>
|
||||
<false/>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>543 103 895 775 0 0 1440 878 </string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>PerspectiveWidths</key>
|
||||
<array>
|
||||
<integer>810</integer>
|
||||
|
|
@ -323,7 +364,7 @@
|
|||
<real>185</real>
|
||||
</array>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>579 290 810 487 0 0 1440 878 </string>
|
||||
<string>620 297 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXSmartGroupTreeModule</string>
|
||||
|
|
@ -339,7 +380,7 @@
|
|||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8B0237581D42B1C400E1E8C8</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MasteringProc.cpp</string>
|
||||
<string>Mastering.h</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
|
|
@ -347,15 +388,16 @@
|
|||
<key>PBXProjectModuleGUID</key>
|
||||
<string>8B0237591D42B1C400E1E8C8</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>MasteringProc.cpp</string>
|
||||
<string>Mastering.h</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>8BF17B6B2CB7FF3200FAAF3F</string>
|
||||
<string>8BC437A32CC7CE520098AE55</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>8BF17AF32CB7F7B000FAAF3F</string>
|
||||
<string>8BF17B6A2CB7FF3200FAAF3F</string>
|
||||
<string>8BC437242CC70EF00098AE55</string>
|
||||
<string>8BC4377F2CC7CCEC0098AE55</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
|
|
@ -369,18 +411,18 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {603, 86}}</string>
|
||||
<string>{{0, 0}, {603, 0}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>579 290 810 487 0 0 1440 878 </string>
|
||||
<string>620 297 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<key>Proportion</key>
|
||||
<string>86pt</string>
|
||||
<string>0pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Proportion</key>
|
||||
<string>355pt</string>
|
||||
<string>441pt</string>
|
||||
<key>Tabs</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
@ -394,9 +436,9 @@
|
|||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {603, 328}}</string>
|
||||
<string>{{10, 27}, {603, 414}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>579 290 810 487 0 0 1440 878 </string>
|
||||
<string>620 297 810 487 0 0 1440 878 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>XCDetailModule</string>
|
||||
|
|
@ -478,11 +520,11 @@
|
|||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>8BF17B6C2CB7FF3200FAAF3F</string>
|
||||
<string>8BC437A42CC7CE520098AE55</string>
|
||||
<string>1CA23ED40692098700951B8B</string>
|
||||
<string>8BF17B6D2CB7FF3200FAAF3F</string>
|
||||
<string>8BC437A52CC7CE520098AE55</string>
|
||||
<string>8B0237581D42B1C400E1E8C8</string>
|
||||
<string>8BF17B6E2CB7FF3200FAAF3F</string>
|
||||
<string>8BC437A62CC7CE520098AE55</string>
|
||||
<string>1CA23EDF0692099D00951B8B</string>
|
||||
<string>1CA23EE00692099D00951B8B</string>
|
||||
<string>1CA23EE10692099D00951B8B</string>
|
||||
|
|
@ -655,7 +697,7 @@
|
|||
<key>StatusbarIsVisible</key>
|
||||
<true/>
|
||||
<key>TimeStamp</key>
|
||||
<real>750255922.06214201</real>
|
||||
<real>751291986.86297703</real>
|
||||
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
||||
<string>2</string>
|
||||
<key>ToolbarDisplayMode</key>
|
||||
|
|
@ -672,11 +714,11 @@
|
|||
<integer>5</integer>
|
||||
<key>WindowOrderList</key>
|
||||
<array>
|
||||
<string>8BF17B6F2CB7FF3200FAAF3F</string>
|
||||
<string>/Users/christopherjohnson/Desktop/airwindows/plugins/MacVST/Mastering/Mastering.xcodeproj</string>
|
||||
<string>8BC437A72CC7CE520098AE55</string>
|
||||
</array>
|
||||
<key>WindowString</key>
|
||||
<string>579 290 810 487 0 0 1440 878 </string>
|
||||
<string>620 297 810 487 0 0 1440 878 </string>
|
||||
<key>WindowToolsV3</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ Mastering::Mastering(audioMasterCallback audioMaster) :
|
|||
G = 0.5;
|
||||
H = 0.5;
|
||||
I = 0.0;
|
||||
J = 1.0;
|
||||
|
||||
for (int x = 0; x < air_total; x++) air[x] = 0.0;
|
||||
for (int x = 0; x < kal_total; x++) {kalM[x] = 0.0;kalS[x] = 0.0;}
|
||||
|
|
@ -36,6 +37,62 @@ Mastering::Mastering(audioMasterCallback audioMaster) :
|
|||
wasNegClipR = false;
|
||||
for (int x = 0; x < 16; x++) {intermediateL[x] = 0.0; intermediateR[x] = 0.0;}
|
||||
|
||||
quantA = 0;
|
||||
quantB = 1;
|
||||
expectedSlew = 0.0;
|
||||
testA = 0.0;
|
||||
testB = 0.0;
|
||||
correction = 0.0;
|
||||
shapedSampleL = 0.0;
|
||||
shapedSampleR = 0.0;
|
||||
currentDither = 0.0;
|
||||
ditherL = 0.0;
|
||||
ditherR = 0.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
hotbinA = 0;
|
||||
hotbinB = 0;
|
||||
benfordize = 0.0;
|
||||
totalA = 0.0;
|
||||
totalB = 0.0;
|
||||
outputSample = 0.0;
|
||||
expon = 0; //internal dither variables
|
||||
//these didn't like to be defined inside a case statement
|
||||
|
||||
NSOddL = 0.0; NSEvenL = 0.0; prevShapeL = 0.0;
|
||||
NSOddR = 0.0; NSEvenR = 0.0; prevShapeR = 0.0;
|
||||
flip = true; //Ten Nines
|
||||
for(int count = 0; count < 99; count++) {
|
||||
darkSampleL[count] = 0;
|
||||
darkSampleR[count] = 0;
|
||||
} //Dark
|
||||
previousDitherL = 0.0;
|
||||
previousDitherR = 0.0; //PaulWide
|
||||
bynL[0] = 1000.0;
|
||||
bynL[1] = 301.0;
|
||||
bynL[2] = 176.0;
|
||||
bynL[3] = 125.0;
|
||||
bynL[4] = 97.0;
|
||||
bynL[5] = 79.0;
|
||||
bynL[6] = 67.0;
|
||||
bynL[7] = 58.0;
|
||||
bynL[8] = 51.0;
|
||||
bynL[9] = 46.0;
|
||||
bynL[10] = 1000.0;
|
||||
noiseShapingL = 0.0;
|
||||
bynR[0] = 1000.0;
|
||||
bynR[1] = 301.0;
|
||||
bynR[2] = 176.0;
|
||||
bynR[3] = 125.0;
|
||||
bynR[4] = 97.0;
|
||||
bynR[5] = 79.0;
|
||||
bynR[6] = 67.0;
|
||||
bynR[7] = 58.0;
|
||||
bynR[8] = 51.0;
|
||||
bynR[9] = 46.0;
|
||||
bynR[10] = 1000.0;
|
||||
noiseShapingR = 0.0; //NJAD
|
||||
|
||||
fpdL = 1.0; while (fpdL < 16386) fpdL = rand()*UINT32_MAX;
|
||||
fpdR = 1.0; while (fpdR < 16386) fpdR = rand()*UINT32_MAX;
|
||||
//this is reset: values being initialized only once. Startup values, whatever they are.
|
||||
|
|
@ -78,6 +135,7 @@ VstInt32 Mastering::getChunk (void** data, bool isPreset)
|
|||
chunkData[6] = G;
|
||||
chunkData[7] = H;
|
||||
chunkData[8] = I;
|
||||
chunkData[9] = J;
|
||||
/* 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. */
|
||||
|
|
@ -98,6 +156,7 @@ VstInt32 Mastering::setChunk (void* data, VstInt32 byteSize, bool isPreset)
|
|||
G = pinParameter(chunkData[6]);
|
||||
H = pinParameter(chunkData[7]);
|
||||
I = pinParameter(chunkData[8]);
|
||||
J = pinParameter(chunkData[9]);
|
||||
/* We're ignoring byteSize as we found it to be a filthy liar */
|
||||
|
||||
/* calculate any other fields you need here - you could copy in
|
||||
|
|
@ -116,6 +175,7 @@ void Mastering::setParameter(VstInt32 index, float value) {
|
|||
case kParamG: G = value; break;
|
||||
case kParamH: H = value; break;
|
||||
case kParamI: I = value; break;
|
||||
case kParamJ: J = value; break;
|
||||
default: throw; // unknown parameter, shouldn't happen!
|
||||
}
|
||||
}
|
||||
|
|
@ -131,6 +191,7 @@ float Mastering::getParameter(VstInt32 index) {
|
|||
case kParamG: return G; break;
|
||||
case kParamH: return H; break;
|
||||
case kParamI: return I; break;
|
||||
case kParamJ: return J; break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} return 0.0; //we only need to update the relevant name, this is simple to manage
|
||||
}
|
||||
|
|
@ -146,6 +207,7 @@ void Mastering::getParameterName(VstInt32 index, char *text) {
|
|||
case kParamG: vst_strncpy (text, "Zoom", kVstMaxParamStrLen); break;
|
||||
case kParamH: vst_strncpy (text, "DarkF", kVstMaxParamStrLen); break;
|
||||
case kParamI: vst_strncpy (text, "Ratio", kVstMaxParamStrLen); break;
|
||||
case kParamJ: vst_strncpy (text, "Dither", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} //this is our labels for displaying in the VST host
|
||||
}
|
||||
|
|
@ -161,6 +223,15 @@ void Mastering::getParameterDisplay(VstInt32 index, char *text) {
|
|||
case kParamG: float2string (G, text, kVstMaxParamStrLen); break;
|
||||
case kParamH: float2string (H, text, kVstMaxParamStrLen); break;
|
||||
case kParamI: float2string (I, text, kVstMaxParamStrLen); break;
|
||||
case kParamJ: switch((VstInt32)( J * 5.999 )) //0 to almost edge of # of params
|
||||
{ case 0: vst_strncpy (text, "Dark", kVstMaxParamStrLen); break;
|
||||
case 1: vst_strncpy (text, "TenNines", kVstMaxParamStrLen); break;
|
||||
case 2: vst_strncpy (text, "TPDFWde", kVstMaxParamStrLen); break;
|
||||
case 3: vst_strncpy (text, "PaulWde", kVstMaxParamStrLen); break;
|
||||
case 4: vst_strncpy (text, "NJAD", kVstMaxParamStrLen); break;
|
||||
case 5: vst_strncpy (text, "Bypass", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} break; //completed consoletype 'popup' parameter, exit
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} //this displays the values and handles 'popups' where it's discrete choices
|
||||
}
|
||||
|
|
@ -176,6 +247,7 @@ void Mastering::getParameterLabel(VstInt32 index, char *text) {
|
|||
case kParamG: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamH: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamI: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamJ: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ enum {
|
|||
kParamG =6,
|
||||
kParamH =7,
|
||||
kParamI =8,
|
||||
kNumParameters = 9
|
||||
kParamJ =9,
|
||||
kNumParameters = 10
|
||||
}; //
|
||||
|
||||
const int kNumPrograms = 0;
|
||||
|
|
@ -69,6 +70,7 @@ private:
|
|||
float G;
|
||||
float H;
|
||||
float I;
|
||||
float J;
|
||||
|
||||
enum {
|
||||
pvAL1,
|
||||
|
|
@ -151,6 +153,41 @@ private:
|
|||
bool wasPosClipR;
|
||||
bool wasNegClipR; //Stereo ClipOnly2
|
||||
|
||||
int quantA;
|
||||
int quantB;
|
||||
float expectedSlew;
|
||||
float testA;
|
||||
float testB;
|
||||
double correction;
|
||||
double shapedSampleL;
|
||||
double shapedSampleR;
|
||||
double currentDither;
|
||||
double ditherL;
|
||||
double ditherR;
|
||||
bool cutbinsL;
|
||||
bool cutbinsR;
|
||||
int hotbinA;
|
||||
int hotbinB;
|
||||
double benfordize;
|
||||
double totalA;
|
||||
double totalB;
|
||||
double outputSample;
|
||||
int expon; //internal dither variables
|
||||
|
||||
double NSOddL; //dither section!
|
||||
double NSEvenL;
|
||||
double prevShapeL;
|
||||
double NSOddR;
|
||||
double NSEvenR;
|
||||
double prevShapeR;
|
||||
bool flip; //VinylDither
|
||||
double darkSampleL[100];
|
||||
double darkSampleR[100]; //Dark
|
||||
double previousDitherL;
|
||||
double previousDitherR; //PaulWide
|
||||
double bynL[13], bynR[13];
|
||||
double noiseShapingL, noiseShapingR; //NJAD
|
||||
|
||||
uint32_t fpdL;
|
||||
uint32_t fpdR;
|
||||
//default stuff
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ void Mastering::processReplacing(float **inputs, float **outputs, VstInt32 sampl
|
|||
double depthSinew = I;
|
||||
int spacing = floor(overallscale); //should give us working basic scaling, usually 2 or 4
|
||||
if (spacing < 1) spacing = 1; if (spacing > 16) spacing = 16;
|
||||
int dither = (int) ( J * 5.999 )+1;
|
||||
int depth = (int)(17.0*overallscale);
|
||||
if (depth < 3) depth = 3;
|
||||
if (depth > 98) depth = 98; //for Dark
|
||||
|
||||
while (--sampleFrames >= 0)
|
||||
{
|
||||
|
|
@ -270,14 +274,388 @@ void Mastering::processReplacing(float **inputs, float **outputs, VstInt32 sampl
|
|||
inputSampleR = (inputSampleR * (1.0-depthSinew))+(lastSinewR*depthSinew);
|
||||
//run Sinew to stop excess slews, but run a dry/wet to allow a range of brights
|
||||
|
||||
//begin 32 bit stereo floating point dither
|
||||
int expon; frexpf((float)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
frexpf((float)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit stereo floating point dither
|
||||
|
||||
switch (dither) {
|
||||
case 1:
|
||||
//begin Dark
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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
|
||||
quantA = floor(inputSampleL);
|
||||
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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark 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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark right
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Dark (Monitoring2)
|
||||
case 2:
|
||||
//begin Dark for Ten Nines
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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 L
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddL = (NSOddL * 0.9999999999) + prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) - prevShapeL;
|
||||
correction = NSOddL;
|
||||
} else {
|
||||
NSOddL = (NSOddL * 0.9999999999) - prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) + prevShapeL;
|
||||
correction = NSEvenL;
|
||||
}
|
||||
shapedSampleL = inputSampleL+correction;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin Dark L
|
||||
quantA = floor(shapedSampleL);
|
||||
quantB = floor(shapedSampleL+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark L
|
||||
|
||||
prevShapeL = (floor(shapedSampleL) - inputSampleL)*0.9999999999;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin R
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddR = (NSOddR * 0.9999999999) + prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) - prevShapeR;
|
||||
correction = NSOddR;
|
||||
} else {
|
||||
NSOddR = (NSOddR * 0.9999999999) - prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) + prevShapeR;
|
||||
correction = NSEvenR;
|
||||
}
|
||||
shapedSampleR = inputSampleR+correction;
|
||||
//end Ten Nines R
|
||||
|
||||
//begin Dark R
|
||||
quantA = floor(shapedSampleR);
|
||||
quantB = floor(shapedSampleR+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark R
|
||||
|
||||
prevShapeR = (floor(shapedSampleR) - inputSampleR)*0.9999999999;
|
||||
//end Ten Nines
|
||||
flip = !flip;
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Ten Nines (which goes into Dark in Monitoring3)
|
||||
case 3:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //TPDFWide (a good neutral with the width enhancement)
|
||||
case 4:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
//Paul Frindle: It's true that the dither itself can sound different
|
||||
//if it's given a different freq response and you get to hear it.
|
||||
//The one we use most is triangular single pole high pass dither.
|
||||
//It's not freq bent enough to sound odd, but is slightly less audible than
|
||||
//flat dither. It can also be easily made by taking one sample of dither
|
||||
//away from the previous one - this gives you the triangular PDF and the
|
||||
//filtering in one go :-)
|
||||
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //PaulWide (brighter neutral that's still TPDF and wide)
|
||||
case 5:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
drySampleL = inputSampleL;//re-using in NJAD
|
||||
inputSampleL -= noiseShapingL;
|
||||
//NJAD L
|
||||
benfordize = floor(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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);
|
||||
inputSampleL /= 8388608.0;
|
||||
if (inputSampleL > 1.0) inputSampleL = 1.0;
|
||||
if (inputSampleL < -1.0) inputSampleL = -1.0;
|
||||
//finished NJAD L
|
||||
|
||||
//NJAD R
|
||||
drySampleR = inputSampleR;
|
||||
inputSampleR -= noiseShapingR;
|
||||
benfordize = floor(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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
|
||||
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);
|
||||
inputSampleR /= 8388608.0;
|
||||
if (inputSampleR > 1.0) inputSampleR = 1.0;
|
||||
if (inputSampleR < -1.0) inputSampleR = -1.0;
|
||||
break; //NJAD (Monitoring. Brightest)
|
||||
case 6:
|
||||
//begin 32 bit stereo floating point dither
|
||||
frexpf((float)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
frexpf((float)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit stereo floating point dither
|
||||
break; //Bypass for saving floating point files directly
|
||||
}
|
||||
|
||||
*out1 = inputSampleL;
|
||||
*out2 = inputSampleR;
|
||||
|
|
@ -318,7 +696,11 @@ void Mastering::processDoubleReplacing(double **inputs, double **outputs, VstInt
|
|||
double depthSinew = I;
|
||||
int spacing = floor(overallscale); //should give us working basic scaling, usually 2 or 4
|
||||
if (spacing < 1) spacing = 1; if (spacing > 16) spacing = 16;
|
||||
|
||||
int dither = (int) ( J * 5.999 )+1;
|
||||
int depth = (int)(17.0*overallscale);
|
||||
if (depth < 3) depth = 3;
|
||||
if (depth > 98) depth = 98; //for Dark
|
||||
|
||||
while (--sampleFrames >= 0)
|
||||
{
|
||||
double inputSampleL = *in1;
|
||||
|
|
@ -552,14 +934,388 @@ void Mastering::processDoubleReplacing(double **inputs, double **outputs, VstInt
|
|||
inputSampleR = (inputSampleR * (1.0-depthSinew))+(lastSinewR*depthSinew);
|
||||
//run Sinew to stop excess slews, but run a dry/wet to allow a range of brights
|
||||
|
||||
//begin 64 bit stereo floating point dither
|
||||
int expon; frexp((double)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
frexp((double)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
//end 64 bit stereo floating point dither
|
||||
|
||||
switch (dither) {
|
||||
case 1:
|
||||
//begin Dark
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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
|
||||
quantA = floor(inputSampleL);
|
||||
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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark 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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark right
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Dark (Monitoring2)
|
||||
case 2:
|
||||
//begin Dark for Ten Nines
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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 L
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddL = (NSOddL * 0.9999999999) + prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) - prevShapeL;
|
||||
correction = NSOddL;
|
||||
} else {
|
||||
NSOddL = (NSOddL * 0.9999999999) - prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) + prevShapeL;
|
||||
correction = NSEvenL;
|
||||
}
|
||||
shapedSampleL = inputSampleL+correction;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin Dark L
|
||||
quantA = floor(shapedSampleL);
|
||||
quantB = floor(shapedSampleL+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark L
|
||||
|
||||
prevShapeL = (floor(shapedSampleL) - inputSampleL)*0.9999999999;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin R
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddR = (NSOddR * 0.9999999999) + prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) - prevShapeR;
|
||||
correction = NSOddR;
|
||||
} else {
|
||||
NSOddR = (NSOddR * 0.9999999999) - prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) + prevShapeR;
|
||||
correction = NSEvenR;
|
||||
}
|
||||
shapedSampleR = inputSampleR+correction;
|
||||
//end Ten Nines R
|
||||
|
||||
//begin Dark R
|
||||
quantA = floor(shapedSampleR);
|
||||
quantB = floor(shapedSampleR+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark R
|
||||
|
||||
prevShapeR = (floor(shapedSampleR) - inputSampleR)*0.9999999999;
|
||||
//end Ten Nines
|
||||
flip = !flip;
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Ten Nines (which goes into Dark in Monitoring3)
|
||||
case 3:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //TPDFWide (a good neutral with the width enhancement)
|
||||
case 4:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
//Paul Frindle: It's true that the dither itself can sound different
|
||||
//if it's given a different freq response and you get to hear it.
|
||||
//The one we use most is triangular single pole high pass dither.
|
||||
//It's not freq bent enough to sound odd, but is slightly less audible than
|
||||
//flat dither. It can also be easily made by taking one sample of dither
|
||||
//away from the previous one - this gives you the triangular PDF and the
|
||||
//filtering in one go :-)
|
||||
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //PaulWide (brighter neutral that's still TPDF and wide)
|
||||
case 5:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
drySampleL = inputSampleL;//re-using in NJAD
|
||||
inputSampleL -= noiseShapingL;
|
||||
//NJAD L
|
||||
benfordize = floor(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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);
|
||||
inputSampleL /= 8388608.0;
|
||||
if (inputSampleL > 1.0) inputSampleL = 1.0;
|
||||
if (inputSampleL < -1.0) inputSampleL = -1.0;
|
||||
//finished NJAD L
|
||||
|
||||
//NJAD R
|
||||
drySampleR = inputSampleR;
|
||||
inputSampleR -= noiseShapingR;
|
||||
benfordize = floor(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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
|
||||
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);
|
||||
inputSampleR /= 8388608.0;
|
||||
if (inputSampleR > 1.0) inputSampleR = 1.0;
|
||||
if (inputSampleR < -1.0) inputSampleR = -1.0;
|
||||
break; //NJAD (Monitoring. Brightest)
|
||||
case 6:
|
||||
//begin 64 bit stereo floating point dither
|
||||
frexp((double)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
frexp((double)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
//end 64 bit stereo floating point dither
|
||||
break; //Bypass for saving floating point files directly
|
||||
}
|
||||
|
||||
*out1 = inputSampleL;
|
||||
*out2 = inputSampleR;
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -21,6 +21,7 @@ Mastering::Mastering(audioMasterCallback audioMaster) :
|
|||
G = 0.5;
|
||||
H = 0.5;
|
||||
I = 0.0;
|
||||
J = 1.0;
|
||||
|
||||
for (int x = 0; x < air_total; x++) air[x] = 0.0;
|
||||
for (int x = 0; x < kal_total; x++) {kalM[x] = 0.0;kalS[x] = 0.0;}
|
||||
|
|
@ -36,6 +37,62 @@ Mastering::Mastering(audioMasterCallback audioMaster) :
|
|||
wasNegClipR = false;
|
||||
for (int x = 0; x < 16; x++) {intermediateL[x] = 0.0; intermediateR[x] = 0.0;}
|
||||
|
||||
quantA = 0;
|
||||
quantB = 1;
|
||||
expectedSlew = 0.0;
|
||||
testA = 0.0;
|
||||
testB = 0.0;
|
||||
correction = 0.0;
|
||||
shapedSampleL = 0.0;
|
||||
shapedSampleR = 0.0;
|
||||
currentDither = 0.0;
|
||||
ditherL = 0.0;
|
||||
ditherR = 0.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
hotbinA = 0;
|
||||
hotbinB = 0;
|
||||
benfordize = 0.0;
|
||||
totalA = 0.0;
|
||||
totalB = 0.0;
|
||||
outputSample = 0.0;
|
||||
expon = 0; //internal dither variables
|
||||
//these didn't like to be defined inside a case statement
|
||||
|
||||
NSOddL = 0.0; NSEvenL = 0.0; prevShapeL = 0.0;
|
||||
NSOddR = 0.0; NSEvenR = 0.0; prevShapeR = 0.0;
|
||||
flip = true; //Ten Nines
|
||||
for(int count = 0; count < 99; count++) {
|
||||
darkSampleL[count] = 0;
|
||||
darkSampleR[count] = 0;
|
||||
} //Dark
|
||||
previousDitherL = 0.0;
|
||||
previousDitherR = 0.0; //PaulWide
|
||||
bynL[0] = 1000.0;
|
||||
bynL[1] = 301.0;
|
||||
bynL[2] = 176.0;
|
||||
bynL[3] = 125.0;
|
||||
bynL[4] = 97.0;
|
||||
bynL[5] = 79.0;
|
||||
bynL[6] = 67.0;
|
||||
bynL[7] = 58.0;
|
||||
bynL[8] = 51.0;
|
||||
bynL[9] = 46.0;
|
||||
bynL[10] = 1000.0;
|
||||
noiseShapingL = 0.0;
|
||||
bynR[0] = 1000.0;
|
||||
bynR[1] = 301.0;
|
||||
bynR[2] = 176.0;
|
||||
bynR[3] = 125.0;
|
||||
bynR[4] = 97.0;
|
||||
bynR[5] = 79.0;
|
||||
bynR[6] = 67.0;
|
||||
bynR[7] = 58.0;
|
||||
bynR[8] = 51.0;
|
||||
bynR[9] = 46.0;
|
||||
bynR[10] = 1000.0;
|
||||
noiseShapingR = 0.0; //NJAD
|
||||
|
||||
fpdL = 1.0; while (fpdL < 16386) fpdL = rand()*UINT32_MAX;
|
||||
fpdR = 1.0; while (fpdR < 16386) fpdR = rand()*UINT32_MAX;
|
||||
//this is reset: values being initialized only once. Startup values, whatever they are.
|
||||
|
|
@ -78,6 +135,7 @@ VstInt32 Mastering::getChunk (void** data, bool isPreset)
|
|||
chunkData[6] = G;
|
||||
chunkData[7] = H;
|
||||
chunkData[8] = I;
|
||||
chunkData[9] = J;
|
||||
/* 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. */
|
||||
|
|
@ -98,6 +156,7 @@ VstInt32 Mastering::setChunk (void* data, VstInt32 byteSize, bool isPreset)
|
|||
G = pinParameter(chunkData[6]);
|
||||
H = pinParameter(chunkData[7]);
|
||||
I = pinParameter(chunkData[8]);
|
||||
J = pinParameter(chunkData[9]);
|
||||
/* We're ignoring byteSize as we found it to be a filthy liar */
|
||||
|
||||
/* calculate any other fields you need here - you could copy in
|
||||
|
|
@ -116,6 +175,7 @@ void Mastering::setParameter(VstInt32 index, float value) {
|
|||
case kParamG: G = value; break;
|
||||
case kParamH: H = value; break;
|
||||
case kParamI: I = value; break;
|
||||
case kParamJ: J = value; break;
|
||||
default: throw; // unknown parameter, shouldn't happen!
|
||||
}
|
||||
}
|
||||
|
|
@ -131,6 +191,7 @@ float Mastering::getParameter(VstInt32 index) {
|
|||
case kParamG: return G; break;
|
||||
case kParamH: return H; break;
|
||||
case kParamI: return I; break;
|
||||
case kParamJ: return J; break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} return 0.0; //we only need to update the relevant name, this is simple to manage
|
||||
}
|
||||
|
|
@ -146,6 +207,7 @@ void Mastering::getParameterName(VstInt32 index, char *text) {
|
|||
case kParamG: vst_strncpy (text, "Zoom", kVstMaxParamStrLen); break;
|
||||
case kParamH: vst_strncpy (text, "DarkF", kVstMaxParamStrLen); break;
|
||||
case kParamI: vst_strncpy (text, "Ratio", kVstMaxParamStrLen); break;
|
||||
case kParamJ: vst_strncpy (text, "Dither", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} //this is our labels for displaying in the VST host
|
||||
}
|
||||
|
|
@ -161,6 +223,15 @@ void Mastering::getParameterDisplay(VstInt32 index, char *text) {
|
|||
case kParamG: float2string (G, text, kVstMaxParamStrLen); break;
|
||||
case kParamH: float2string (H, text, kVstMaxParamStrLen); break;
|
||||
case kParamI: float2string (I, text, kVstMaxParamStrLen); break;
|
||||
case kParamJ: switch((VstInt32)( J * 5.999 )) //0 to almost edge of # of params
|
||||
{ case 0: vst_strncpy (text, "Dark", kVstMaxParamStrLen); break;
|
||||
case 1: vst_strncpy (text, "TenNines", kVstMaxParamStrLen); break;
|
||||
case 2: vst_strncpy (text, "TPDFWde", kVstMaxParamStrLen); break;
|
||||
case 3: vst_strncpy (text, "PaulWde", kVstMaxParamStrLen); break;
|
||||
case 4: vst_strncpy (text, "NJAD", kVstMaxParamStrLen); break;
|
||||
case 5: vst_strncpy (text, "Bypass", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} break; //completed consoletype 'popup' parameter, exit
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
} //this displays the values and handles 'popups' where it's discrete choices
|
||||
}
|
||||
|
|
@ -176,6 +247,7 @@ void Mastering::getParameterLabel(VstInt32 index, char *text) {
|
|||
case kParamG: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamH: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamI: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
case kParamJ: vst_strncpy (text, "", kVstMaxParamStrLen); break;
|
||||
default: break; // unknown parameter, shouldn't happen!
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ enum {
|
|||
kParamG =6,
|
||||
kParamH =7,
|
||||
kParamI =8,
|
||||
kNumParameters = 9
|
||||
kParamJ =9,
|
||||
kNumParameters = 10
|
||||
}; //
|
||||
|
||||
const int kNumPrograms = 0;
|
||||
|
|
@ -69,6 +70,7 @@ private:
|
|||
float G;
|
||||
float H;
|
||||
float I;
|
||||
float J;
|
||||
|
||||
enum {
|
||||
pvAL1,
|
||||
|
|
@ -151,6 +153,41 @@ private:
|
|||
bool wasPosClipR;
|
||||
bool wasNegClipR; //Stereo ClipOnly2
|
||||
|
||||
int quantA;
|
||||
int quantB;
|
||||
float expectedSlew;
|
||||
float testA;
|
||||
float testB;
|
||||
double correction;
|
||||
double shapedSampleL;
|
||||
double shapedSampleR;
|
||||
double currentDither;
|
||||
double ditherL;
|
||||
double ditherR;
|
||||
bool cutbinsL;
|
||||
bool cutbinsR;
|
||||
int hotbinA;
|
||||
int hotbinB;
|
||||
double benfordize;
|
||||
double totalA;
|
||||
double totalB;
|
||||
double outputSample;
|
||||
int expon; //internal dither variables
|
||||
|
||||
double NSOddL; //dither section!
|
||||
double NSEvenL;
|
||||
double prevShapeL;
|
||||
double NSOddR;
|
||||
double NSEvenR;
|
||||
double prevShapeR;
|
||||
bool flip; //VinylDither
|
||||
double darkSampleL[100];
|
||||
double darkSampleR[100]; //Dark
|
||||
double previousDitherL;
|
||||
double previousDitherR; //PaulWide
|
||||
double bynL[13], bynR[13];
|
||||
double noiseShapingL, noiseShapingR; //NJAD
|
||||
|
||||
uint32_t fpdL;
|
||||
uint32_t fpdR;
|
||||
//default stuff
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ void Mastering::processReplacing(float **inputs, float **outputs, VstInt32 sampl
|
|||
double depthSinew = I;
|
||||
int spacing = floor(overallscale); //should give us working basic scaling, usually 2 or 4
|
||||
if (spacing < 1) spacing = 1; if (spacing > 16) spacing = 16;
|
||||
int dither = (int) ( J * 5.999 )+1;
|
||||
int depth = (int)(17.0*overallscale);
|
||||
if (depth < 3) depth = 3;
|
||||
if (depth > 98) depth = 98; //for Dark
|
||||
|
||||
while (--sampleFrames >= 0)
|
||||
{
|
||||
|
|
@ -270,14 +274,388 @@ void Mastering::processReplacing(float **inputs, float **outputs, VstInt32 sampl
|
|||
inputSampleR = (inputSampleR * (1.0-depthSinew))+(lastSinewR*depthSinew);
|
||||
//run Sinew to stop excess slews, but run a dry/wet to allow a range of brights
|
||||
|
||||
//begin 32 bit stereo floating point dither
|
||||
int expon; frexpf((float)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
frexpf((float)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit stereo floating point dither
|
||||
|
||||
switch (dither) {
|
||||
case 1:
|
||||
//begin Dark
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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
|
||||
quantA = floor(inputSampleL);
|
||||
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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark 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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark right
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Dark (Monitoring2)
|
||||
case 2:
|
||||
//begin Dark for Ten Nines
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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 L
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddL = (NSOddL * 0.9999999999) + prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) - prevShapeL;
|
||||
correction = NSOddL;
|
||||
} else {
|
||||
NSOddL = (NSOddL * 0.9999999999) - prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) + prevShapeL;
|
||||
correction = NSEvenL;
|
||||
}
|
||||
shapedSampleL = inputSampleL+correction;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin Dark L
|
||||
quantA = floor(shapedSampleL);
|
||||
quantB = floor(shapedSampleL+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark L
|
||||
|
||||
prevShapeL = (floor(shapedSampleL) - inputSampleL)*0.9999999999;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin R
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddR = (NSOddR * 0.9999999999) + prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) - prevShapeR;
|
||||
correction = NSOddR;
|
||||
} else {
|
||||
NSOddR = (NSOddR * 0.9999999999) - prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) + prevShapeR;
|
||||
correction = NSEvenR;
|
||||
}
|
||||
shapedSampleR = inputSampleR+correction;
|
||||
//end Ten Nines R
|
||||
|
||||
//begin Dark R
|
||||
quantA = floor(shapedSampleR);
|
||||
quantB = floor(shapedSampleR+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark R
|
||||
|
||||
prevShapeR = (floor(shapedSampleR) - inputSampleR)*0.9999999999;
|
||||
//end Ten Nines
|
||||
flip = !flip;
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Ten Nines (which goes into Dark in Monitoring3)
|
||||
case 3:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //TPDFWide (a good neutral with the width enhancement)
|
||||
case 4:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
//Paul Frindle: It's true that the dither itself can sound different
|
||||
//if it's given a different freq response and you get to hear it.
|
||||
//The one we use most is triangular single pole high pass dither.
|
||||
//It's not freq bent enough to sound odd, but is slightly less audible than
|
||||
//flat dither. It can also be easily made by taking one sample of dither
|
||||
//away from the previous one - this gives you the triangular PDF and the
|
||||
//filtering in one go :-)
|
||||
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //PaulWide (brighter neutral that's still TPDF and wide)
|
||||
case 5:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
drySampleL = inputSampleL;//re-using in NJAD
|
||||
inputSampleL -= noiseShapingL;
|
||||
//NJAD L
|
||||
benfordize = floor(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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);
|
||||
inputSampleL /= 8388608.0;
|
||||
if (inputSampleL > 1.0) inputSampleL = 1.0;
|
||||
if (inputSampleL < -1.0) inputSampleL = -1.0;
|
||||
//finished NJAD L
|
||||
|
||||
//NJAD R
|
||||
drySampleR = inputSampleR;
|
||||
inputSampleR -= noiseShapingR;
|
||||
benfordize = floor(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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
|
||||
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);
|
||||
inputSampleR /= 8388608.0;
|
||||
if (inputSampleR > 1.0) inputSampleR = 1.0;
|
||||
if (inputSampleR < -1.0) inputSampleR = -1.0;
|
||||
break; //NJAD (Monitoring. Brightest)
|
||||
case 6:
|
||||
//begin 32 bit stereo floating point dither
|
||||
frexpf((float)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
frexpf((float)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 5.5e-36l * pow(2,expon+62));
|
||||
//end 32 bit stereo floating point dither
|
||||
break; //Bypass for saving floating point files directly
|
||||
}
|
||||
|
||||
*out1 = inputSampleL;
|
||||
*out2 = inputSampleR;
|
||||
|
|
@ -318,7 +696,11 @@ void Mastering::processDoubleReplacing(double **inputs, double **outputs, VstInt
|
|||
double depthSinew = I;
|
||||
int spacing = floor(overallscale); //should give us working basic scaling, usually 2 or 4
|
||||
if (spacing < 1) spacing = 1; if (spacing > 16) spacing = 16;
|
||||
|
||||
int dither = (int) ( J * 5.999 )+1;
|
||||
int depth = (int)(17.0*overallscale);
|
||||
if (depth < 3) depth = 3;
|
||||
if (depth > 98) depth = 98; //for Dark
|
||||
|
||||
while (--sampleFrames >= 0)
|
||||
{
|
||||
double inputSampleL = *in1;
|
||||
|
|
@ -552,14 +934,388 @@ void Mastering::processDoubleReplacing(double **inputs, double **outputs, VstInt
|
|||
inputSampleR = (inputSampleR * (1.0-depthSinew))+(lastSinewR*depthSinew);
|
||||
//run Sinew to stop excess slews, but run a dry/wet to allow a range of brights
|
||||
|
||||
//begin 64 bit stereo floating point dither
|
||||
int expon; frexp((double)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
frexp((double)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
//end 64 bit stereo floating point dither
|
||||
|
||||
switch (dither) {
|
||||
case 1:
|
||||
//begin Dark
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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
|
||||
quantA = floor(inputSampleL);
|
||||
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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark 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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark right
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Dark (Monitoring2)
|
||||
case 2:
|
||||
//begin Dark for Ten Nines
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0; //we will apply the 24 bit Dark
|
||||
//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 L
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddL = (NSOddL * 0.9999999999) + prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) - prevShapeL;
|
||||
correction = NSOddL;
|
||||
} else {
|
||||
NSOddL = (NSOddL * 0.9999999999) - prevShapeL;
|
||||
NSEvenL = (NSEvenL * 0.9999999999) + prevShapeL;
|
||||
correction = NSEvenL;
|
||||
}
|
||||
shapedSampleL = inputSampleL+correction;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin Dark L
|
||||
quantA = floor(shapedSampleL);
|
||||
quantB = floor(shapedSampleL+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleL[x+1] - darkSampleL[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleL[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleL[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleL[x+1] = darkSampleL[x];
|
||||
}
|
||||
darkSampleL[0] = inputSampleL;
|
||||
//end Dark L
|
||||
|
||||
prevShapeL = (floor(shapedSampleL) - inputSampleL)*0.9999999999;
|
||||
//end Ten Nines L
|
||||
|
||||
//begin R
|
||||
correction = 0;
|
||||
if (flip) {
|
||||
NSOddR = (NSOddR * 0.9999999999) + prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) - prevShapeR;
|
||||
correction = NSOddR;
|
||||
} else {
|
||||
NSOddR = (NSOddR * 0.9999999999) - prevShapeR;
|
||||
NSEvenR = (NSEvenR * 0.9999999999) + prevShapeR;
|
||||
correction = NSEvenR;
|
||||
}
|
||||
shapedSampleR = inputSampleR+correction;
|
||||
//end Ten Nines R
|
||||
|
||||
//begin Dark R
|
||||
quantA = floor(shapedSampleR);
|
||||
quantB = floor(shapedSampleR+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
|
||||
|
||||
expectedSlew = 0;
|
||||
for(int x = 0; x < depth; x++) {
|
||||
expectedSlew += (darkSampleR[x+1] - darkSampleR[x]);
|
||||
}
|
||||
expectedSlew /= depth; //we have an average of all recent slews
|
||||
//we are doing that to voice the thing down into the upper mids a bit
|
||||
//it mustn't just soften the brightest treble, it must smooth high mids too
|
||||
|
||||
testA = fabs((darkSampleR[0] - quantA) - expectedSlew);
|
||||
testB = fabs((darkSampleR[0] - quantB) - expectedSlew);
|
||||
|
||||
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--) {
|
||||
darkSampleR[x+1] = darkSampleR[x];
|
||||
}
|
||||
darkSampleR[0] = inputSampleR;
|
||||
//end Dark R
|
||||
|
||||
prevShapeR = (floor(shapedSampleR) - inputSampleR)*0.9999999999;
|
||||
//end Ten Nines
|
||||
flip = !flip;
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //Ten Nines (which goes into Dark in Monitoring3)
|
||||
case 3:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherR = -1.0;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
ditherR += (double(fpdR)/UINT32_MAX);
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
ditherL = -1.0;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
ditherL += (double(fpdL)/UINT32_MAX);
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //TPDFWide (a good neutral with the width enhancement)
|
||||
case 4:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
//Paul Frindle: It's true that the dither itself can sound different
|
||||
//if it's given a different freq response and you get to hear it.
|
||||
//The one we use most is triangular single pole high pass dither.
|
||||
//It's not freq bent enough to sound odd, but is slightly less audible than
|
||||
//flat dither. It can also be easily made by taking one sample of dither
|
||||
//away from the previous one - this gives you the triangular PDF and the
|
||||
//filtering in one go :-)
|
||||
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
//TPDF: two 0-1 random noises
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
currentDither = (double(fpdR)/UINT32_MAX);
|
||||
ditherR = currentDither;
|
||||
ditherR -= previousDitherR;
|
||||
previousDitherR = currentDither;
|
||||
}
|
||||
|
||||
if (fabs(ditherL-ditherR) < 0.5) {
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
currentDither = (double(fpdL)/UINT32_MAX);
|
||||
ditherL = currentDither;
|
||||
ditherL -= previousDitherL;
|
||||
previousDitherL = currentDither;
|
||||
}
|
||||
|
||||
inputSampleL = floor(inputSampleL+ditherL);
|
||||
inputSampleR = floor(inputSampleR+ditherR);
|
||||
|
||||
inputSampleL /= 8388608.0;
|
||||
inputSampleR /= 8388608.0;
|
||||
break; //PaulWide (brighter neutral that's still TPDF and wide)
|
||||
case 5:
|
||||
inputSampleL *= 8388608.0;
|
||||
inputSampleR *= 8388608.0;
|
||||
cutbinsL = false;
|
||||
cutbinsR = false;
|
||||
drySampleL = inputSampleL;//re-using in NJAD
|
||||
inputSampleL -= noiseShapingL;
|
||||
//NJAD L
|
||||
benfordize = floor(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleL);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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);
|
||||
inputSampleL /= 8388608.0;
|
||||
if (inputSampleL > 1.0) inputSampleL = 1.0;
|
||||
if (inputSampleL < -1.0) inputSampleL = -1.0;
|
||||
//finished NJAD L
|
||||
|
||||
//NJAD R
|
||||
drySampleR = inputSampleR;
|
||||
inputSampleR -= noiseShapingR;
|
||||
benfordize = floor(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinA > 0) && (hotbinA < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
benfordize = ceil(inputSampleR);
|
||||
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.0;
|
||||
if ((hotbinB > 0) && (hotbinB < 10))
|
||||
{
|
||||
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;
|
||||
//produce total number- smaller is closer to Benford real
|
||||
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
|
||||
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);
|
||||
inputSampleR /= 8388608.0;
|
||||
if (inputSampleR > 1.0) inputSampleR = 1.0;
|
||||
if (inputSampleR < -1.0) inputSampleR = -1.0;
|
||||
break; //NJAD (Monitoring. Brightest)
|
||||
case 6:
|
||||
//begin 64 bit stereo floating point dither
|
||||
frexp((double)inputSampleL, &expon);
|
||||
fpdL ^= fpdL << 13; fpdL ^= fpdL >> 17; fpdL ^= fpdL << 5;
|
||||
inputSampleL += ((double(fpdL)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
frexp((double)inputSampleR, &expon);
|
||||
fpdR ^= fpdR << 13; fpdR ^= fpdR >> 17; fpdR ^= fpdR << 5;
|
||||
inputSampleR += ((double(fpdR)-uint32_t(0x7fffffff)) * 1.1e-44l * pow(2,expon+62));
|
||||
//end 64 bit stereo floating point dither
|
||||
break; //Bypass for saving floating point files directly
|
||||
}
|
||||
|
||||
*out1 = inputSampleL;
|
||||
*out2 = inputSampleR;
|
||||
|
|
|
|||
3
what.txt
3
what.txt
|
|
@ -331,7 +331,8 @@ SpatializeDither is a high-performance clarity and accuracy dither.[coll=]
|
|||
Spiral is the new best smoothest distortion algorithm.[coll=]
|
||||
Spiral2 is Spiral with controls including Presence.[coll=Latest]
|
||||
Srsly is a psychoacoustic stereo processor.[coll=Recommended]
|
||||
Srsly2 is a revisit of Srsly, to make the stereo widening more extreme.[coll=Basic,Recommended,Latest]
|
||||
Srsly2 is a revisit of Srsly, to make the stereo widening more extreme.[coll=]
|
||||
Srsly3 is Srsly2, with a Nonlin control to analogify the filters.[coll=Basic,Recommended,Latest]
|
||||
StarChild is a weird digital ambience/echo plugin.[coll=]
|
||||
StarChild2 is a weird digital ambience/echo plugin adapted to high sample rates.[coll=Latest]
|
||||
StereoChorus is a nice basic stereo chorus.[coll=Latest]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue