aboutsummaryrefslogblamecommitdiffstats
path: root/plugins/WinVST/AQuickVoiceClip/AQuickVoiceClipProc.cpp
blob: cc282b6dd8bec5a8352d98da4e528925d963fcda (plain) (tree)










































                                                                                               













































































































































































































































































































































































                                                                                                                                                                                                                                 







                                                                                               

























































                                                                                                                   













































































































































































































































































































































































                                                                                                                                                                                                                                 









                                                                                               






















                                                                                                                   
/* ========================================
 *  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++;
    }
}