/* ======================================== * AQuickVoiceClip - AQuickVoiceClip.h * Copyright (c) 2016 airwindows, All rights reserved * ======================================== */ #ifndef __AQuickVoiceClip_H #include "AQuickVoiceClip.h" #endif void AQuickVoiceClip::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) { float* in1 = inputs[0]; float* in2 = inputs[1]; float* out1 = outputs[0]; float* out2 = outputs[1]; double overallscale = 1.0; overallscale /= 44100.0; overallscale *= getSampleRate(); double softness = 0.484416; double hardness = 1.0 - softness; double iirAmount = ((pow(A,3)*2070)+30)/8000.0; iirAmount /= overallscale; double altAmount = (1.0 - iirAmount); double cancelnew = 0.0682276; double cancelold = 1.0 - cancelnew; double lpSpeed = 0.0009; double cliplevel = 0.98; double refclip = 0.5; //preset to cut out gain quite a lot. 91%? no touchy unless clip double LmaxRecent; bool LclipOnset; double LpassThrough; double LoutputSample; double LdrySample; double RmaxRecent; bool RclipOnset; double RpassThrough; double RoutputSample; double RdrySample; long double inputSampleL; long double inputSampleR; while (--sampleFrames >= 0) { inputSampleL = *in1; inputSampleR = *in2; if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { static int noisesource = 0; //this declares a variable before anything else is compiled. It won't keep assigning //it to 0 for every sample, it's as if the declaration doesn't exist in this context, //but it lets me add this denormalization fix in a single place rather than updating //it in three different locations. The variable isn't thread-safe but this is only //a random seed and we can share it with whatever. noisesource = noisesource % 1700021; noisesource++; int residue = noisesource * noisesource; residue = residue % 170003; residue *= residue; residue = residue % 17011; residue *= residue; residue = residue % 1709; residue *= residue; residue = residue % 173; residue *= residue; residue = residue % 17; double applyresidue = residue; applyresidue *= 0.00000001; applyresidue *= 0.00000001; inputSampleL = applyresidue; } if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { static int noisesource = 0; noisesource = noisesource % 1700021; noisesource++; int residue = noisesource * noisesource; residue = residue % 170003; residue *= residue; residue = residue % 17011; residue *= residue; residue = residue % 1709; residue *= residue; residue = residue % 173; residue *= residue; residue = residue % 17; double applyresidue = residue; applyresidue *= 0.00000001; applyresidue *= 0.00000001; inputSampleR = applyresidue; //this denormalization routine produces a white noise at -300 dB which the noise //shaping will interact with to produce a bipolar output, but the noise is actually //all positive. That should stop any variables from going denormal, and the routine //only kicks in if digital black is input. As a final touch, if you save to 24-bit //the silence will return to being digital black again. } LpassThrough = LataDrySample = inputSampleL; RpassThrough = RataDrySample = inputSampleR; LataHalfDrySample = LataHalfwaySample = (inputSampleL + LataLast1Sample + (LataLast2Sample*ataK1) + (LataLast3Sample*ataK2) + (LataLast4Sample*ataK6) + (LataLast5Sample*ataK7) + (LataLast6Sample*ataK8)) / 2.0; LataLast6Sample = LataLast5Sample; LataLast5Sample = LataLast4Sample; LataLast4Sample = LataLast3Sample; LataLast3Sample = LataLast2Sample; LataLast2Sample = LataLast1Sample; LataLast1Sample = inputSampleL; //setting up oversampled special antialiasing RataHalfDrySample = RataHalfwaySample = (inputSampleR + RataLast1Sample + (RataLast2Sample*ataK1) + (RataLast3Sample*ataK2) + (RataLast4Sample*ataK6) + (RataLast5Sample*ataK7) + (RataLast6Sample*ataK8)) / 2.0; RataLast6Sample = RataLast5Sample; RataLast5Sample = RataLast4Sample; RataLast4Sample = RataLast3Sample; RataLast3Sample = RataLast2Sample; RataLast2Sample = RataLast1Sample; RataLast1Sample = inputSampleR; //setting up oversampled special antialiasing LclipOnset = false; RclipOnset = false; LmaxRecent = fabs( LataLast6Sample ); if (fabs( LataLast5Sample ) > LmaxRecent ) LmaxRecent = fabs( LataLast5Sample ); if (fabs( LataLast4Sample ) > LmaxRecent ) LmaxRecent = fabs( LataLast4Sample ); if (fabs( LataLast3Sample ) > LmaxRecent ) LmaxRecent = fabs( LataLast3Sample ); if (fabs( LataLast2Sample ) > LmaxRecent ) LmaxRecent = fabs( LataLast2Sample ); if (fabs( LataLast1Sample ) > LmaxRecent ) LmaxRecent = fabs( LataLast1Sample ); if (fabs( inputSampleL ) > LmaxRecent ) LmaxRecent = fabs( inputSampleL ); //this gives us something that won't cut out in zero crossings, to interpolate with RmaxRecent = fabs( RataLast6Sample ); if (fabs( RataLast5Sample ) > RmaxRecent ) RmaxRecent = fabs( RataLast5Sample ); if (fabs( RataLast4Sample ) > RmaxRecent ) RmaxRecent = fabs( RataLast4Sample ); if (fabs( RataLast3Sample ) > RmaxRecent ) RmaxRecent = fabs( RataLast3Sample ); if (fabs( RataLast2Sample ) > RmaxRecent ) RmaxRecent = fabs( RataLast2Sample ); if (fabs( RataLast1Sample ) > RmaxRecent ) RmaxRecent = fabs( RataLast1Sample ); if (fabs( inputSampleR ) > RmaxRecent ) RmaxRecent = fabs( inputSampleR ); //this gives us something that won't cut out in zero crossings, to interpolate with LmaxRecent *= 2.0; RmaxRecent *= 2.0; //by refclip this is 1.0 and fully into the antialiasing if (LmaxRecent > 1.0) LmaxRecent = 1.0; if (RmaxRecent > 1.0) RmaxRecent = 1.0; //and it tops out at 1. Higher means more antialiasing, lower blends into passThrough without antialiasing LataHalfwaySample -= Loverall; RataHalfwaySample -= Roverall; //subtract dist-cancel from input after getting raw input, before doing anything LdrySample = LataHalfwaySample; RdrySample = RataHalfwaySample; //begin L channel for the clipper if (LlastSample >= refclip) { LlpDepth += 0.1; if (LataHalfwaySample < refclip) { LlastSample = ((refclip*hardness) + (LataHalfwaySample * softness)); } else LlastSample = refclip; } if (LlastSample <= -refclip) { LlpDepth += 0.1; if (LataHalfwaySample > -refclip) { LlastSample = ((-refclip*hardness) + (LataHalfwaySample * softness)); } else LlastSample = -refclip; } if (LataHalfwaySample > refclip) { LlpDepth += 0.1; if (LlastSample < refclip) { LataHalfwaySample = ((refclip*hardness) + (LlastSample * softness)); } else LataHalfwaySample = refclip; } if (LataHalfwaySample < -refclip) { LlpDepth += 0.1; if (LlastSample > -refclip) { LataHalfwaySample = ((-refclip*hardness) + (LlastSample * softness)); } else LataHalfwaySample = -refclip; } ///end L channel for the clipper //begin R channel for the clipper if (RlastSample >= refclip) { RlpDepth += 0.1; if (RataHalfwaySample < refclip) { RlastSample = ((refclip*hardness) + (RataHalfwaySample * softness)); } else RlastSample = refclip; } if (RlastSample <= -refclip) { RlpDepth += 0.1; if (RataHalfwaySample > -refclip) { RlastSample = ((-refclip*hardness) + (RataHalfwaySample * softness)); } else RlastSample = -refclip; } if (RataHalfwaySample > refclip) { RlpDepth += 0.1; if (RlastSample < refclip) { RataHalfwaySample = ((refclip*hardness) + (RlastSample * softness)); } else RataHalfwaySample = refclip; } if (RataHalfwaySample < -refclip) { RlpDepth += 0.1; if (RlastSample > -refclip) { RataHalfwaySample = ((-refclip*hardness) + (RlastSample * softness)); } else RataHalfwaySample = -refclip; } ///end R channel for the clipper LoutputSample = LlastSample; RoutputSample = RlastSample; LlastSample = LataHalfwaySample; RlastSample = RataHalfwaySample; LataHalfwaySample = LoutputSample; RataHalfwaySample = RoutputSample; //swap around in a circle for one final ADClip, //this time not tracking overshoot anymore //end interpolated sample //begin raw sample- inputSample and ataDrySample handled separately here inputSampleL -= Loverall; inputSampleR -= Roverall; //subtract dist-cancel from input after getting raw input, before doing anything LdrySample = inputSampleL; RdrySample = inputSampleR; //begin second L clip if (LlastSample >= refclip) { LlpDepth += 0.1; if (inputSampleL < refclip) { LlastSample = ((refclip*hardness) + (inputSampleL * softness)); } else LlastSample = refclip; } if (LlastSample <= -refclip) { LlpDepth += 0.1; if (inputSampleL > -refclip) { LlastSample = ((-refclip*hardness) + (inputSampleL * softness)); } else LlastSample = -refclip; } if (inputSampleL > refclip) { LlpDepth += 0.1; if (LlastSample < refclip) { inputSampleL = ((refclip*hardness) + (LlastSample * softness)); } else inputSampleL = refclip; } if (inputSampleL < -refclip) { LlpDepth += 0.1; if (LlastSample > -refclip) { inputSampleL = ((-refclip*hardness) + (LlastSample * softness)); } else inputSampleL = -refclip; } //end second L clip //begin second R clip if (RlastSample >= refclip) { RlpDepth += 0.1; if (inputSampleR < refclip) { RlastSample = ((refclip*hardness) + (inputSampleR * softness)); } else RlastSample = refclip; } if (RlastSample <= -refclip) { RlpDepth += 0.1; if (inputSampleR > -refclip) { RlastSample = ((-refclip*hardness) + (inputSampleR * softness)); } else RlastSample = -refclip; } if (inputSampleR > refclip) { RlpDepth += 0.1; if (RlastSample < refclip) { inputSampleR = ((refclip*hardness) + (RlastSample * softness)); } else inputSampleR = refclip; } if (inputSampleR < -refclip) { RlpDepth += 0.1; if (RlastSample > -refclip) { inputSampleR = ((-refclip*hardness) + (RlastSample * softness)); } else inputSampleR = -refclip; } //end second R clip LoutputSample = LlastSample; RoutputSample = RlastSample; LlastSample = inputSampleL; RlastSample = inputSampleR; inputSampleL = LoutputSample; inputSampleR = RoutputSample; LataHalfDrySample = (LataDrySample*ataK3)+(LataHalfDrySample*ataK4); LataHalfDiffSample = (LataHalfwaySample - LataHalfDrySample)/2.0; LataLastDiffSample = LataDiffSample*ataK5; LataDiffSample = (inputSampleL - LataDrySample)/2.0; LataDiffSample += LataHalfDiffSample; LataDiffSample -= LataLastDiffSample; inputSampleL = LataDrySample; inputSampleL += LataDiffSample; RataHalfDrySample = (RataDrySample*ataK3)+(RataHalfDrySample*ataK4); RataHalfDiffSample = (RataHalfwaySample - RataHalfDrySample)/2.0; RataLastDiffSample = RataDiffSample*ataK5; RataDiffSample = (inputSampleR - RataDrySample)/2.0; RataDiffSample += RataHalfDiffSample; RataDiffSample -= RataLastDiffSample; inputSampleR = RataDrySample; inputSampleR += RataDiffSample; Loverall = (Loverall * cancelold) + (LataDiffSample * cancelnew); Roverall = (Roverall * cancelold) + (RataDiffSample * cancelnew); //apply all the diffs to a lowpassed IIR if (flip) { LiirSampleA = (LiirSampleA * altAmount) + (inputSampleL * iirAmount); inputSampleL -= LiirSampleA; LiirSampleC = (LiirSampleC * altAmount) + (LpassThrough * iirAmount); LpassThrough -= LiirSampleC; RiirSampleA = (RiirSampleA * altAmount) + (inputSampleR * iirAmount); inputSampleR -= RiirSampleA; RiirSampleC = (RiirSampleC * altAmount) + (RpassThrough * iirAmount); RpassThrough -= RiirSampleC; } else { LiirSampleB = (LiirSampleB * altAmount) + (inputSampleL * iirAmount); inputSampleL -= LiirSampleB; LiirSampleD = (LiirSampleD * altAmount) + (LpassThrough * iirAmount); LpassThrough -= LiirSampleD; RiirSampleB = (RiirSampleB * altAmount) + (inputSampleR * iirAmount); inputSampleR -= RiirSampleB; RiirSampleD = (RiirSampleD * altAmount) + (RpassThrough * iirAmount); RpassThrough -= RiirSampleD; } flip = !flip; //highpass section LlastOut3Sample = LlastOut2Sample; LlastOut2Sample = LlastOutSample; LlastOutSample = inputSampleL; RlastOut3Sample = RlastOut2Sample; RlastOut2Sample = RlastOutSample; RlastOutSample = inputSampleR; LlpDepth -= lpSpeed; RlpDepth -= lpSpeed; if (LlpDepth > 0.0) { if (LlpDepth > 1.0) LlpDepth = 1.0; inputSampleL *= (1.0-LlpDepth); inputSampleL += (((LlastOutSample + LlastOut2Sample + LlastOut3Sample) / 3.6)*LlpDepth); } if (RlpDepth > 0.0) { if (RlpDepth > 1.0) RlpDepth = 1.0; inputSampleR *= (1.0-RlpDepth); inputSampleR += (((RlastOutSample + RlastOut2Sample + RlastOut3Sample) / 3.6)*RlpDepth); } if (LlpDepth < 0.0) LlpDepth = 0.0; if (RlpDepth < 0.0) RlpDepth = 0.0; //stereo 32 bit dither, made small and tidy. int expon; frexpf((float)inputSampleL, &expon); long double dither = (rand()/(RAND_MAX*7.737125245533627e+25))*pow(2,expon+62); inputSampleL += (dither-fpNShapeL); fpNShapeL = dither; frexpf((float)inputSampleR, &expon); dither = (rand()/(RAND_MAX*7.737125245533627e+25))*pow(2,expon+62); inputSampleR += (dither-fpNShapeR); fpNShapeR = dither; //end 32 bit dither inputSampleL *= (1.0-LmaxRecent); inputSampleR *= (1.0-RmaxRecent); inputSampleL += (LpassThrough * LmaxRecent); inputSampleR += (RpassThrough * RmaxRecent); //there's our raw signal, without antialiasing. Brings up low level stuff and softens more when hot if (inputSampleL > cliplevel) inputSampleL = cliplevel; if (inputSampleL < -cliplevel) inputSampleL = -cliplevel; if (inputSampleR > cliplevel) inputSampleR = cliplevel; if (inputSampleR < -cliplevel) inputSampleR = -cliplevel; //final iron bar *out1 = inputSampleL; *out2 = inputSampleR; *in1++; *in2++; *out1++; *out2++; } } void AQuickVoiceClip::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) { double* in1 = inputs[0]; double* in2 = inputs[1]; double* out1 = outputs[0]; double* out2 = outputs[1]; double overallscale = 1.0; overallscale /= 44100.0; overallscale *= getSampleRate(); double softness = 0.484416; double hardness = 1.0 - softness; double iirAmount = ((pow(A,3)*2070)+30)/8000.0; iirAmount /= overallscale; double altAmount = (1.0 - iirAmount); double cancelnew = 0.0682276; double cancelold = 1.0 - cancelnew; double lpSpeed = 0.0009; double cliplevel = 0.98; double refclip = 0.5; //preset to cut out gain quite a lot. 91%? no touchy unless clip double LmaxRecent; bool LclipOnset; double LpassThrough; double LoutputSample; double LdrySample; double RmaxRecent; bool RclipOnset; double RpassThrough; double RoutputSample; double RdrySample; long double inputSampleL; long double inputSampleR; while (--sampleFrames >= 0) { inputSampleL = *in1; inputSampleR = *in2; if (inputSampleL<1.2e-38 && -inputSampleL<1.2e-38) { static int noisesource = 0; //this declares a variable before anything else is compiled. It won't keep assigning //it to 0 for every sample, it's as if the declaration doesn't exist in this context, //but it lets me add this denormalization fix in a single place rather than updating //it in three different locations. The variable isn't thread-safe but this is only //a random seed and we can share it with whatever. noisesource = noisesource % 1700021; noisesource++; int residue = noisesource * noisesource; residue = residue % 170003; residue *= residue; residue = residue % 17011; residue *= residue; residue = residue % 1709; residue *= residue; residue = residue % 173; residue *= residue; residue = residue % 17; double applyresidue = residue; applyresidue *= 0.00000001; applyresidue *= 0.00000001; inputSampleL = applyresidue; } if (inputSampleR<1.2e-38 && -inputSampleR<1.2e-38) { static int noisesource = 0; noisesource = noisesource % 1700021; noisesource++; int residue = noisesource * noisesource; residue = residue % 170003; residue *= residue; residue = residue % 17011; residue *= residue; residue = residue % 1709; residue *= residue; residue = residue % 173; residue *= residue; residue = residue % 17; double applyresidue = residue; applyresidue *= 0.00000001; applyresidue *= 0.00000001; inputSampleR = applyresidue; //this denormalization routine produces a white noise at -300 dB which the noise //shaping will interact with to produce a bipolar output, but the noise is actually //all positive. That should stop any variables from going denormal, and the routine //only kicks in if digital black is input. As a final touch, if you save to 24-bit //the silence will return to being digital black again. } LpassThrough = LataDrySample = inputSampleL; RpassThrough = RataDrySample = inputSampleR; LataHalfDrySample = LataHalfwaySample = (inputSampleL + LataLast1Sample + (LataLast2Sample*ataK1) + (LataLast3Sample*ataK2) + (LataLast4Sample*ataK6) + (LataLast5Sample*ataK7) + (LataLast6Sample*ataK8)) / 2.0; LataLast6Sample = LataLast5Sample; LataLast5Sample = LataLast4Sample; LataLast4Sample = LataLast3Sample; LataLast3Sample = LataLast2Sample; LataLast2Sample = LataLast1Sample; LataLast1Sample = inputSampleL; //setting up oversampled special antialiasing RataHalfDrySample = RataHalfwaySample = (inputSampleR + RataLast1Sample + (RataLast2Sample*ataK1) + (RataLast3Sample*ataK2) + (RataLast4Sample*ataK6) + (RataLast5Sample*ataK7) + (RataLast6Sample*ataK8)) / 2.0; RataLast6Sample = RataLast5Sample; RataLast5Sample = RataLast4Sample; RataLast4Sample = RataLast3Sample; RataLast3Sample = RataLast2Sample; RataLast2Sample = RataLast1Sample; RataLast1Sample = inputSampleR; //setting up oversampled special antialiasing LclipOnset = false; RclipOnset = false; LmaxRecent = fabs( LataLast6Sample ); if (fabs( LataLast5Sample ) > LmaxRecent ) LmaxRecent = fabs( LataLast5Sample ); if (fabs( LataLast4Sample ) > LmaxRecent ) LmaxRecent = fabs( LataLast4Sample ); if (fabs( LataLast3Sample ) > LmaxRecent ) LmaxRecent = fabs( LataLast3Sample ); if (fabs( LataLast2Sample ) > LmaxRecent ) LmaxRecent = fabs( LataLast2Sample ); if (fabs( LataLast1Sample ) > LmaxRecent ) LmaxRecent = fabs( LataLast1Sample ); if (fabs( inputSampleL ) > LmaxRecent ) LmaxRecent = fabs( inputSampleL ); //this gives us something that won't cut out in zero crossings, to interpolate with RmaxRecent = fabs( RataLast6Sample ); if (fabs( RataLast5Sample ) > RmaxRecent ) RmaxRecent = fabs( RataLast5Sample ); if (fabs( RataLast4Sample ) > RmaxRecent ) RmaxRecent = fabs( RataLast4Sample ); if (fabs( RataLast3Sample ) > RmaxRecent ) RmaxRecent = fabs( RataLast3Sample ); if (fabs( RataLast2Sample ) > RmaxRecent ) RmaxRecent = fabs( RataLast2Sample ); if (fabs( RataLast1Sample ) > RmaxRecent ) RmaxRecent = fabs( RataLast1Sample ); if (fabs( inputSampleR ) > RmaxRecent ) RmaxRecent = fabs( inputSampleR ); //this gives us something that won't cut out in zero crossings, to interpolate with LmaxRecent *= 2.0; RmaxRecent *= 2.0; //by refclip this is 1.0 and fully into the antialiasing if (LmaxRecent > 1.0) LmaxRecent = 1.0; if (RmaxRecent > 1.0) RmaxRecent = 1.0; //and it tops out at 1. Higher means more antialiasing, lower blends into passThrough without antialiasing LataHalfwaySample -= Loverall; RataHalfwaySample -= Roverall; //subtract dist-cancel from input after getting raw input, before doing anything LdrySample = LataHalfwaySample; RdrySample = RataHalfwaySample; //begin L channel for the clipper if (LlastSample >= refclip) { LlpDepth += 0.1; if (LataHalfwaySample < refclip) { LlastSample = ((refclip*hardness) + (LataHalfwaySample * softness)); } else LlastSample = refclip; } if (LlastSample <= -refclip) { LlpDepth += 0.1; if (LataHalfwaySample > -refclip) { LlastSample = ((-refclip*hardness) + (LataHalfwaySample * softness)); } else LlastSample = -refclip; } if (LataHalfwaySample > refclip) { LlpDepth += 0.1; if (LlastSample < refclip) { LataHalfwaySample = ((refclip*hardness) + (LlastSample * softness)); } else LataHalfwaySample = refclip; } if (LataHalfwaySample < -refclip) { LlpDepth += 0.1; if (LlastSample > -refclip) { LataHalfwaySample = ((-refclip*hardness) + (LlastSample * softness)); } else LataHalfwaySample = -refclip; } ///end L channel for the clipper //begin R channel for the clipper if (RlastSample >= refclip) { RlpDepth += 0.1; if (RataHalfwaySample < refclip) { RlastSample = ((refclip*hardness) + (RataHalfwaySample * softness)); } else RlastSample = refclip; } if (RlastSample <= -refclip) { RlpDepth += 0.1; if (RataHalfwaySample > -refclip) { RlastSample = ((-refclip*hardness) + (RataHalfwaySample * softness)); } else RlastSample = -refclip; } if (RataHalfwaySample > refclip) { RlpDepth += 0.1; if (RlastSample < refclip) { RataHalfwaySample = ((refclip*hardness) + (RlastSample * softness)); } else RataHalfwaySample = refclip; } if (RataHalfwaySample < -refclip) { RlpDepth += 0.1; if (RlastSample > -refclip) { RataHalfwaySample = ((-refclip*hardness) + (RlastSample * softness)); } else RataHalfwaySample = -refclip; } ///end R channel for the clipper LoutputSample = LlastSample; RoutputSample = RlastSample; LlastSample = LataHalfwaySample; RlastSample = RataHalfwaySample; LataHalfwaySample = LoutputSample; RataHalfwaySample = RoutputSample; //swap around in a circle for one final ADClip, //this time not tracking overshoot anymore //end interpolated sample //begin raw sample- inputSample and ataDrySample handled separately here inputSampleL -= Loverall; inputSampleR -= Roverall; //subtract dist-cancel from input after getting raw input, before doing anything LdrySample = inputSampleL; RdrySample = inputSampleR; //begin second L clip if (LlastSample >= refclip) { LlpDepth += 0.1; if (inputSampleL < refclip) { LlastSample = ((refclip*hardness) + (inputSampleL * softness)); } else LlastSample = refclip; } if (LlastSample <= -refclip) { LlpDepth += 0.1; if (inputSampleL > -refclip) { LlastSample = ((-refclip*hardness) + (inputSampleL * softness)); } else LlastSample = -refclip; } if (inputSampleL > refclip) { LlpDepth += 0.1; if (LlastSample < refclip) { inputSampleL = ((refclip*hardness) + (LlastSample * softness)); } else inputSampleL = refclip; } if (inputSampleL < -refclip) { LlpDepth += 0.1; if (LlastSample > -refclip) { inputSampleL = ((-refclip*hardness) + (LlastSample * softness)); } else inputSampleL = -refclip; } //end second L clip //begin second R clip if (RlastSample >= refclip) { RlpDepth += 0.1; if (inputSampleR < refclip) { RlastSample = ((refclip*hardness) + (inputSampleR * softness)); } else RlastSample = refclip; } if (RlastSample <= -refclip) { RlpDepth += 0.1; if (inputSampleR > -refclip) { RlastSample = ((-refclip*hardness) + (inputSampleR * softness)); } else RlastSample = -refclip; } if (inputSampleR > refclip) { RlpDepth += 0.1; if (RlastSample < refclip) { inputSampleR = ((refclip*hardness) + (RlastSample * softness)); } else inputSampleR = refclip; } if (inputSampleR < -refclip) { RlpDepth += 0.1; if (RlastSample > -refclip) { inputSampleR = ((-refclip*hardness) + (RlastSample * softness)); } else inputSampleR = -refclip; } //end second R clip LoutputSample = LlastSample; RoutputSample = RlastSample; LlastSample = inputSampleL; RlastSample = inputSampleR; inputSampleL = LoutputSample; inputSampleR = RoutputSample; LataHalfDrySample = (LataDrySample*ataK3)+(LataHalfDrySample*ataK4); LataHalfDiffSample = (LataHalfwaySample - LataHalfDrySample)/2.0; LataLastDiffSample = LataDiffSample*ataK5; LataDiffSample = (inputSampleL - LataDrySample)/2.0; LataDiffSample += LataHalfDiffSample; LataDiffSample -= LataLastDiffSample; inputSampleL = LataDrySample; inputSampleL += LataDiffSample; RataHalfDrySample = (RataDrySample*ataK3)+(RataHalfDrySample*ataK4); RataHalfDiffSample = (RataHalfwaySample - RataHalfDrySample)/2.0; RataLastDiffSample = RataDiffSample*ataK5; RataDiffSample = (inputSampleR - RataDrySample)/2.0; RataDiffSample += RataHalfDiffSample; RataDiffSample -= RataLastDiffSample; inputSampleR = RataDrySample; inputSampleR += RataDiffSample; Loverall = (Loverall * cancelold) + (LataDiffSample * cancelnew); Roverall = (Roverall * cancelold) + (RataDiffSample * cancelnew); //apply all the diffs to a lowpassed IIR if (flip) { LiirSampleA = (LiirSampleA * altAmount) + (inputSampleL * iirAmount); inputSampleL -= LiirSampleA; LiirSampleC = (LiirSampleC * altAmount) + (LpassThrough * iirAmount); LpassThrough -= LiirSampleC; RiirSampleA = (RiirSampleA * altAmount) + (inputSampleR * iirAmount); inputSampleR -= RiirSampleA; RiirSampleC = (RiirSampleC * altAmount) + (RpassThrough * iirAmount); RpassThrough -= RiirSampleC; } else { LiirSampleB = (LiirSampleB * altAmount) + (inputSampleL * iirAmount); inputSampleL -= LiirSampleB; LiirSampleD = (LiirSampleD * altAmount) + (LpassThrough * iirAmount); LpassThrough -= LiirSampleD; RiirSampleB = (RiirSampleB * altAmount) + (inputSampleR * iirAmount); inputSampleR -= RiirSampleB; RiirSampleD = (RiirSampleD * altAmount) + (RpassThrough * iirAmount); RpassThrough -= RiirSampleD; } flip = !flip; //highpass section LlastOut3Sample = LlastOut2Sample; LlastOut2Sample = LlastOutSample; LlastOutSample = inputSampleL; RlastOut3Sample = RlastOut2Sample; RlastOut2Sample = RlastOutSample; RlastOutSample = inputSampleR; LlpDepth -= lpSpeed; RlpDepth -= lpSpeed; if (LlpDepth > 0.0) { if (LlpDepth > 1.0) LlpDepth = 1.0; inputSampleL *= (1.0-LlpDepth); inputSampleL += (((LlastOutSample + LlastOut2Sample + LlastOut3Sample) / 3.6)*LlpDepth); } if (RlpDepth > 0.0) { if (RlpDepth > 1.0) RlpDepth = 1.0; inputSampleR *= (1.0-RlpDepth); inputSampleR += (((RlastOutSample + RlastOut2Sample + RlastOut3Sample) / 3.6)*RlpDepth); } if (LlpDepth < 0.0) LlpDepth = 0.0; if (RlpDepth < 0.0) RlpDepth = 0.0; //stereo 64 bit dither, made small and tidy. int expon; frexp((double)inputSampleL, &expon); long double dither = (rand()/(RAND_MAX*7.737125245533627e+25))*pow(2,expon+62); dither /= 536870912.0; //needs this to scale to 64 bit zone inputSampleL += (dither-fpNShapeL); fpNShapeL = dither; frexp((double)inputSampleR, &expon); dither = (rand()/(RAND_MAX*7.737125245533627e+25))*pow(2,expon+62); dither /= 536870912.0; //needs this to scale to 64 bit zone inputSampleR += (dither-fpNShapeR); fpNShapeR = dither; //end 64 bit dither inputSampleL *= (1.0-LmaxRecent); inputSampleR *= (1.0-RmaxRecent); inputSampleL += (LpassThrough * LmaxRecent); inputSampleR += (RpassThrough * RmaxRecent); //there's our raw signal, without antialiasing. Brings up low level stuff and softens more when hot if (inputSampleL > cliplevel) inputSampleL = cliplevel; if (inputSampleL < -cliplevel) inputSampleL = -cliplevel; if (inputSampleR > cliplevel) inputSampleR = cliplevel; if (inputSampleR < -cliplevel) inputSampleR = -cliplevel; //final iron bar *out1 = inputSampleL; *out2 = inputSampleR; *in1++; *in2++; *out1++; *out2++; } }