/***************************************** EQ10 library version 1.0 Copyright (C)2002 4Front Technologies Written by George Yohng http://www.opensound.com Proprietary software. *****************************************/ #include "main.h" #include "eq10dsp.h" //#include //#include #include #include "WinampAttributes.h" #define DENORMAL_FIX // comment this for no denormal fixes char _eq10_copyright[]= "EQ10 Library version 1.0\n" "Copyright (C)2002 4Front Technologies http://www.opensound.com\n" "Copyright (C)2001-2002 by George Yohng http://www.yohng.com\n\0" "EQ10 ENGINE"; static double eq10_freq[EQ10_NOFBANDS]={ 70, 180, 320, 600, 1000, 3000, 6000, 12000, 14000, 16000 }; // winamp style frequency table; static double eq10_freq_iso[EQ10_NOFBANDS]={31,62,125,250,500,1000,2000,4000,8000,16000}; // ISO frequency table #ifdef EQ10_DQ static double eq10_q[EQ10_NOFBANDS]=EQ10_DQ; #endif static void eq10_bsetup2(int u,double rate,eq10band_t *band,double freq,double Q) { double angle; double a0,/*a1,a2,*/b0,b1,b2,alpha; if (rate<4000.0) rate=4000.0; if (rate>384000.0) rate=384000.0; if (freq<20.0) freq=20.0; if (freq>=(rate*0.499)) {band->ua0=band->da0=0;return;} angle = 2.0*3.1415926535897932384626433832795*freq/rate; alpha = sin(angle)/(2.0*Q); b0 = 1.0/(1.0+alpha); a0 = b0*alpha; b1 = b0*2*cos(angle); b2 = b0*(alpha-1); if (u>0) { band->ua0=a0; band->ub1=b1; band->ub2=b2; } else { band->da0=a0; band->db1=b1; band->db2=b2; } } static void eq10_bsetup(double rate,eq10band_t *band,double freq,double Q) { memset(band,0,sizeof(*band)); eq10_bsetup2(-1,rate,band,freq,Q*0.5); eq10_bsetup2(1,rate,band,freq,Q*2.0); #ifdef EQ10_DETECTOR_CODE /* release of detector */ band->detectdecay=pow(0.001,1.0/(rate*EQ10_DETECTOR_RELEASE)); #endif } void eq10_setup(eq10_t *eq, int eqs, double rate) { int t,k; for(k=0;kband[t],(config_eq_frequencies==EQ_FREQUENCIES_WINAMP)?eq10_freq[t]:eq10_freq_iso[t],EQ10_Q); #else eq10_bsetup(rate,&eq->band[t],(config_eq_frequencies==EQ_FREQUENCIES_WINAMP)?eq10_freq[t]:eq10_freq_iso[t],eq10_q[t]); #endif eq->detect=0; /* release of trimmer */ eq->detectdecay=pow(0.001,1.0/(rate*EQ10_TRIM_RELEASE)); } } void eq10_processf(eq10_t *eq,float *buf,float *outbuf,int sz,int idx,int step) { int t,k; float *in,*out; if (!eq) return; buf+=idx; outbuf+=idx; in=buf; for(k=0;kband[k].x1; double x2 = eq->band[k].x2; double y1 = eq->band[k].y1; double y2 = eq->band[k].y2; double gain = eq->band[k].gain; #ifdef EQ10_DETECTOR_CODE double detect = eq->band[k].detect; double detectdecay = eq->band[k].detectdecay; #endif out = outbuf; if (gain>0.0) { a0 = eq->band[k].ua0*gain; b1 = eq->band[k].ub1; b2 = eq->band[k].ub2; } else { a0 = eq->band[k].da0*gain; b1 = eq->band[k].db1; b2 = eq->band[k].db2; } if (a0==0.0) continue; for(t=0;tdetect) detect=fabs(y0); detect*=detectdecay; #ifdef DENORMAL_FIX detect+=1e-30; #endif #endif x2=x1; x1=in[0]; y2=y1; y1=y0; out[0] = (float)(y0 + in[0]); } in=outbuf; eq->band[k].x1=x1; eq->band[k].x2=x2; eq->band[k].y1=y1; eq->band[k].y2=y2; #ifdef EQ10_DETECTOR_CODE eq->band[k].detect=detect; #endif } if (config_eq_limiter) { double detect=eq->detect; double detectdecay=eq->detectdecay; out=outbuf; for(t=0;tdetect) detect=fabs(in[0]); if (detect>EQ10_TRIM_CODE) out[0]=in[0]*(float)(EQ10_TRIM_CODE/detect); else out[0]=in[0]; detect*=detectdecay; #ifdef DENORMAL_FIX detect+=1e-30; #endif } eq->detect=detect; } else if ((in==buf)&&(buf!=outbuf)) { out=outbuf; for(t=0;tband[bandnr].gain=realgain; } double eq10_getgain(eq10_t *eq,int bandnr) { return eq10_gain2db(eq->band[bandnr].gain); } double eq10_detect(eq10_t *eq,int bandnr) { #ifdef EQ10_DETECTOR_CODE return eq10_gain2db(eq->band[bandnr].detect); #else return 0; #endif } #ifdef TESTCASE eq10_t eq; float buf1[4096] = {0}; float buf[4096] = {0}; int main() { int t,k; eq10_setup(&eq,1,44100); for(t=0;t<4096;t++) { buf1[t]=warand()*(1.0/16384); } for(t=0;t