Exemple #1
0
inline int comb::process(int input)
{
	int output;

	output = buffer[bufidx];
	undenormalise(output);

	filterstore = FMUL(output, damp2) + FMUL(filterstore, damp1);
	undenormalise(filterstore);

	buffer[bufidx] = input + FMUL(filterstore, feedback);
	if(++bufidx>=bufsize) bufidx = 0;

	return output;
}
inline float comb::process(float input)
{
	float output;

	output = buffer[bufidx];
	undenormalise(output);

	filterstore = (output*damp2) + (filterstore*damp1);
	undenormalise(filterstore);

	buffer[bufidx] = input + (filterstore*feedback);

	if(++bufidx>=bufsize) bufidx = 0;

	return output;
}
Exemple #3
0
void Reverb::process(float *p_src,float *p_dst,int p_frames) {

	if (p_frames>INPUT_BUFFER_MAX_SIZE)
		p_frames=INPUT_BUFFER_MAX_SIZE;

	int predelay_frames=lrint((params.predelay/1000.0)*params.mix_rate);
	if (predelay_frames<10)
		predelay_frames=10;
	if (predelay_frames>=echo_buffer_size)
		predelay_frames=echo_buffer_size-1;

	for (int i=0;i<p_frames;i++) {

		if (echo_buffer_pos>=echo_buffer_size)
			echo_buffer_pos=0;

		int read_pos=echo_buffer_pos-predelay_frames;
		while (read_pos<0)
			read_pos+=echo_buffer_size;

		float in=undenormalise(echo_buffer[read_pos]*params.predelay_fb+p_src[i]);

		echo_buffer[echo_buffer_pos]=in;

		input_buffer[i]=in;

		p_dst[i]=0; //take the chance and clear this

		echo_buffer_pos++;
	}

	if (params.hpf>0) {
		float hpaux=expf(-2.0*Math_PI*params.hpf*6000/params.mix_rate);
		float hp_a1=(1.0+hpaux)/2.0;
		float hp_a2=-(1.0+hpaux)/2.0;
		float hp_b1=hpaux;

		for (int i=0;i<p_frames;i++) {

			float in=input_buffer[i];
			input_buffer[i]=in*hp_a1+hpf_h1*hp_a2+hpf_h2*hp_b1;
			hpf_h2=input_buffer[i];
			hpf_h1=in;
		}
	}

	for (int i=0;i<MAX_COMBS;i++) {

		Comb &c=comb[i];

		int size_limit=c.size-lrintf((float)c.extra_spread_frames*(1.0-params.extra_spread));
		for (int j=0;j<p_frames;j++) {

			if (c.pos>=size_limit) //reset this now just in case
				c.pos=0;

			float out=undenormalise(c.buffer[c.pos]*c.feedback);
			out=out*(1.0-c.damp)+c.damp_h*c.damp; //lowpass
			c.damp_h=out;
			c.buffer[c.pos]=input_buffer[j]+out;
			p_dst[j]+=out;
			c.pos++;
		}

	}


	static const float allpass_feedback=0.7;
	/* this one works, but the other version is just nicer....
	int ap_size_limit[MAX_ALLPASS];

	for (int i=0;i<MAX_ALLPASS;i++) {

		AllPass &a=allpass[i];
		ap_size_limit[i]=a.size-lrintf((float)a.extra_spread_frames*(1.0-params.extra_spread));
	}

	for (int i=0;i<p_frames;i++) {

		float sample=p_dst[i];
		float aux,in;
		float AllPass*ap;

#define PROCESS_ALLPASS(m_ap) 	\
	ap=&allpass[m_ap];	\
	if (ap->pos>=ap_size_limit[m_ap])	\
		ap->pos=0;	\
	aux=undenormalise(ap->buffer[ap->pos]);	\
	in=sample;	\
	sample=-in+aux;	\
	ap->pos++;


		PROCESS_ALLPASS(0);
		PROCESS_ALLPASS(1);
		PROCESS_ALLPASS(2);
		PROCESS_ALLPASS(3);

		p_dst[i]=sample;
	}
	*/

	for (int i=0;i<MAX_ALLPASS;i++) {

		AllPass &a=allpass[i];
		int size_limit=a.size-lrintf((float)a.extra_spread_frames*(1.0-params.extra_spread));

		for (int j=0;j<p_frames;j++) {

			if (a.pos>=size_limit)
				a.pos=0;

			float aux=a.buffer[a.pos];
			a.buffer[a.pos]=undenormalise(allpass_feedback*aux+p_dst[j]);
			p_dst[j]=aux-allpass_feedback*a.buffer[a.pos];
			a.pos++;

		}
	}

	static const float wet_scale=0.6;

	for (int i=0;i<p_frames;i++) {


		p_dst[i]=p_dst[i]*params.wet*wet_scale+p_src[i]*params.dry;
	}

}
void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {

	const float *src = (const float *)p_src_frames;
	float *dst = (float *)p_dst_frames;

	//float lpf_c=expf(-2.0*Math_PI*keep_hf_hz.get()/(mix_rate*(float)OVERSAMPLE));
	float lpf_c = expf(-2.0 * Math_PI * base->keep_hf_hz / (AudioServer::get_singleton()->get_mix_rate()));
	float lpf_ic = 1.0 - lpf_c;

	float drive_f = base->drive;
	float pregain_f = Math::db2linear(base->pre_gain);
	float postgain_f = Math::db2linear(base->post_gain);

	float atan_mult = pow(10, drive_f * drive_f * 3.0) - 1.0 + 0.001;
	float atan_div = 1.0 / (atanf(atan_mult) * (1.0 + drive_f * 8));

	float lofi_mult = powf(2.0, 2.0 + (1.0 - drive_f) * 14); //goes from 16 to 2 bits

	for (int i = 0; i < p_frame_count * 2; i++) {

		float out = undenormalise(src[i] * lpf_ic + lpf_c * h[i & 1]);
		h[i & 1] = out;
		float a = out;
		float ha = src[i] - out; //high freqs
		a *= pregain_f;

		switch (base->mode) {

			case AudioEffectDistortion::MODE_CLIP: {

				a = powf(a, 1.0001 - drive_f);
				if (a > 1.0)
					a = 1.0;
				else if (a < (-1.0))
					a = -1.0;

			} break;
			case AudioEffectDistortion::MODE_ATAN: {

				a = atanf(a * atan_mult) * atan_div;

			} break;
			case AudioEffectDistortion::MODE_LOFI: {

				a = floorf(a * lofi_mult + 0.5) / lofi_mult;

			} break;
			case AudioEffectDistortion::MODE_OVERDRIVE: {

				const double x = a * 0.686306;
				const double z = 1 + exp(sqrt(fabs(x)) * -0.75);
				a = (expf(x) - expf(-x * z)) / (expf(x) + expf(-x));
			} break;
			case AudioEffectDistortion::MODE_WAVESHAPE: {
				float x = a;
				float k = 2 * drive_f / (1.00001 - drive_f);

				a = (1.0 + k) * x / (1.0 + k * fabsf(x));

			} break;
		}

		dst[i] = a * postgain_f + ha;
	}
}
void Filter::prepare_coefficients(Coeffs *p_coeffs) {

	
	double final_cutoff=(cutoff>=(sampling_rate/2))?(sampling_rate/2-1):cutoff;
	if (final_cutoff<20) //avoid crapness
		final_cutoff=20; //i dont allow less than this
	
	
		
	double omega=2.0*M_PI*final_cutoff/sampling_rate;
	
	double sin_v=sin(omega);
	double cos_v=cos(omega);
	
	float Q=resonance;
	if (Q<=0.0) { 
		Q=0.0001;
	}
	

	if (mode==BANDPASS) 
		Q*=2.0;
	
	if (stages>1) {
		
		Q=(Q>1.0 ? pow(Q,1.0/stages) : Q);
		
	}
	double alpha = sin_v/(2*Q);
	
	double a0 = 1.0 + alpha;
	
	switch (mode) {


		case LOWPASS: {	    
	
			p_coeffs->b0=  (1.0 - cos_v)/2.0 ;
			p_coeffs->b1=   1.0 - cos_v    ;
			p_coeffs->b2=  (1.0 - cos_v)/2.0 ;
			p_coeffs->a1=  -2.0*cos_v      ;
			p_coeffs->a2=   1.0 - alpha  ;
		} break;
	
	
		case HIGHPASS: {
	
			p_coeffs->b0 =  (1.0 + cos_v)/2.0;
			p_coeffs->b1 = -(1.0 + cos_v);
			p_coeffs->b2 =  (1.0 + cos_v)/2.0;
			p_coeffs->a1 =  -2.0*cos_v;
			p_coeffs->a2 =   1.0 - alpha;
		} break;
		
		case BANDPASS: {
	
			p_coeffs->b0 =  alpha*sqrt(Q+1);
			p_coeffs->b1 =  0.0 ;
			p_coeffs->b2 =  -alpha*sqrt(Q+1);
			p_coeffs->a1 =  -2.0*cos_v;
			p_coeffs->a2 =   1.0 - alpha;
		} break;
	
		case NOTCH: {
	
			p_coeffs->b0 =   1.0;
			p_coeffs->b1 =  -2.0*cos_v;
			p_coeffs->b2 =   1.0;
			p_coeffs->a1 =  -2.0*cos_v;
			p_coeffs->a2 =   1.0 - alpha;
		} break;
    
    };

    p_coeffs->b0/=a0;
    p_coeffs->b1/=a0;
    p_coeffs->b2/=a0;
    p_coeffs->a1/=0.0-a0;
    p_coeffs->a2/=0.0-a0;
    
    //undenormalise
    p_coeffs->b0=undenormalise(p_coeffs->b0);
    p_coeffs->b1=undenormalise(p_coeffs->b1);
    p_coeffs->b2=undenormalise(p_coeffs->b2);
    p_coeffs->a1=undenormalise(p_coeffs->a1);
    p_coeffs->a2=undenormalise(p_coeffs->a2);
    
}