All pastes #329745 Raw Edit

Anonymous

public cpp v1 · immutable
#329745 ·published 2007-01-27 00:29 UTC
rendered paste body
#define LOG10 2.30258509299#define MULSCA(a, b) ((int)((LONG_LONG)((a) << 4) * (b) >> 32))#define SCALEB 12typedef int sample_t;struct IT_FILTER_STATE{	sample_t currsample, prevsample;};static void it_filter_int(DUMB_CLICK_REMOVER *cr, IT_FILTER_STATE *state, sample_t *dst, long pos, sample_t *src, long size, int step, int sampfreq, int cutoff, int resonance){	//profiler( filter ); // ~25600 cycles	sample_t currsample = state->currsample;	sample_t prevsample = state->prevsample;	float a, b, c;	long datasize;	{		float inv_angle = (float)(sampfreq * pow(0.5, 0.25 + cutoff*(1.0/(24<<IT_ENVELOPE_SHIFT))) * (1.0/(2*3.14159265358979323846*110.0)));		float loss = (float)exp(resonance*(-LOG10*1.2/128.0));		float d, e;#if 0		loss *= 2; // This is the mistake most players seem to make!#endif#if 1		d = (1.0f - loss) / inv_angle;		if (d > 2.0f) d = 2.0f;		d = (loss - d) * inv_angle;		e = inv_angle * inv_angle;		a = 1.0f / (1.0f + d + e);		c = -e * a;		b = 1.0f - a - c;#else		a = 1.0f / (inv_angle*inv_angle + inv_angle*loss + loss);		c = -(inv_angle*inv_angle) * a;		b = 1.0f - a - c;#endif	}	dst += pos * step;	datasize = size * step;#define INT_FILTERS#ifdef INT_FILTERS	{		int ai = (int)(a * (1 << (16+SCALEB)));		int bi = (int)(b * (1 << (16+SCALEB)));		int ci = (int)(c * (1 << (16+SCALEB)));		int i;		if (cr) {			sample_t startstep = MULSCA(src[0], ai) + MULSCA(currsample, bi) + MULSCA(prevsample, ci);			dumb_record_click(cr, pos, startstep);		}		for (i = 0; i < datasize; i += step) {			{				sample_t newsample = MULSCA(src[i], ai) + MULSCA(currsample, bi) + MULSCA(prevsample, ci);				prevsample = currsample;				currsample = newsample;			}			dst[i] += currsample;		}		if (cr) {			sample_t endstep = MULSCA(src[datasize], ai) + MULSCA(currsample, bi) + MULSCA(prevsample, ci);			dumb_record_click(cr, pos + size, -endstep);		}	}#else	if (cr) {		float startstep = src[0]*a + currsample*b + prevsample*c;		dumb_record_click(cr, pos, (sample_t)startstep);	}	{		int i = size % 3;		while (i > 0) {			{				float newsample = *src*a + currsample*b + prevsample*c;				src += step;				prevsample = currsample;				currsample = newsample;			}			*dst += (sample_t)currsample;			dst += step;			i--;		}		i = size / 3;		while (i > 0) {			float newsample;			/* Gotta love unrolled loops! */			*dst += (sample_t)(newsample = *src*a + currsample*b + prevsample*c);			src += step; dst += step;			*dst += (sample_t)(prevsample = *src*a + newsample*b + currsample*c);			src += step; dst += step;			*dst += (sample_t)(currsample = *src*a + prevsample*b + newsample*c);			src += step; dst += step;			i--;		}	}	if (cr) {		float endstep = src[datasize]*a + currsample*b + prevsample*c;		dumb_record_click(cr, pos + size, -(sample_t)endstep);	}#endif	state->currsample = currsample;	state->prevsample = prevsample;}static void it_filter_sse(DUMB_CLICK_REMOVER *cr, IT_FILTER_STATE *state, sample_t *dst, long pos, sample_t *src, long size, int step, int sampfreq, int cutoff, int resonance){	__m128 data, impulse;	__m128 temp1, temp2;	sample_t currsample = state->currsample;	sample_t prevsample = state->prevsample;	float imp[4];	// Leave the above alone, or alignment could break... spoony compiler, those aren't even accessed with explicitly aligned intrinsics	//profiler( filter_sse ); // On ClawHammer Athlon64 3200+, ~12000 cycles	long datasize;	{		//profiler( filter_setup ); // ~500 cycles		float inv_angle = (float)(sampfreq * pow(0.5, 0.25 + cutoff*(1.0/(24<<IT_ENVELOPE_SHIFT))) * (1.0/(2*3.14159265358979323846*110.0)));		float loss = (float)exp(resonance*(-LOG10*1.2/128.0));		float d, e;#if 0		loss *= 2; // This is the mistake most players seem to make!#endif#if 1		d = (1.0f - loss) / inv_angle;		if (d > 2.0f) d = 2.0f;		d = (loss - d) * inv_angle;		e = inv_angle * inv_angle;		imp[0] = 1.0f / (1.0f + d + e);		imp[2] = -e * imp[0];		imp[1] = 1.0f - imp[0] - imp[2];#else		imp[0] = 1.0f / (inv_angle*inv_angle + inv_angle*loss + loss);		imp[2] = -(inv_angle*inv_angle) * imp[0];		imp[1] = 1.0f - imp[0] - imp[2];#endif		imp[3] = 0;	}	dst += pos * step;	datasize = size * step;	{		int ai, bi, ci, i;		if (cr) {			sample_t startstep;			ai = (int)(imp[0] * (1 << (16+SCALEB)));			bi = (int)(imp[1] * (1 << (16+SCALEB)));			ci = (int)(imp[2] * (1 << (16+SCALEB)));			startstep = MULSCA(src[0], ai) + MULSCA(currsample, bi) + MULSCA(prevsample, ci);			dumb_record_click(cr, pos, startstep);		}		data = _mm_cvtsi32_ss( data, prevsample );		data = _mm_shuffle_ps( data, data, _MM_SHUFFLE(0, 0, 0, 0) );		data = _mm_cvtsi32_ss( data, currsample );		impulse = _mm_loadu_ps( (const float *) &imp );		temp1 = _mm_shuffle_ps( data, data, _MM_SHUFFLE(0, 1, 0, 0) );		for (i = 0; i < datasize; i += step) {			data = _mm_cvtsi32_ss( temp1, src [i] );			temp1 = _mm_mul_ps( data, impulse );			temp2 = _mm_shuffle_ps( temp1, temp1, _MM_SHUFFLE(0, 0, 3, 2) );			temp1 = _mm_add_ps( temp1, temp2 );			temp2 = _mm_shuffle_ps( temp1, temp1, _MM_SHUFFLE(0, 0, 0, 1) );			temp1 = _mm_add_ps( temp1, temp2 );			temp1 = _mm_shuffle_ps( temp1, data, _MM_SHUFFLE(0, 1, 0, 0) );			dst [i] += _mm_cvtss_si32( temp1 );		}		currsample = _mm_cvtss_si32( temp1 );		temp1 = _mm_shuffle_ps( temp1, temp1, _MM_SHUFFLE(0, 0, 0, 2) );		prevsample = _mm_cvtss_si32( temp1 );		_mm_empty(); // is this necessary?		if (cr) {			sample_t endstep = MULSCA(src[datasize], ai) + MULSCA(currsample, bi) + MULSCA(prevsample, ci);			dumb_record_click(cr, pos + size, -endstep);		}	}	state->currsample = currsample;	state->prevsample = prevsample;}