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, ...@@ -313,7 +313,7 @@ void compute_iir_fast_decay2(float *x, int n, iir_state *is,
} }
/* allow decay to proceed in freefall */ /* 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){ iir_filter *decay){
double d_c0=decay->c[0]; double d_c0=decay->c[0];
...@@ -347,42 +347,6 @@ void compute_iir_freefall1(float *x, int n, iir_state *is, ...@@ -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, void compute_iir_decayonly2(float *x, int n, iir_state *is,
iir_filter *decay){ iir_filter *decay){
double d_c0=decay->c[0]; double d_c0=decay->c[0];
...@@ -420,83 +384,6 @@ void compute_iir_decayonly2(float *x, int n, iir_state *is, ...@@ -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 */ /* symmetric filter computation */
void compute_iir_symmetric2(float *x, int n, iir_state *is, 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, ...@@ -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, void compute_iir_symmetric_freefall2(float *x, int n, iir_state *is,
iir_filter *filter){ iir_filter *filter){
double c0=filter->c[0]; double c0=filter->c[0];
double c1=filter->c[1]; double c1=filter->c[1];
double c2=filter->c[2];
double g=filter->g; double g=filter->g;
double x0=is->x[0],y0=is->y[0]; double x0=is->x[0];
double x1=is->x[1],y1=is->y[1]; double x1=is->x[1];
double x2=is->x[2],y2=is->y[2]; double y0=is->y[0];
double y1=is->y[1];
int i=0; int i=0;
if(zerome(y0) && zerome(y1) && zerome(y2)){ if(zerome(y0) && zerome(y1)){
y0=y1=y2=0.; y0=y1=0.;
} }
while(i<n){ while(i<n){
double yd= (x[i]+(x0+x1)*3.+x2)/g + y0*c0+y1*c1+y2*c2; double yd= (x0*2.+x1)/g + y0*c0+y1*c1;
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.;
}
while(i<n){ if(x[i]<yd){
double yd= (x[i]+(x0+x2)*4.+x1*6.+x3)/g + x1=x0;x0=0;
y0*c0+y1*c1+y2*c2+y3*c3; }else{
x3=x2;x2=x1;x1=x0;x0=x[i]; yd+= x[i]/g;
y3=y2;y2=y1;y1=y0;x[i]=y0=yd; x1=x0;x0=x[i];
}
y1=y0;x[i]=y0=yd;
i++; i++;
} }
is->x[0]=x0;is->y[0]=y0; is->x[0]=x0;
is->x[1]=x1;is->y[1]=y1; is->x[1]=x1;
is->x[2]=x2;is->y[2]=y2; is->y[0]=y0;
is->x[3]=x3;is->y[3]=y3; is->y[1]=y1;
} }
/* filter decision wrapper */ /* filter decision wrapper */
void compute_iir2(float *x, int n, iir_state *is, void compute_iir2(float *x, int n, iir_state *is,
iir_filter *attack, iir_filter *decay){ iir_filter *attack, iir_filter *decay){
......
...@@ -77,20 +77,14 @@ extern void compute_iir_fast_decay2(float *x, int n, iir_state *is, ...@@ -77,20 +77,14 @@ extern void compute_iir_fast_decay2(float *x, int n, iir_state *is,
iir_filter *attack, iir_filter *decay); iir_filter *attack, iir_filter *decay);
extern void compute_iir_symmetric2(float *x, int n, iir_state *is, extern void compute_iir_symmetric2(float *x, int n, iir_state *is,
iir_filter *filter); 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, extern void compute_iir2(float *x, int n, iir_state *is,
iir_filter *attack, iir_filter *decay); iir_filter *attack, iir_filter *decay);
extern void compute_iir_freefall1(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_freefall2(float *x, int n, iir_state *is,
iir_filter *decay); iir_filter *decay);
extern void compute_iir_decayonly2(float *x, int n, iir_state *is, extern void compute_iir_decayonly2(float *x, int n, iir_state *is,
iir_filter *decay); iir_filter *decay);
extern void compute_iir_freefall3(float *x, int n, iir_state *is,
iir_filter *decay); extern void compute_iir_symmetric_freefall2(float *x, int n, iir_state *is,
extern void compute_iir_freefall4(float *x, int n, iir_state *is, iir_filter *filter);
iir_filter *decay);
...@@ -113,6 +113,27 @@ int suppress_load(void){ ...@@ -113,6 +113,27 @@ int suppress_load(void){
return 0; 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){ static void suppress_work_helper(void *vs, suppress_settings *sset){
suppress_state *sss=(suppress_state *)vs; suppress_state *sss=(suppress_state *)vs;
subband_state *ss=&sss->ss; subband_state *ss=&sss->ss;
...@@ -122,9 +143,10 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){ ...@@ -122,9 +143,10 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){
iir_filter *smooth=&sss->smooth; iir_filter *smooth=&sss->smooth;
iir_filter *release=&sss->release; iir_filter *release=&sss->release;
int ahead; int ahead;
static off_t offset=0;
if(smoothms!=smooth->ms)filter_set(ss,smoothms,smooth,1,2); 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); ahead=impulse_ahead2(smooth->alpha);
...@@ -164,13 +186,14 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){ ...@@ -164,13 +186,14 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){
if(sset->linkp==0 || firstlink==1){ 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); smooth);
compute_iir_fast_attack2(slow, input_size, &sss->iirR[i][j], memcpy(slow,fast,sizeof(slow));
smooth,release); compute_iir_freefall1(slow, input_size, &sss->iirR[i][j],
release);
//_analysis("fast",i,fast,input_size,1,offset); //_analysis("fast",i,fast,input_size,1,offset);
//_analysis("slow",i,slow,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){ ...@@ -221,8 +244,8 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){
} }
sss->prevratio[i]=multiplier; sss->prevratio[i]=multiplier;
} }
offset+=input_size;
} }
static void suppress_work_channel(void *vs){ 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