⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxeqengine.c

📁 linux下的一款播放器
💻 C
📖 第 1 页 / 共 3 页
字号:
		eq->echoPtr[i] = eq->eqhist;		for (chan = 0; chan < EQ_MAXCHANS; chan++) {			eq->echoFiltState[chan][i] = 0.0f;		}	}	eq->gain = 0.0f;	eq->reverb = 0;	eq->roomsize = 0;	eq->timer = 0L;	eq->echoFiltCoeff = echoFiltCoeff_tab[ratecode];#ifdef _EQ_X86_WINDOWS	// Initialize the limiter	eq->limState = LimiterInit(samprate, nchans, EQ_FIXED_HEADROOM_BITS);	init_codecutil();#endif	return eq;}static voidAddReverb(EQPTR eq, short *inpcm, int nsamps){	// apply reverb	int		echo;			// the current echo number being processed	int		chan;			// the current chan being processed	int		samps;			// samps processed between echo pointer shifts	float	*fhistPtr;		// working pointer into the eq->eqhist buffer 	short	*inpcmPtr;		// working pointer to the input pcm data	int		bufflength;		// length of the eq->eqhist buffer	float	*loop_echoPtr[REVERB_NUM_ECHOS];	float	loop_eFiltState[EQ_MAXCHANS][REVERB_NUM_ECHOS];	register float	fres;	// storage for new reverb'ed samples	register float	ftmp;	register float	c = 1.0f - eq->echoFiltCoeff;	register float	loop_gain;	register float	*loop_eFiltStatePtr;	eq->timer += nsamps * 1000 / (ratetab[eq->ratecode] * eq->nchans);	bufflength = eq->eqhist_end-eq->eqhist;	eq->eqhist_start = eq->eqhist_head;	// convert input pcm to floats and fill history	inpcmPtr = inpcm;	fhistPtr = eq->eqhist_head;	while (inpcmPtr < inpcm + nsamps)	{		*(eq->eqhist_head) = (float)(*inpcmPtr);		inpcmPtr++;		eq->eqhist_head++;		if (eq->eqhist_head == eq->eqhist_end)			eq->eqhist_head = eq->eqhist;	}	// fill the buffer extension	if ((eq->eqhist_head <= eq->eqhist + EQ_MAXSAMPS * eq->nchans) || 		(eq->eqhist_start <= eq->eqhist + EQ_MAXSAMPS * eq->nchans))	{		memcpy(eq->eqhist_end,eq->eqhist,EQ_MAXSAMPS * eq->nchans * sizeof(float));	}	if (eq->reverb == 0)		return;	// add echos to the history	loop_gain = eq->gain * eq->echoFiltCoeff;	for (echo = 0; echo < REVERB_NUM_ECHOS; echo++)	{		loop_echoPtr[echo] = eq->echoPtr[echo];		for (chan = 0; chan < eq->nchans; chan++)		{			loop_eFiltState[chan][echo] = eq->echoFiltState[chan][echo];		}	}	samps = 1;	nsamps /= REVERB_NUM_ECHOS;	echo = 0;	while (1)	{		loop_eFiltStatePtr = &(loop_eFiltState[0][0]);		for (chan = 0; chan < eq->nchans; chan++)		{			fres = (*fhistPtr);#define PROCESS_ECHO_UP(e) \			ftmp = (loop_gain*(*(loop_echoPtr[(e)])++)) + c*loop_eFiltStatePtr[(e)]; \			loop_eFiltStatePtr[(e)] = ftmp; \			fres += ftmp#define PROCESS_ECHO_DOWN(e) \			ftmp = (loop_gain*(*(loop_echoPtr[(e)])++)) + c*loop_eFiltStatePtr[(e)]; \			loop_eFiltStatePtr[(e)] = ftmp; \			fres -= ftmp			PROCESS_ECHO_UP(0);			PROCESS_ECHO_DOWN(1);			PROCESS_ECHO_UP(2);			PROCESS_ECHO_DOWN(3);			PROCESS_ECHO_UP(4);			PROCESS_ECHO_DOWN(5);			PROCESS_ECHO_UP(6);			PROCESS_ECHO_DOWN(7);			PROCESS_ECHO_UP(8);			PROCESS_ECHO_DOWN(9);			// remove mean from reverb			eq->mean[chan] = (1.0f - 0.01f) * eq->mean[chan] + 0.01f * fres;			fres -= eq->mean[chan];			*fhistPtr++ = fres;			loop_eFiltStatePtr += REVERB_NUM_ECHOS;			samps++;		}		if (fhistPtr >= eq->eqhist_end)			fhistPtr -= bufflength;		if (fhistPtr == eq->eqhist_head)			break;#ifdef MOVE_FEEDBACK_DELAYS		// Move echo pointers a little to prevent resonance effects		// NOTE: This is currently not compiled in since, as implemented,		//   it seem to be causing some flanging effects.		if (samps > nsamps)		{			(loop_echoPtr[echo]) += ((((int)(eq->timer) & 1023) < 512) ? (1 - 2 * (echo & 1)) : (2 * (echo & 1) - 1))*(eq->nchans);			echo++;			samps = 1;		}#endif	}	// store the echo locations	for (echo = 0; echo < REVERB_NUM_ECHOS; echo++)	{		if (loop_echoPtr[echo] >= eq->eqhist_end)			eq->echoPtr[echo] = loop_echoPtr[echo] - bufflength;		else			eq->echoPtr[echo] = loop_echoPtr[echo];		for (chan = 0; chan < eq->nchans; chan++)		{			eq->echoFiltState[chan][echo] = loop_eFiltState[chan][echo];		}	}	inpcmPtr = inpcm;	fhistPtr = eq->eqhist_start;}/* * Process a single block of samples. * * Requires nsamps <= EQ_MAXSAMPS * nchans * Requires chan = 0 for mono, 0/1 for stereo. * * Returns the count of clipped outputs. */static voidProcessBlock(EQPTR eq, int nsamps, int chan){	float *iptr, *optr, *ihptr, *ohptr;	const float *cptr;	float *iptrend;	float alpha, beta, gamma, accum;	float ibuf1, ibuf2, obuf1, obuf2;	float ftmp;	int band, n;	iptr = eq->iflt;	optr = eq->oflt;	cptr = eq->eqhist_start + chan;	/* if stereo, de-interleave */	for (n = chan; n < nsamps; n += eq->nchans) {		ftmp = *cptr;		*iptr++ = ftmp;		*optr++ = ftmp;		cptr += eq->nchans;		if (cptr >= eq->eqhist_end)			cptr -= (eq->eqhist_end - eq->eqhist);	}	iptrend = iptr;		/* one past last input */	/* add the filter output from each band */	cptr = eq->coeff;	ihptr = eq->ihist[chan];	ohptr = eq->ohist[chan];	for (band = 0; band < eq->nbands; band++) {		/* load band filter coeffs */		alpha = cptr[0] * eq->filtgain[band];	/* premult filtgain into alpha */		gamma = cptr[1];		beta = cptr[2];		cptr += 3;		/* fast-path zero-gain case */		if (eq->filtgain[band] > 0.25f || eq->filtgain[band] < -0.25f)		{			/* restore band history */			ibuf2 = ihptr[0];		/* iptr[-2] */			ibuf1 = ihptr[1];		/* iptr[-1] */			obuf2 = ohptr[0];		/* optr[-2] */			obuf1 = ohptr[1];		/* optr[-1] */			/* 			 * The following code is an optimized implementation of:			 * y[n] = alpha * (x[n] - x[n-2]) + beta * y[n-2] + gamma * y[n-1];			 * out[n] += y[n];			 */			iptr = eq->iflt;			optr = eq->oflt;			accum = obuf1;			/* filter, unrolled by 4 */			for (; iptr < iptrend-3; ) {				accum *= gamma;							/* gamma * y[n-1] */				accum += (iptr[0] - ibuf2) * alpha;		/* alpha * (x[n] - x[n-2]) */				ibuf2 = iptr[0];						/* flip ibuf */				accum += obuf2 * beta;					/* beta * y[n-2] */				optr[0] += accum;						/* out[n] += y[n] */				obuf2 = accum;							/* flip obuf */				accum *= gamma;				accum += (iptr[1] - ibuf1) * alpha;				ibuf1 = iptr[1];				accum += obuf1 * beta;				optr[1] += accum;				obuf1 = accum;				accum *= gamma;				accum += (iptr[2] - ibuf2) * alpha;				ibuf2 = iptr[2];				accum += obuf2 * beta;				optr[2] += accum;				obuf2 = accum;				accum *= gamma;				accum += (iptr[3] - ibuf1) * alpha;				ibuf1 = iptr[3];				accum += obuf1 * beta;				optr[3] += accum;				obuf1 = accum;				iptr += 4;				optr += 4;			}			/* filter the remainder */			for (; iptr < iptrend; ) {				accum *= gamma;							/* gamma * y[n-1] */				accum += (*iptr - ibuf2) * alpha;		/* alpha * (x[n] - x[n-2]) */				ibuf2 = ibuf1;							/* shift ibuf */				ibuf1 = *iptr++;						/* shift ibuf */				accum += obuf2 * beta;					/* beta * y[n-2] */				obuf2 = obuf1;							/* shift obuf */				obuf1 = accum;							/* shift obuf */				*optr++ += accum;						/* out[n] += y[n] */			}			/* save band output history */			ohptr[0] = obuf2;			ohptr[1] = obuf1;			ohptr += 2;		}		else		{			/* save band output history */			ohptr[0] = 0;			ohptr[1] = 0;			ohptr += 2;			ibuf2 = iptrend[-2];		/* iptr[-2] */			ibuf1 = iptrend[-1];		/* iptr[-1] */		}	}	/* save input history */	ihptr[0] = ibuf2;	ihptr[1] = ibuf1;	/* Re-interleave samples */	iptr = eq->oflt;	optr = eq->itlbuf + chan;	for (n = chan; n < nsamps; n += eq->nchans) {		*optr = *iptr++;		optr += eq->nchans;	}}#ifdef _EQ_X86_WINDOWS#define PWR_NOISE_THRESH  (512.f*512.f)#define PWR_LOW_THRESH    (4096.f*4096.f)#define PWR_HIGH_THRESH   (8192.f*8192.f*2.f)voidApplyGain(EQPTR eq, int nsamps){	int n, chan, settings_change = 0;	float *optr;	float pwr, chan_pwr[EQ_MAXCHANS];	float prev_pregain, ftmp;	if (eq->autopregain == 0)	{		if (eq->pregain < 0.90 || eq->pregain > 1.1)		{			/* Apply fixed pregain */			optr = eq->itlbuf;			for (n = 0; n < nsamps; n++)			{				ftmp = *optr;				ftmp *= eq->pregain;				*optr = ftmp;				optr ++;			}		}	}	else	{		prev_pregain = eq->pregain;		/* measure the power in each channel */		for (chan = 0; chan < eq->nchans; chan++)		{			pwr = 0;			optr = eq->itlbuf + chan;			for (n = 0; n < nsamps; n += eq->nchans)			{				ftmp = *optr;				ftmp *= prev_pregain;				ftmp *= ftmp;				pwr += ftmp;				optr += eq->nchans;			}			chan_pwr[chan] = pwr/(float)(nsamps/eq->nchans);		}		/* find the largest power in all channels */		pwr = 0;		for (chan = 0; chan < eq->nchans; chan++)		{			if (chan_pwr[chan] > pwr)				pwr = chan_pwr[chan];		}		if (pwr > PWR_NOISE_THRESH)		{			if (pwr > eq->pwrLevelMeasure)				eq->pwrLevelMeasure = (1.0f - 0.1f) * eq->pwrLevelMeasure + (0.1f) * pwr;			else				eq->pwrLevelMeasure = (1.0f - 0.01f) * eq->pwrLevelMeasure + (0.01f) * pwr;			/* now adjust desired pregain given the pwr */			if (eq->pwrLevelMeasure < PWR_LOW_THRESH)			{				eq->pregain *= 1.001f;			}			else if (eq->pwrLevelMeasure > PWR_HIGH_THRESH)			{				eq->pregain *= 0.99f;			}			/* bound the pregain to +/-18 dB */			if (eq->pregain > powertab[EQ_MAXGAIN-EQ_MINGAIN])				eq->pregain = powertab[EQ_MAXGAIN-EQ_MINGAIN];			else if (eq->pregain < powertab[0])				eq->pregain = powertab[0];			eq->pwrLevelMeasure *= (eq->pregain/prev_pregain);		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -