This commit is contained in:
Christopher Johnson 2024-11-03 16:32:16 -05:00
parent 04874c800b
commit 59635ea5d9
43 changed files with 6200 additions and 1319 deletions

View file

@ -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>

View file

@ -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;
}

View file

@ -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;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -3,7 +3,7 @@
*
* Version: 1.0
*
* Created: 10/8/24
* Created: 10/21/24
*
* Copyright: Copyright © 2024 Airwindows, Airwindows uses the MIT license
*

View file

@ -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>&lt;No Editor&gt;</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>

View file

@ -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;
};

View file

@ -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>

View file

@ -3,7 +3,7 @@
*
* Version: 1.0
*
* Created: 10/8/24
* Created: 10/21/24
*
* Copyright: Copyright © 2024 Airwindows, Airwindows uses the MIT license
*

View file

@ -0,0 +1,5 @@
//
// Prefix header for all source files of the '«PROJECTNAMEASIDENTIFIER»' target in the '«PROJECTNAMEASIDENTIFIER»' project.
//
#include <CoreServices/CoreServices.h>