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

📄 hxeqengine.c

📁 linux下的一款播放器
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* apply ramping pregain */		pwr = (eq->pregain - prev_pregain)/(float)(nsamps/eq->nchans);				for (chan = 0; chan < eq->nchans; chan++)		{			eq->pregain = prev_pregain;			optr = eq->itlbuf + chan;			for (n = 0; n < nsamps; n += eq->nchans)			{				ftmp = *optr;				ftmp *= eq->pregain;				*optr = ftmp;				eq->pregain += pwr;				optr += eq->nchans;			}		}	}}	#else // _EQ_X86_WINDOWSstatic int FillOutputShorts(EQPTR eq, short *outpcm, int nsamps){	float *optr, ftmp;	int ltmp, n, nclips;	unsigned int max_samp;	nclips = 0;	max_samp = 0;	/* store output with Auto-Gain adjustments */	if (eq->autopregain == 1)	{		/* store output */		optr = eq->itlbuf;		for (n = 0; n < nsamps; n ++) {			ftmp = *optr++;			ltmp = RoundFtoL((eq->pregain*ftmp));			if (ltmp > 32767) {				eq->pregain *= 32767.f/(float)ltmp;				ltmp = 32767;			} else if (ltmp < -32768) {				eq->pregain *= -32768.f/(float)ltmp;				ltmp = -32768;			}			outpcm[n] = (short)ltmp;			max_samp |= ((ltmp)^(ltmp>>31));		}	    /* only update if we get some audible audio */	    if (max_samp > 0x0800)	    {			/* Update the time averaged maximum measurement */			if (max_samp > eq->pwrLevelMeasure)				eq->pwrLevelMeasure = (float)max_samp;			else				eq->pwrLevelMeasure = 0.99f * eq->pwrLevelMeasure + 0.01f * (float)max_samp;			if (eq->pwrLevelMeasure < 8192.f)			{				eq->pregain += 0.004f;			}	    }	    /* 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];	}	else	{		/* store output */		optr = eq->itlbuf;		for (n = 0; n < nsamps; n ++) {			ftmp = *optr++;			ltmp = RoundFtoL(eq->pregain*ftmp);			if (ltmp > 32767) {				ltmp = 32767;				nclips++;			} else if (ltmp < -32768) {				ltmp = -32768;				nclips++;			}			outpcm[n] = (short)ltmp;		}	}	return nclips;}#endif // _EQ_X86_WINDOWS/* * Process a buffer of mono/stereo samples. * * Requires nsamps to be a multiple of nchans. * * Returns a count of clipped outputs, intended to drive * a clipping indicator. */intEQProcess(EQPTR eq, short *inpcm, short *outpcm, int nsamps){	int nclips, chan;	int chunk, maxchunk;#ifdef _EQ_X86_WINDOWS	int *fixedbuf;#endif	nclips = 0;	maxchunk = EQ_MAXSAMPS * eq->nchans;	/* double, if stereo */	/* process in chunks no bigger than maxchunk */	while (nsamps > 0) {		/* size of next chunk */		chunk = (nsamps < maxchunk ? nsamps : maxchunk);		/* add reverb to input samples -- applies to both channels if stereo */		AddReverb(eq, inpcm, chunk);		/* process all channels */		for (chan = 0; chan < eq->nchans; chan++) {			/* apply equalizer filtering to samples stored in eq->eqhist. */			/* The output is written as interleaved 'floats' to eq->inlbuf. */			ProcessBlock(eq, chunk, chan);		}#ifdef _EQ_X86_WINDOWS		/* perform auto pre-gain control and apply gain */		/* On x86 the auto pre-gain is based on signal power */		/* and the subsequent limiter will handle clipping */		ApplyGain(eq, chunk);		/* Convert the floating point numbers to 32-bit fixed point */		fixedbuf = (int *)eq->itlbuf;		FloatToFixed32(eq->itlbuf, fixedbuf, chunk, EQ_FLT2FIX_SCALE);		/* Apply limiter */		LimiterProcess(fixedbuf, chunk, eq->limState);		LimiterOutput16(fixedbuf, outpcm, chunk, eq->limState);#else		/* fill the output pcm data, handle clipping, and auto gain */		/* (excellent place for a dynamic range compressor) */		/* On non-x86, (automatic) pre-gain is also handled here */		nclips += FillOutputShorts(eq, outpcm, chunk);#endif		inpcm += chunk;		outpcm += chunk;		nsamps -= chunk;	}	return nclips;}/* * Set the EQ gains. * * dbgain[] is an array of gain settings. * units are in 1/8 dB, where 0 = 0 dB. * gains above EQ_MAXGAIN are clamped to +18dB. * gains below EQ_MINGAIN are clamped to -18dB. */voidEQSetGain(EQPTR eq, int *dbgain){	int i, igain, highgain, chan;	highgain = 0;	for (i = 0; i < eq->nbands; i++) {		igain = dbgain[i];				/* clamp to +/-18dB */		if (igain > EQ_MAXGAIN)			igain = EQ_MAXGAIN;		if (igain < EQ_MINGAIN)			igain = EQ_MINGAIN;		/* find the highest positive gain */		if (igain > highgain)			highgain = igain;		/*		 * Now convert from 1/8 dB to filter gain.		 * Since bandpass filters are added to a unity-gain passthru,		 * filter gain g results in response of 20*log10(1 + g) dB.		 * The inverse is g[i] = 10^(i/20) - 1.		 *		 * filtgain = (float)pow(10.0, igain/(8.0 * 20.0)) - 1.0f;		 */				eq->filtgain[i] = powertab[igain-EQ_MINGAIN] - 1.0f;	}	/* init history to zero */	for (chan = 0; chan < EQ_MAXCHANS; chan++) {		eq->ihist[chan][0] = 0.0f;		eq->ihist[chan][1] = 0.0f;		for (i = 0; i < 2 * EQ_MAXBANDS; i++)			eq->ohist[chan][i] = 0.0f;	}}/* * Set the pre-gain. * * 'pregain' is the pregain setting. * units are in 1/8 dB, where 0 = 0 dB. * gains above EQ_MAXGAIN are clamped to +18dB. * gains below EQ_MINGAIN are clamped to -18dB. */voidEQSetPreGain(EQPTR eq, int pregain){	int igain;	igain = pregain;		/* clamp to +/-18dB */	if (igain > EQ_MAXGAIN)		igain = EQ_MAXGAIN;	if (igain < EQ_MINGAIN)		igain = EQ_MINGAIN;	/*	 * Now convert from 1/8 dB to filter gain.	 * Since bandpass filters are added to a unity-gain passthru,	 * filter gain g results in response of 20*log10(1 + g) dB.	 * The inverse is g[i] = 10^(i/20) - 1.	 *	 * pregain = (float)pow(10.0, igain/(8.0 * 20.0)) - 1.0f;	 */		eq->pregain = powertab[igain-EQ_MINGAIN];}/* * Set the Reverb settings. * * roomsize:	0-12 sets the size of the room to be simulated. *				0: no reverb, 1: very small room, 12: very large room * reverb:		0-12 sets the amount of echo. *				0: no echo, 1: little echo, 12: tons of echo */void EQSetReverb(EQPTR eq, int roomsize, int reverb){	int echo, delay;	// Assign the reverb settings	eq->roomsize = roomsize;	eq->reverb = reverb;	// setup delays/gains	eq->gain = feedbackgain_tab[reverb];	for (echo = 0; echo < REVERB_NUM_ECHOS; echo++)	{		delay = (ratetab[eq->ratecode] * delay_tab[roomsize][echo] * (eq->nchans) / 1000) + echo;		if ((eq->nchans == 2) && (delay & 1))			delay--;		eq->echoPtr[echo] = eq->eqhist_head - delay;		while (eq->echoPtr[echo] < eq->eqhist)			eq->echoPtr[echo] += eq->eqhist_end - eq->eqhist;	}}/* * Get the Reverb settings. * * roomsize:	0-12 sets the size of the room to be simulated. *				0: no reverb, 1: very small room, 12: very large room * reverb:		0-12 sets the amount of echo. *				0: no echo, 1: little echo, 12: tons of echo */voidEQGetReverb(EQPTR eq, int *roomsize, int *reverb){	// Assign the reverb settings	*roomsize = eq->roomsize;	*reverb = eq->reverb;} /* * Enables the automatic pregain control. * * enable:		0: off, 1: on */voidEQEnableAutoPreGain(EQPTR eq, int enable){    eq->autopregain = enable;}/* * Get the pre-gain. * * 'pregain' is a pointer to the pregain setting. * units are in 1/8 dB, where 0 = 0 dB. * gains above EQ_MAXGAIN are clamped to +18dB. * gains below EQ_MINGAIN are clamped to -18dB. */voidEQGetPreGain(EQPTR eq, int *pregain){    int i;    for (i = 0; i < EQ_MAXGAIN-EQ_MINGAIN+1; i++)		if (eq->pregain < powertab[i])			break;    *pregain = i + EQ_MINGAIN;}/* * Resets the reverb echo buffers. */voidEQResetReverb(EQPTR eq){	memset(eq->eqhist, 0, (eq->eqhist_end - eq->eqhist + (EQ_MAXSAMPS * eq->nchans)) * sizeof(float));}/* * Free an EQ instance. */voidEQFree(EQPTR eq){	if (eq) 	{		if (eq->eqhist) 		{			free(eq->eqhist);			eq->eqhist = NULL;		}		if (eq->itlbuf)		{			free(eq->itlbuf);			eq->itlbuf = NULL;		}		#ifdef _EQ_X86_WINDOWS		LimiterFree(eq->limState);#endif		free(eq);	/* free all memory */		eq = NULL;	}}

⌨️ 快捷键说明

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