Commit 886ed02b authored by Monty Montgomery's avatar Monty Montgomery

Thinking a little harder about the filter setup in the deverber; make a small...

Thinking a little harder about the filter setup in the deverber; make a small follower change that yields a large quality improvement in deverb.



git-svn-id: https://svn.xiph.org/trunk/postfish@7874 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 180ad0df
......@@ -313,7 +313,7 @@ void compute_iir_fast_decay2(float *x, int n, iir_state *is,
}
/* allow decay to proceed in freefall */
void compute_iir_freefall1(float *x, int n, iir_state *is,
void compute_iir_only_freefall1(float *x, int n, iir_state *is,
iir_filter *decay){
double d_c0=decay->c[0];
......@@ -347,42 +347,6 @@ void compute_iir_freefall1(float *x, int n, iir_state *is,
}
void compute_iir_freefall2(float *x, int n, iir_state *is,
iir_filter *decay){
double d_c0=decay->c[0];
double d_c1=decay->c[1];
double x0=is->x[0];
double x1=is->x[1];
double y0=is->y[0];
double y1=is->y[1];
int i=0;
if(zerome(y0) && zerome(y1)){
y0=y1=0.;
}
while(i<n){
double yd;
if(y1<y0)y1=y0; // slope fixup
yd = y0*d_c0+y1*d_c1;
if(x[i]>yd)yd=x[i];
x1=x0;x0=x[i];
y1=y0;x[i]=y0=yd;
i++;
}
is->x[0]=x0;
is->x[1]=x1;
is->y[0]=y0;
is->y[1]=y1;
}
void compute_iir_decayonly2(float *x, int n, iir_state *is,
iir_filter *decay){
double d_c0=decay->c[0];
......@@ -420,83 +384,6 @@ void compute_iir_decayonly2(float *x, int n, iir_state *is,
}
void compute_iir_freefall3(float *x, int n, iir_state *is,
iir_filter *decay){
double d_c0=decay->c[0];
double d_c1=decay->c[1];
double d_c2=decay->c[2];
double x0=is->x[0],y0=is->y[0];
double x1=is->x[1],y1=is->y[1];
double x2=is->x[2],y2=is->y[2];
int i=0;
if(zerome(y0) && zerome(y1) && zerome(y2)){
y0=y1=y2=0.;
}
while(i<n){
double yd;
if(y1<y0)y1=y0; // slope fixup
if(y2<y1)y2=y1; // slope fixup
yd = y0*d_c0+y1*d_c1+y2*d_c2;
if(x[i]>yd)yd=x[i];
x2=x1;x1=x0;x0=x[i];
y2=y1;y1=y0;x[i]=y0=yd;
i++;
}
is->x[0]=x0;is->y[0]=y0;
is->x[1]=x1;is->y[1]=y1;
is->x[2]=x2;is->y[2]=y2;
}
void compute_iir_freefall4(float *x, int n, iir_state *is,
iir_filter *decay){
double d_c0=decay->c[0];
double d_c1=decay->c[1];
double d_c2=decay->c[2];
double d_c3=decay->c[3];
double x0=is->x[0],y0=is->y[0];
double x1=is->x[1],y1=is->y[1];
double x2=is->x[2],y2=is->y[2];
double x3=is->x[3],y3=is->y[3];
int i=0;
if(zerome(y0) && zerome(y1) && zerome(y2) && zerome(y3)){
y0=y1=y2=y3=0.;
}
while(i<n){
double yd;
if(y1<y0)y1=y0; // slope fixup
if(y2<y1)y2=y1; // slope fixup
if(y3<y2)y3=y2; // slope fixup
yd = y0*d_c0+y1*d_c1+y2*d_c2+y3*d_c3;
if(x[i]>yd)yd=x[i];
x3=x2;x2=x1;x1=x0;x0=x[i];
y3=y2;y2=y1;y1=y0;x[i]=y0=yd;
i++;
}
is->x[0]=x0;is->y[0]=y0;
is->x[1]=x1;is->y[1]=y1;
is->x[2]=x2;is->y[2]=y2;
is->x[3]=x3;is->y[3]=y3;
}
/* symmetric filter computation */
void compute_iir_symmetric2(float *x, int n, iir_state *is,
......@@ -530,71 +417,43 @@ void compute_iir_symmetric2(float *x, int n, iir_state *is,
}
void compute_iir_symmetric3(float *x, int n, iir_state *is,
iir_filter *filter){
void compute_iir_symmetric_freefall2(float *x, int n, iir_state *is,
iir_filter *filter){
double c0=filter->c[0];
double c1=filter->c[1];
double c2=filter->c[2];
double g=filter->g;
double x0=is->x[0],y0=is->y[0];
double x1=is->x[1],y1=is->y[1];
double x2=is->x[2],y2=is->y[2];
double x0=is->x[0];
double x1=is->x[1];
double y0=is->y[0];
double y1=is->y[1];
int i=0;
if(zerome(y0) && zerome(y1) && zerome(y2)){
y0=y1=y2=0.;
if(zerome(y0) && zerome(y1)){
y0=y1=0.;
}
while(i<n){
double yd= (x[i]+(x0+x1)*3.+x2)/g + y0*c0+y1*c1+y2*c2;
x2=x1;x1=x0;x0=x[i];
y2=y1;y1=y0;x[i]=y0=yd;
i++;
}
is->x[0]=x0;is->y[0]=y0;
is->x[1]=x1;is->y[1]=y1;
is->x[2]=x2;is->y[2]=y2;
}
void compute_iir_symmetric4(float *x, int n, iir_state *is,
iir_filter *filter){
double c0=filter->c[0];
double c1=filter->c[1];
double c2=filter->c[2];
double c3=filter->c[3];
double g=filter->g;
double x0=is->x[0],y0=is->y[0];
double x1=is->x[1],y1=is->y[1];
double x2=is->x[2],y2=is->y[2];
double x3=is->x[3],y3=is->y[3];
int i=0;
if(zerome(y0) && zerome(y1) && zerome(y2) && zerome(y3)){
y0=y1=y2=y3=0.;
}
double yd= (x0*2.+x1)/g + y0*c0+y1*c1;
while(i<n){
double yd= (x[i]+(x0+x2)*4.+x1*6.+x3)/g +
y0*c0+y1*c1+y2*c2+y3*c3;
x3=x2;x2=x1;x1=x0;x0=x[i];
y3=y2;y2=y1;y1=y0;x[i]=y0=yd;
if(x[i]<yd){
x1=x0;x0=0;
}else{
yd+= x[i]/g;
x1=x0;x0=x[i];
}
y1=y0;x[i]=y0=yd;
i++;
}
is->x[0]=x0;is->y[0]=y0;
is->x[1]=x1;is->y[1]=y1;
is->x[2]=x2;is->y[2]=y2;
is->x[3]=x3;is->y[3]=y3;
is->x[0]=x0;
is->x[1]=x1;
is->y[0]=y0;
is->y[1]=y1;
}
/* filter decision wrapper */
void compute_iir2(float *x, int n, iir_state *is,
iir_filter *attack, iir_filter *decay){
......
......@@ -77,20 +77,14 @@ extern void compute_iir_fast_decay2(float *x, int n, iir_state *is,
iir_filter *attack, iir_filter *decay);
extern void compute_iir_symmetric2(float *x, int n, iir_state *is,
iir_filter *filter);
extern void compute_iir_symmetric3(float *x, int n, iir_state *is,
iir_filter *filter);
extern void compute_iir_symmetric4(float *x, int n, iir_state *is,
iir_filter *filter);
extern void compute_iir2(float *x, int n, iir_state *is,
iir_filter *attack, iir_filter *decay);
extern void compute_iir_freefall1(float *x, int n, iir_state *is,
iir_filter *decay);
extern void compute_iir_freefall2(float *x, int n, iir_state *is,
extern void compute_iir_only_freefall1(float *x, int n, iir_state *is,
iir_filter *decay);
extern void compute_iir_decayonly2(float *x, int n, iir_state *is,
iir_filter *decay);
extern void compute_iir_freefall3(float *x, int n, iir_state *is,
iir_filter *decay);
extern void compute_iir_freefall4(float *x, int n, iir_state *is,
iir_filter *decay);
extern void compute_iir_symmetric_freefall2(float *x, int n, iir_state *is,
iir_filter *filter);
......@@ -113,6 +113,27 @@ int suppress_load(void){
return 0;
}
static void _analysis(char *base,int seq, float *data, int n,int dB,
off_t offset){
FILE *f;
char buf[80];
sprintf(buf,"%s_%d.m",base,seq);
f=fopen(buf,"a");
if(f){
int i;
for(i=0;i<n;i++)
if(dB)
fprintf(f,"%d %f\n",(int)(i+offset),todB(data[i]));
else
fprintf(f,"%d %f\n",(int)(i+offset),(data[i]));
}
fclose(f);
}
static void suppress_work_helper(void *vs, suppress_settings *sset){
suppress_state *sss=(suppress_state *)vs;
subband_state *ss=&sss->ss;
......@@ -122,9 +143,10 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){
iir_filter *smooth=&sss->smooth;
iir_filter *release=&sss->release;
int ahead;
static off_t offset=0;
if(smoothms!=smooth->ms)filter_set(ss,smoothms,smooth,1,2);
if(releasems!=release->ms)filter_set(ss,releasems,release,0,2);
if(releasems!=release->ms)filter_set(ss,releasems,release,0,1);
ahead=impulse_ahead2(smooth->alpha);
......@@ -164,13 +186,14 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){
if(sset->linkp==0 || firstlink==1){
memcpy(slow,fast,sizeof(slow));
//memcpy(slow,fast,sizeof(slow));
compute_iir_symmetric2(fast, input_size, &sss->iirS[i][j],
compute_iir_symmetric_freefall2(fast, input_size, &sss->iirS[i][j],
smooth);
compute_iir_fast_attack2(slow, input_size, &sss->iirR[i][j],
smooth,release);
memcpy(slow,fast,sizeof(slow));
compute_iir_freefall1(slow, input_size, &sss->iirR[i][j],
release);
//_analysis("fast",i,fast,input_size,1,offset);
//_analysis("slow",i,slow,input_size,1,offset);
......@@ -221,8 +244,8 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){
}
sss->prevratio[i]=multiplier;
}
offset+=input_size;
}
static void suppress_work_channel(void *vs){
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment