[xiph-commits] r7913 - trunk/postfish
xiphmont at motherfish-iii.xiph.org
xiphmont at motherfish-iii.xiph.org
Mon Oct 4 23:09:09 PDT 2004
Author: xiphmont
Date: 2004-10-04 23:09:08 -0700 (Mon, 04 Oct 2004)
New Revision: 7913
Modified:
trunk/postfish/bessel.c
trunk/postfish/bessel.h
trunk/postfish/deverb.c
trunk/postfish/deverbpanel.c
trunk/postfish/freq.c
trunk/postfish/limit.c
trunk/postfish/mix.c
trunk/postfish/multicompand.c
trunk/postfish/reverb.c
trunk/postfish/singlecomp.c
trunk/postfish/subband.c
trunk/postfish/version.h
trunk/postfish/window.c
trunk/postfish/window.h
Log:
Farily large bugfixes to the Bessel followers and peak tracking
Modified: trunk/postfish/bessel.c
===================================================================
--- trunk/postfish/bessel.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/bessel.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -183,138 +183,104 @@
return hypot(dc_gain.re,dc_gain.im);
}
-/* assymetrical attack/decay filter computation */
-/* this one is designed for fast attack, slow decay */
-void compute_iir_fast_attack2(float *x, int n, iir_state *is,
- iir_filter *attack, iir_filter *decay){
- double a_c0=attack->c[0],d_c0=decay->c[0];
- double a_c1=attack->c[1],d_c1=decay->c[1];
- double a_g=attack->g, d_g=decay->g;
+/* applies a 2nd order filter (attack) that is decay-limited by a
+ first-order freefall filter (decay) */
+void compute_iir_symmetric_limited(float *x, int n, iir_state *is,
+ iir_filter *attack, iir_filter *limit){
+ double a_c0=attack->c[0],l_c0=limit->c[0];
+ double a_c1=attack->c[1];
+ double a_g=1./attack->g;
double x0=is->x[0],x1=is->x[1];
double y0=is->y[0],y1=is->y[1];
- int state=is->state;
+
int i=0;
- if(zerome(y0) && zerome(y1)){
- y0=y1=0.;
- }
+ if(zerome(y0) && zerome(y1)) y0=y1=0.;
- if(x[0]>y0)state=0;
-
while(i<n){
-
- if(state==0){
- /* attack case */
- while(i<n){
- double ya= (x[i]+x0*2.+x1)/a_g + y0*a_c0+y1*a_c1;
-
- if(x[i]<y0 && ya<y0){
- state=1;
- break;
- }
- x1=x0;x0=x[i];
- y1=y0;x[i]=y0=ya;
- i++;
- }
- }
+ double ya= (x[i]+x0*2.+x1)*a_g + y0*a_c0+y1*a_c1;
+ double yl= y0*l_c0;
+ if(ya<y0 && ya<yl)ya=yl;
+
+ x1=x0;x0=x[i];
+ y1=y0;x[i]=y0=ya;
+ i++;
+ }
+
+ is->x[0]=x0;is->x[1]=x1;
+ is->y[0]=y0;is->y[1]=y1;
+}
- if(state==1){
- /* decay case */
- if(y1<y0){
- /* decay fixup needed because we're in discontinuous time */
- y1=y0;
- }
+/* applies a 2nd order filter (decay) to decay from peak value only,
+ decay limited by a first-order freefall filter (limit) with the
+ same alpha as decay */
+void compute_iir_decay_limited(float *x, int n, iir_state *is,
+ iir_filter *decay, iir_filter *limit){
+ double d_c0=decay->c[0],l_c0=limit->c[0];
+ double d_c1=decay->c[1];
+ double d_g=1./decay->g;
+
+ double x0=is->x[0],x1=is->x[1];
+ double y0=is->y[0],y1=is->y[1];
- while(1){
- double yd = (x[i]+x0*2.+x1)/d_g + y0*d_c0+y1*d_c1;
+ int i=0;
- x1=x0;x0=x[i];
- y1=y0;x[i]=y0=yd;
- i++;
+ if(zerome(y0) && zerome(y1)) y0=y1=0.;
- if(i>=n)break;
- if(x[i]>y0){
- state=0;
- break;
- }
- }
- }
+ while(i<n){
+ double yd= (x[i]+x0*2.+x1)*d_g + y0*d_c0+y1*d_c1;
+ double yl= y0*l_c0;
+ if(yd<yl)yd=yl;
+ if(yd<x[i])y1=y0=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;
- is->state=state;
-
}
-/* this one is designed for fast decay, slow attack */
-void compute_iir_fast_decay2(float *x, int n, iir_state *is,
- iir_filter *attack, iir_filter *decay){
- double a_c0=attack->c[0],d_c0=decay->c[0];
- double a_c1=attack->c[1],d_c1=decay->c[1];
- double a_g=attack->g, d_g=decay->g;
+/* applies a 2nd order filter (attack) that is decay-limited by a
+ first-order filter (decay) */
+void compute_iir_freefall_limited(float *x, int n, iir_state *is,
+ iir_filter *attack, iir_filter *limit){
+ double a_c0=attack->c[0],l_c0=limit->c[0];
+ double a_c1=attack->c[1];
+ double a_g=1./attack->g;
double x0=is->x[0],x1=is->x[1];
double y0=is->y[0],y1=is->y[1];
- int state=is->state;
+
int i=0;
- if(zerome(y0) && zerome(y1)){
- y0=y1=0.;
- }
+ if(zerome(y0) && zerome(y1)) y0=y1=0.;
- if(x[0]<y0)state=1;
-
while(i<n){
-
- if(state==1){
- /* decay case */
- while(i<n){
- double yd= (x[i]+x0*2.+x1)/d_g + y0*d_c0+y1*d_c1;
-
- if(x[i]>y0 && yd>y0){
- state=0;
- break;
- }
- x1=x0;x0=x[i];
- y1=y0;x[i]=y0=yd;
- i++;
- }
- }
+ double ya= (x0*2.+x1)*a_g + y0*a_c0+y1*a_c1;
+ double yl= y0*l_c0;
- if(state==0){
- /* attack case */
- if(y1>y0){
- /* attack fixup needed because we're in discontinuous time */
- y1=y0;
- }
-
- while(1){
- double ya = (x[i]+x0*2.+x1)/a_g + y0*a_c0+y1*a_c1;
-
- x1=x0;x0=x[i];
- y1=y0;x[i]=y0=ya;
- i++;
-
- if(i>=n)break;
- if(x[i]<y0){
- state=1;
- break;
- }
- }
+ if(x[i]<ya){
+ x1=x0;x0=0;
+ }else{
+ ya+= x[i]*a_g;
+ x1=x0;x0=x[i];
}
+
+ if(ya<y0 && ya<yl)ya=yl;
+
+ y1=y0;x[i]=y0=ya;
+ i++;
}
is->x[0]=x0;is->x[1]=x1;
is->y[0]=y0;is->y[1]=y1;
- is->state=state;
-
}
-/* allow decay to proceed in freefall */
-void compute_iir_only_freefall1(float *x, int n, iir_state *is,
- iir_filter *decay){
+void compute_iir_freefallonly1(float *x, int n, iir_state *is,
+ iir_filter *decay){
double d_c0=decay->c[0];
double x0=is->x[0];
@@ -347,123 +313,40 @@
}
-void compute_iir_decayonly2(float *x, int n, iir_state *is,
- iir_filter *decay){
- double d_c0=decay->c[0];
- double d_c1=decay->c[1];
- double d_g=decay->g;
+/* applies a 1st order freefall filter, followed by a 2nd order attack
+ filter */
+void compute_iir_freefall1_then_symmetric2(float *x, int n, iir_state *is,
+ iir_filter *attack,
+ iir_filter *decay){
+ double a_c0=attack->c[0],d_c0=decay->c[0];
+ double a_c1=attack->c[1];
+ double a_g=1./attack->g;
- double x0=is->x[0];
- double x1=is->x[1];
- double y0=is->y[0];
- double y1=is->y[1];
+ double x0=is->x[0],x1=is->x[1];
+ double y0=is->y[0],y1=is->y[1];
+ double yd=is->y[2];
+
int i=0;
- if(zerome(y0) && zerome(y1)){
- y0=y1=0.;
- }
+ if(zerome(y0) && zerome(y1)) y0=y1=0.;
+ if(zerome(yd)) yd=0.;
while(i<n){
- double yd;
-
- if(y1<y0)y1=y0; // slope fixup
-
- yd = (x[i]+x0*2.+x1)/d_g + y0*d_c0+y1*d_c1;
- if(x[i]>yd)yd=x[i];
+ yd*=d_c0;
+ if(yd<x[i])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;
-
-}
-
-/* symmetric filter computation */
-
-void compute_iir_symmetric2(float *x, int n, iir_state *is,
- iir_filter *filter){
- double c0=filter->c[0];
- double c1=filter->c[1];
- double g=filter->g;
-
- double x0=is->x[0];
- double x1=is->x[1];
- double y0=is->y[0];
- double y1=is->y[1];
-
- int i=0;
+ {
+ double ya= (yd+x0*2.+x1)*a_g + y0*a_c0+y1*a_c1;
- if(zerome(y0) && zerome(y1)){
- y0=y1=0.;
- }
-
- while(i<n){
- double yd= (x[i]+x0*2.+x1)/g + y0*c0+y1*c1;
- 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_symmetric_freefall2(float *x, int n, iir_state *is,
- iir_filter *filter){
- double c0=filter->c[0];
- double c1=filter->c[1];
- double g=filter->g;
-
- 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= (x0*2.+x1)/g + y0*c0+y1*c1;
-
- if(x[i]<yd){
- x1=x0;x0=0;
- }else{
- yd+= x[i]/g;
- x1=x0;x0=x[i];
+ x1=x0;x0=yd;
+ y1=y0;x[i]=y0=ya;
}
- y1=y0;x[i]=y0=yd;
i++;
}
-
- 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){
-
- if (attack->alpha > decay->alpha){
- /* fast attack, slow decay */
- compute_iir_fast_attack2(x, n, is, attack, decay);
- }else{
- compute_iir_symmetric2(x, n, is, attack);
- }
+ is->x[0]=x0;is->x[1]=x1;
+ is->y[0]=y0;is->y[1]=y1;
+ is->y[2]=yd;
}
-
Modified: trunk/postfish/bessel.h
===================================================================
--- trunk/postfish/bessel.h 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/bessel.h 2004-10-05 06:09:08 UTC (rev 7913)
@@ -24,7 +24,7 @@
#include "postfish.h"
extern int input_rate;
-#define MAXORDER 4
+#define MAXORDER 2
typedef struct {
double c[MAXORDER];
@@ -66,25 +66,26 @@
typedef struct {
double x[MAXORDER];
- double y[MAXORDER];
- int state;
+ double y[MAXORDER+1];
} iir_state;
extern double mkbessel(double raw_alpha,int order,double *ycoeff);
-extern void compute_iir_fast_attack2(float *x, int n, iir_state *is,
- iir_filter *attack, iir_filter *decay);
-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_iir2(float *x, int n, iir_state *is,
- iir_filter *attack, iir_filter *decay);
-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_symmetric_freefall2(float *x, int n, iir_state *is,
- iir_filter *filter);
+extern void compute_iir_symmetric_limited(float *x, int n, iir_state *is,
+ iir_filter *attack, iir_filter *limit);
+extern void compute_iir_decay_limited(float *x, int n, iir_state *is,
+ iir_filter *decay, iir_filter *limit);
+
+
+extern void compute_iir_freefall_limited(float *x, int n, iir_state *is,
+ iir_filter *attack, iir_filter *limit);
+
+extern void compute_iir_freefallonly1(float *x, int n, iir_state *is,
+ iir_filter *decay);
+
+extern void compute_iir_freefall1_then_symmetric2(float *x, int n,
+ iir_state *is,
+ iir_filter *attack,
+ iir_filter *decay);
Modified: trunk/postfish/deverb.c
===================================================================
--- trunk/postfish/deverb.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/deverb.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -49,6 +49,7 @@
subband_state ss;
iir_filter smooth;
+ iir_filter smoothlimit;
iir_filter release;
iir_state *iirS[deverb_freqs];
@@ -113,28 +114,6 @@
return 0;
}
-#if 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);
-}
-#endif
-
static void deverb_work_helper(void *vs, deverb_settings *sset){
deverb_state *sss=(deverb_state *)vs;
subband_state *ss=&sss->ss;
@@ -142,10 +121,14 @@
float smoothms=sset->smooth*.1;
float releasems=sset->release*.1;
iir_filter *smooth=&sss->smooth;
+ iir_filter *smoothlimit=&sss->smoothlimit;
iir_filter *release=&sss->release;
int ahead;
- if(smoothms!=smooth->ms)filter_set(ss,smoothms,smooth,1,2);
+ if(smoothms!=smooth->ms){
+ filter_set(ss,smoothms,smooth,1,2);
+ filter_set(ss,smoothms,smoothlimit,0,1);
+ }
if(releasems!=release->ms)filter_set(ss,releasems,release,0,1);
ahead=impulse_ahead2(smooth->alpha);
@@ -186,17 +169,14 @@
if(sset->linkp==0 || firstlink==1){
- //memcpy(slow,fast,sizeof(slow));
-
+ compute_iir_freefall_limited(fast, input_size, &sss->iirS[i][j],
+ smooth,smoothlimit);
- compute_iir_symmetric_freefall2(fast, input_size, &sss->iirS[i][j],
- smooth);
memcpy(slow,fast,sizeof(slow));
- compute_iir_only_freefall1(slow, input_size, &sss->iirR[i][j],
- release);
+ compute_iir_freefallonly1(slow, input_size, &sss->iirR[i][j],
+ release);
- //_analysis("fast",i,fast,input_size,1,offset);
- //_analysis("slow",i,slow,input_size,1,offset);
+ //_analysis("fast3",i,fast,input_size,1,offset);
if(multiplier==sss->prevratio[i]){
@@ -214,7 +194,7 @@
}
- //_analysis("adj",i,fast,input_size,1,offset);
+ //_analysis("adj3",i,fast,input_size,1,offset);
if(sset->linkp && firstlink==1){
@@ -245,6 +225,7 @@
sss->prevratio[i]=multiplier;
}
+ //offset+=input_size;
}
static void deverb_work_channel(void *vs){
Modified: trunk/postfish/deverbpanel.c
===================================================================
--- trunk/postfish/deverbpanel.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/deverbpanel.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -219,8 +219,8 @@
multibar_callback(MULTIBAR(slider),timing_change,&ps->timing);
- multibar_thumb_set(MULTIBAR(slider),0,100);
- multibar_thumb_set(MULTIBAR(slider),1,400);
+ multibar_thumb_set(MULTIBAR(slider),100,0);
+ multibar_thumb_set(MULTIBAR(slider),400,1);
gtk_table_attach(GTK_TABLE(table),slider,1,2,1,2,
GTK_FILL|GTK_EXPAND,GTK_EXPAND,5,0);
Modified: trunk/postfish/freq.c
===================================================================
--- trunk/postfish/freq.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/freq.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -27,6 +27,7 @@
#include "feedback.h"
#include "freq.h"
#include "lpc.h"
+#include "window.h"
extern int input_rate;
extern int input_size;
@@ -76,11 +77,7 @@
f->bands=bands;
/* fill in time window */
- f->window=malloc(blocksize*sizeof(*f->window));
- for(i=0;i<blocksize;i++)f->window[i]=sin(M_PIl*i/blocksize);
- for(i=0;i<blocksize;i++)f->window[i]*=f->window[i];
- for(i=0;i<blocksize;i++)f->window[i]=sin(f->window[i]*M_PIl*.5);
- for(i=0;i<blocksize;i++)f->window[i]*=f->window[i];
+ f->window=window_get(3,f->qblocksize);
f->fftwf_buffer = fftwf_malloc(sizeof(*f->fftwf_buffer) *
(f->qblocksize*4+2));
@@ -290,11 +287,9 @@
memset(buffer+qblocksize*3,0,sizeof(*buffer)*qblocksize);
/* window (if nonzero) */
- if(!muted0 || !mutedC){
- buffer+=qblocksize;
- for(i=0;i<qblocksize*2;i++)
- buffer[i] *= window[i]*scale;
- }
+ if(!muted0 || !mutedC)
+ window_apply(buffer+qblocksize,window,scale,qblocksize);
+
}
static void freq_work(freq_class_setup *fc,
@@ -307,12 +302,14 @@
int i,j,ch=f->out.channels;
int have_feedback=0;
-
+ u_int32_t outactive=0;
+
f->cache_samples+=in->samples;
for(i=0;i<ch;i++){
int mutedC=mute_channel_muted(in->active,i);
int muted0=mute_channel_muted(f->mutemask0,i);
+ int muted1=mute_channel_muted(f->mutemask1,i);
int activeC=active[i] && !(muted0 && mutedC);
int active0=f->active0[i];
@@ -386,9 +383,11 @@
float *temp=out->data[i];
out->data[i]=f->cache1[i];
f->cache1[i]=temp;
+
+ outactive|= (f->mutemask1 & (1<<i));
}
}else{
- float *w2=fc->window+input_size;
+ float *w2=fc->window;
float *l0=f->lap0[i];
float *l1=f->lap1[i];
float *lC=f->lapC[i];
@@ -400,8 +399,10 @@
float *tC=t0+input_size;
float *tN=tC+input_size;
+ outactive|= (1<<i);
+
if(!trans_active){
- /* lap the cache into the trasform vector */
+ /* lap the cache into the transform vector */
fill_freq_buffer_helper(fc->fftwf_buffer,
fc->window,
f->cache0[i],in->data[i],
@@ -411,10 +412,15 @@
if(!activeP && !active1 && !active0){
/* previously in a bypassed/inactive state; the lapping cache
will need to be re-prepared */
-
- memcpy(l1,c1,sizeof(*l1)*input_size);
- for(j=0;j<input_size;j++)
- l0[j]= c0[j]*w2[j];
+ if(muted1)
+ memset(l1,0,sizeof(*l1)*input_size);
+ else
+ memcpy(l1,c1,sizeof(*l1)*input_size);
+ if(muted0)
+ memset(l0,0,sizeof(*l0)*input_size);
+ else
+ for(j=0;j<input_size;j++)
+ l0[j]= c0[j]*w2[input_size-j];
memset(lC,0,sizeof(*lC)*input_size);
}
@@ -478,7 +484,7 @@
/* complete output linkage */
if(out){
- out->active=f->mutemask1;
+ out->active=outactive;
f->out.samples=(f->cache_samples>input_size?input_size:f->cache_samples);
f->cache_samples-=f->out.samples;
}
Modified: trunk/postfish/limit.c
===================================================================
--- trunk/postfish/limit.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/limit.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -25,6 +25,7 @@
#include "feedback.h"
#include "bessel.h"
#include "limit.h"
+#include "window.h"
extern int input_size;
extern int input_rate;
@@ -38,6 +39,7 @@
iir_state *iir;
iir_filter decay;
+ iir_filter limit;
int prev_active;
int initted;
@@ -48,7 +50,7 @@
limit_settings limitset;
limit_state limitstate;
-float *window;
+static float *window;
/* feedback! */
typedef struct limit_feedback{
@@ -87,22 +89,19 @@
for(i=0;i<ch;i++)
limitstate.out.data[i]=malloc(input_size*sizeof(**limitstate.out.data));
- window=malloc(input_size*sizeof(*window));
- for(i=0;i<input_size;i++){
- window[i]=sin((i+.5)/input_size*M_PI*.5);
- window[i]*=window[i];
- }
+ window=window_get(1,input_size);
return(0);
}
static void filter_set(float msec,
+ int order,
iir_filter *filter){
float alpha;
float corner_freq= 500./msec;
alpha=corner_freq/input_rate;
- filter->g=mkbessel(alpha,2,filter->c);
+ filter->g=mkbessel(alpha,order,filter->c);
filter->alpha=alpha;
filter->Hz=alpha*input_rate;
filter->ms=msec;
@@ -141,7 +140,10 @@
float localatt;
float decayms=limitset.decay*.1;
- if(decayms!=limitstate.decay.ms)filter_set(decayms,&limitstate.decay);
+ if(decayms!=limitstate.decay.ms){
+ filter_set(decayms,2,&limitstate.decay);
+ filter_set(decayms,1,&limitstate.limit);
+ }
if(in->samples==0){
limitstate.out.samples=0;
@@ -191,9 +193,9 @@
prev_thresh+=thresh_add;
}
- compute_iir_decayonly2(x,input_size,limitstate.iir+i,&limitstate.decay);
+ compute_iir_decay_limited(x,input_size,limitstate.iir+i,
+ &limitstate.decay,&limitstate.limit);
-
for(k=0;k<in->samples;k++)
x[k]=inx[k]*fromdB(-x[k]);
Modified: trunk/postfish/mix.c
===================================================================
--- trunk/postfish/mix.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/mix.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -24,6 +24,7 @@
#include "postfish.h"
#include "feedback.h"
#include "mix.h"
+#include "window.h"
extern int input_ch;
extern int input_size;
@@ -58,7 +59,7 @@
mix_state ms;
/* this should be moved somewhere obvious/generic */
-float *frame_window;
+static float *window;
/* feedback! */
typedef struct limit_feedback{
@@ -131,11 +132,7 @@
for(i=0;i<outch;i++)
ms.out.data[i]=malloc(input_size*sizeof(**ms.out.data));
- frame_window=malloc(input_size*sizeof(*frame_window));
- for(i=0;i<input_size;i++){
- frame_window[i]= sin( (i+.5)/input_size*M_PI*.5 );
- frame_window[i]*=frame_window[i];
- }
+ window=window_get(1,input_size);
return 0;
}
@@ -182,20 +179,20 @@
/* current settings */
i=input_size*2+del;
while(i<input_size && offset<input_size){
- out[offset]+=cachePP[i++]*att*frame_window[offset];
+ out[offset]+=cachePP[i++]*att*window[offset];
offset++;
}
i=input_size+del;
if(i<0)i=0;
while(i<input_size && offset<input_size){
- out[offset]+=cacheP[i++]*att*frame_window[offset];
+ out[offset]+=cacheP[i++]*att*window[offset];
offset++;
}
i=0;
while(offset<input_size){
- out[offset]+=data[i++]*att*frame_window[offset];
+ out[offset]+=data[i++]*att*window[offset];
offset++;
}
@@ -203,20 +200,20 @@
offset=0;
i=input_size*2+delP;
while(i<input_size && offset<input_size){
- out[offset]+=cachePP[i++]*attP*frame_window[input_size-offset-1];
+ out[offset]+=cachePP[i++]*attP*window[input_size-offset-1];
offset++;
}
i=input_size+delP;
if(i<0)i=0;
while(i<input_size && offset<input_size){
- out[offset]+=cacheP[i++]*attP*frame_window[input_size-offset-1];
+ out[offset]+=cacheP[i++]*attP*window[input_size-offset-1];
offset++;
}
i=0;
while(offset<input_size){
- out[offset]+=data[i++]*attP*frame_window[input_size-offset-1];
+ out[offset]+=data[i++]*attP*window[input_size-offset-1];
offset++;
}
}
@@ -231,15 +228,7 @@
out[i]+=in[i];
return;
}
- if(active){
- /* transitioning to active */
- for(i=0;i<input_size;i++)
- out[i]+=in[i]*frame_window[i];
- return;
- }
- /* transitioning to inactive */
- for(i=0;i<input_size;i++)
- out[i]+=in[i]*frame_window[input_size-i-1];
+ /* mutes no longer need be transitioned */
}
/* called only by playback thread */
Modified: trunk/postfish/multicompand.c
===================================================================
--- trunk/postfish/multicompand.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/multicompand.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -203,18 +203,30 @@
return 0;
}
-static void filter_set(multicompand_state *ms,
+static void filter_set1(multicompand_state *ms,
float msec,
- iir_filter *filter,
- int attackp){
+ iir_filter *filter){
float alpha;
float corner_freq= 500./msec;
+ alpha=corner_freq/input_rate;
+ filter->g=mkbessel(alpha,1,filter->c);
+ filter->alpha=alpha;
+ filter->Hz=alpha*input_rate;
+
+}
+
+static void filter_set2(multicompand_state *ms,
+ float msec,
+ iir_filter *filter){
+ float alpha;
+ float corner_freq= 500./msec;
+
/* make sure the chosen frequency doesn't require a lookahead
greater than what's available */
- if(step_freq(input_size*2-ms->ss.qblocksize*3)*1.01>corner_freq && attackp)
+ if(step_freq(input_size*2-ms->ss.qblocksize*3)*1.01>corner_freq)
corner_freq=step_freq(input_size*2-ms->ss.qblocksize*3);
-
+
alpha=corner_freq/input_rate;
filter->g=mkbessel(alpha,2,filter->c);
filter->alpha=alpha;
@@ -222,16 +234,24 @@
}
-static void filterbank_set(multicompand_state *ms,
+static void filterbank_set1(multicompand_state *ms,
float msec,
- iir_filter *filter,
- int attackp){
+ iir_filter *filter){
int i;
for(i=0;i<ms->ch;i++)
- filter_set(ms,msec,filter+i,attackp);
+ filter_set1(ms,msec,filter+i);
}
+static void filterbank_set2(multicompand_state *ms,
+ float msec,
+ iir_filter *filter){
+ int i;
+ for(i=0;i<ms->ch;i++)
+ filter_set2(ms,msec,filter+i);
+
+}
+
static void prepare_rms(float *rms, float *xx, int n, int ahead){
int i;
float *x=xx+ahead;
@@ -239,8 +259,8 @@
rms[i]+=x[i]*x[i];
}
-static void prepare_peak(float *peak, float *x, int n, int ahead,int hold,
- peak_state *ps){
+static void prepare_peak(float *peak, float *x, int n, int ahead,
+ peak_state *ps){
int ii,jj;
int loc=ps->loc;
float val=ps->val;
@@ -248,37 +268,37 @@
/* Although we have two input_size blocks of zeroes after a
reset, we may still need to look ahead explicitly after a
reset if the lookahead is exceptionally long */
+
if(loc==0 && val==0){
for(ii=0;ii<ahead;ii++)
if((x[ii]*x[ii])>val){
- val=(x[ii]*x[ii]);
- loc=ii+hold;
+ val=(x[ii]*x[ii]);
+ loc=ii;
}
}
if(val>peak[0])peak[0]=val;
-
+
for(ii=1;ii<n;ii++){
if((x[ii+ahead]*x[ii+ahead])>val){
val=(x[ii+ahead]*x[ii+ahead]);
- loc=ii+ahead+hold;
- }
+ loc=ii+ahead;
+ }
if(ii>=loc){
/* backfill */
val=0;
for(jj=ii+ahead-1;jj>=ii;jj--){
- if((x[jj]*x[jj])>val)val=(x[jj]*x[jj]);
- if(jj<n && val>peak[jj])peak[jj]=val;
+ if((x[jj]*x[jj])>val)val=(x[jj]*x[jj]);
+ if(jj<n && val>peak[jj])peak[jj]=val;
}
- val=(x[ii+ahead-1]*x[ii+ahead-1]);
- loc=ii+ahead+hold;
+ val=(x[ii+ahead]*x[ii+ahead]);
+ loc=ii+ahead;
}
if(val>peak[ii])peak[ii]=val;
}
ps->loc=loc-input_size;
ps->val=val;
-
}
static void run_filter(float *dB,float *x,int n,
@@ -288,16 +308,21 @@
int i;
memset(dB,0,sizeof(*dB)*n);
- if(mode)
- prepare_peak(dB, x, n,
- step_ahead(attack->alpha)*lookahead,
- step_ahead(attack->alpha)*(1.-lookahead),
- ps);
- else
- prepare_rms(dB, x, n, impulse_ahead2(attack->alpha)*lookahead);
+ if(mode){
+ int ahead=step_ahead(attack->alpha)*lookahead;
+ if(ahead>input_size*2)ahead=input_size*2;
+
+ prepare_peak(dB, x, n, ahead, ps);
+ compute_iir_freefall1_then_symmetric2(dB, n, iir, attack, decay);
- compute_iir2(dB, n, iir, attack, decay);
-
+ }else{
+ int ahead=impulse_ahead2(attack->alpha)*lookahead;
+ if(ahead>input_size*2)ahead=input_size*2;
+ prepare_rms(dB, x, n, ahead);
+ compute_iir_symmetric_limited(dB, n, iir, attack, decay);
+
+ }
+
for(i=0;i<n;i++)
dB[i]=todB_a(dB+i)*.5f;
@@ -709,17 +734,17 @@
float b_decayms=multi_master_set.base_decay*.1;
if(o_attackms!=ms->over_attack[0].ms)
- filterbank_set(ms,o_attackms,ms->over_attack,1);
+ filterbank_set2(ms,o_attackms,ms->over_attack);
if(o_decayms !=ms->over_decay[0].ms)
- filterbank_set(ms,o_decayms,ms->over_decay,0);
+ filterbank_set1(ms,o_decayms,ms->over_decay);
if(u_attackms!=ms->under_attack[0].ms)
- filterbank_set(ms,u_attackms,ms->under_attack,1);
+ filterbank_set2(ms,u_attackms,ms->under_attack);
if(u_decayms !=ms->under_decay[0].ms)
- filterbank_set(ms,u_decayms,ms->under_decay,0);
+ filterbank_set1(ms,u_decayms,ms->under_decay);
if(b_attackms!=ms->base_attack[0].ms)
- filterbank_set(ms,b_attackms,ms->base_attack,1);
+ filterbank_set2(ms,b_attackms,ms->base_attack);
if(b_decayms !=ms->base_decay[0].ms)
- filterbank_set(ms,b_decayms,ms->base_decay,0);
+ filterbank_set1(ms,b_decayms,ms->base_decay);
}
return subband_read(in, &master_state.ss, w, visible,active,
@@ -744,17 +769,17 @@
float b_decayms=multi_channel_set[i].base_decay*.1;
if(o_attackms!=ms->over_attack[i].ms)
- filter_set(ms,o_attackms,ms->over_attack+i,1);
+ filter_set2(ms,o_attackms,ms->over_attack+i);
if(o_decayms !=ms->over_decay[i].ms)
- filter_set(ms,o_decayms,ms->over_decay+i,0);
+ filter_set1(ms,o_decayms,ms->over_decay+i);
if(u_attackms!=ms->under_attack[i].ms)
- filter_set(ms,u_attackms,ms->under_attack+i,1);
+ filter_set2(ms,u_attackms,ms->under_attack+i);
if(u_decayms !=ms->under_decay[i].ms)
- filter_set(ms,u_decayms,ms->under_decay+i,0);
+ filter_set1(ms,u_decayms,ms->under_decay+i);
if(b_attackms!=ms->base_attack[i].ms)
- filter_set(ms,b_attackms,ms->base_attack+i,1);
+ filter_set2(ms,b_attackms,ms->base_attack+i);
if(b_decayms !=ms->base_decay[i].ms)
- filter_set(ms,b_decayms,ms->base_decay+i,0);
+ filter_set1(ms,b_decayms,ms->base_decay+i);
w[i]=&sw[multi_channel_set[i].active_bank];
visible[i]=multi_channel_set[i].panel_visible;
Modified: trunk/postfish/reverb.c
===================================================================
--- trunk/postfish/reverb.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/reverb.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -48,6 +48,7 @@
#include "postfish.h"
#include "reverb.h"
+#include "window.h"
typedef struct {
int size;
@@ -84,7 +85,7 @@
extern int input_size;
extern int input_ch;
-extern float *frame_window;
+float *window;
plate_set *plate_channel_set;
plate_set plate_master_set;
@@ -177,16 +178,16 @@
float *out0, float *out1, int i){
float tmp;
- *out0 = wg->buffer[0][wg->dptr]*(1.-frame_window[i]) +
- wg->buffer[0][wg->dptr_pending]*frame_window[i];
+ *out0 = wg->buffer[0][wg->dptr]*(1.-window[i]) +
+ wg->buffer[0][wg->dptr_pending]*window[i];
*out0 = wg->lp[0] * (wg->fc - 1.0f) + wg->fc * *out0;
wg->lp[0] = *out0;
tmp = *out0 * -(wg->a1a) + wg->zm1[0];
wg->zm1[0] = tmp * wg->a1a + *out0;
*out0 = tmp;
- *out1 = wg->buffer[1][wg->dptr]*(1.-frame_window[i]) +
- wg->buffer[1][wg->dptr_pending]*frame_window[i];
+ *out1 = wg->buffer[1][wg->dptr]*(1.-window[i]) +
+ wg->buffer[1][wg->dptr_pending]*window[i];
*out1 = wg->lp[1] * (wg->fc - 1.0f) + wg->fc * *out1;
wg->lp[1] = *out1;
tmp = *out1 * -(wg->a1a) + wg->zm1[1];
@@ -271,6 +272,8 @@
channel.prevactive=calloc(input_ch,sizeof(*channel.prevactive));
master.prevactive=calloc(1,sizeof(*master.prevactive));
+
+ window=window_get(1,input_size);
return 0;
}
@@ -407,12 +410,12 @@
if(!active[i]){
/* transition to inactive */
for(j=0;j<input_size;j++)
- x[j] *= (1.f - frame_window[j]);
+ x[j] *= (1.f - window[j]);
}else if (!ps->prevactive[i] || !ps->fillstate){
/* transition to active */
for(j=0;j<input_size;j++)
- x[j]*= frame_window[j];
+ x[j]*= window[j];
}
}else{
ps->out.data[i]=x;
@@ -428,8 +431,8 @@
if(!active[i]){
/* transition to inactive */
for(j=0;j<input_size;j++){
- yA[j] *= (1.f - frame_window[j]);
- yB[j] *= (1.f - frame_window[j]);
+ yA[j] *= (1.f - window[j]);
+ yB[j] *= (1.f - window[j]);
}
}
@@ -493,12 +496,12 @@
if(!active){
/* transition to inactive */
for(j=0;j<input_size;j++)
- y[j] *= (1.f - frame_window[j]);
+ y[j] *= (1.f - window[j]);
}else if (!ps->prevactive[0] || !ps->fillstate){
/* transition to active */
for(j=0;j<input_size;j++)
- y[j]*= frame_window[j];
+ y[j]*= window[j];
}
plate_compute(&plate_master_set, &ps->plates[i],
@@ -508,7 +511,7 @@
if(!active){
/* transition to inactive */
for(j=0;j<input_size;j++)
- y[j]*= 1.f - frame_window[j];
+ y[j]*= 1.f - window[j];
}
if(!mute_channel_muted(in->active,i))
Modified: trunk/postfish/singlecomp.c
===================================================================
--- trunk/postfish/singlecomp.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/singlecomp.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -181,18 +181,19 @@
}
static void filter_set(float msec,
- iir_filter *filter,
- int attackp){
+ int order,
+ int attackp,
+ iir_filter *filter){
float alpha;
float corner_freq= 500./msec;
/* make sure the chosen frequency doesn't require a lookahead
greater than what's available */
- if(step_freq(input_size)*1.01>corner_freq && attackp)
+ if(step_freq(input_size)*1.01>corner_freq && attackp && order==2)
corner_freq=step_freq(input_size);
alpha=corner_freq/input_rate;
- filter->g=mkbessel(alpha,2,filter->c);
+ filter->g=mkbessel(alpha,order,filter->c);
filter->alpha=alpha;
filter->Hz=alpha*input_rate;
filter->ms=msec;
@@ -229,7 +230,7 @@
return 0;
}
-static void prepare_peak(float *peak, float *x, int n, int ahead,int hold,
+static void prepare_peak(float *peak, float *x, int n, int ahead,
peak_state *ps){
int ii,jj;
int loc=ps->loc;
@@ -243,16 +244,16 @@
for(ii=0;ii<ahead;ii++)
if((x[ii]*x[ii])>val){
val=(x[ii]*x[ii]);
- loc=ii+hold;
+ loc=ii;
}
}
if(val>peak[0])peak[0]=val;
-
+
for(ii=1;ii<n;ii++){
if((x[ii+ahead]*x[ii+ahead])>val){
val=(x[ii+ahead]*x[ii+ahead]);
- loc=ii+ahead+hold;
+ loc=ii+ahead;
}
if(ii>=loc){
/* backfill */
@@ -261,8 +262,8 @@
if((x[jj]*x[jj])>val)val=(x[jj]*x[jj]);
if(jj<n && val>peak[jj])peak[jj]=val;
}
- val=(x[ii+ahead-1]*x[ii+ahead-1]);
- loc=ii+ahead+hold;
+ val=(x[ii+ahead]*x[ii+ahead]);
+ loc=ii+ahead;
}
if(val>peak[ii])peak[ii]=val;
}
@@ -271,20 +272,50 @@
ps->val=val;
}
+#if 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 int seq=0;
+static int offch;
+#endif
+
static void run_filter(float *cache, float *in, float *work,
- int ahead,int hold,int mode,
- iir_state *iir,iir_filter *attack,iir_filter *decay,
+ int ahead,int mode,
+ iir_state *iir,
+ iir_filter *attack,
+ iir_filter *decay,
peak_state *ps){
int k;
- float *work2=work+input_size;
if(mode){
/* peak mode */
- memcpy(work,cache,sizeof(*work)*input_size);
- memcpy(work2,in,sizeof(*work)*input_size);
-
- prepare_peak(work, work, input_size, ahead, hold, ps);
-
+ float bigcache[input_size*2];
+ memcpy(bigcache,cache,sizeof(*work)*input_size);
+ memcpy(bigcache+input_size,in,sizeof(*work)*input_size);
+
+ memset(work,0,sizeof(*work)*input_size);
+ prepare_peak(work, bigcache, input_size, ahead, ps);
+
+ compute_iir_freefall1_then_symmetric2(work, input_size, iir, attack, decay);
+
}else{
/* rms mode */
float *cachea=cache+ahead;
@@ -295,10 +326,11 @@
for(k=0;k<ahead;k++)
worka[k]=in[k]*in[k];
+
+ compute_iir_symmetric_limited(work, input_size, iir, attack, decay);
+
}
-
- compute_iir2(work, input_size, iir, attack, decay);
-
+
for(k=0;k<input_size;k++)
work[k]=todB_a(work+k)*.5f;
}
@@ -323,11 +355,10 @@
int k;
float work[input_size*2];
- int ahead=(mode?step_ahead(attack->alpha):impulse_ahead2(attack->alpha));
- int hold=(1.-lookahead)*ahead;
- ahead-=hold;
+ int ahead=(mode?step_ahead(attack->alpha):impulse_ahead2(attack->alpha))*lookahead;
+ if(ahead>input_size)ahead=input_size;
- run_filter(A,B,work,ahead,hold,mode,iir,attack,decay,ps);
+ run_filter(A,B,work,ahead,mode,iir,attack,decay,ps);
if(active){
if(multiplier!=currmultiplier || zerocorner!=currcorner){
@@ -369,11 +400,10 @@
int active){
int k;
float work[input_size*2];
- int ahead=(mode?step_ahead(attack->alpha):impulse_ahead2(attack->alpha));
- int hold=(1.-lookahead)*ahead;
- ahead-=hold;
+ int ahead=(mode?step_ahead(attack->alpha):impulse_ahead2(attack->alpha))*lookahead;
+ if(ahead>input_size)ahead=input_size;
- run_filter(A,B,work,ahead,hold,mode,iir,attack,decay,ps);
+ run_filter(A,B,work,ahead,mode,iir,attack,decay,ps);
if(active){
if(multiplier!=currmultiplier || zerocorner!=currcorner){
@@ -417,11 +447,10 @@
int k;
float work[input_size*2];
-
int ahead=(mode?step_ahead(attack->alpha):impulse_ahead2(attack->alpha));
- run_filter(A,B,work,ahead,0,mode,iir,attack,decay,ps);
-
+ run_filter(A,B,work,ahead,mode,iir,attack,decay,ps);
+
if(active){
if(multiplier!=currmultiplier){
float multiplier_add=(currmultiplier-multiplier)/input_size;
@@ -470,12 +499,12 @@
float b_attackms=scset[i]->b_attack*.1;
float b_decayms=scset[i]->b_decay*.1;
- if(o_attackms!=scs->o_attack[i].ms)filter_set(o_attackms,&scs->o_attack[i],1);
- if(o_decayms!=scs->o_decay[i].ms)filter_set(o_decayms,&scs->o_decay[i],0);
- if(u_attackms!=scs->u_attack[i].ms)filter_set(u_attackms,&scs->u_attack[i],1);
- if(u_decayms!=scs->u_decay[i].ms)filter_set(u_decayms,&scs->u_decay[i],0);
- if(b_attackms!=scs->b_attack[i].ms)filter_set(b_attackms,&scs->b_attack[i],1);
- if(b_decayms!=scs->b_decay[i].ms)filter_set(b_decayms,&scs->b_decay[i],0);
+ if(o_attackms!=scs->o_attack[i].ms)filter_set(o_attackms,2,1,&scs->o_attack[i]);
+ if(o_decayms!=scs->o_decay[i].ms)filter_set(o_decayms,1,0,&scs->o_decay[i]);
+ if(u_attackms!=scs->u_attack[i].ms)filter_set(u_attackms,2,1,&scs->u_attack[i]);
+ if(u_decayms!=scs->u_decay[i].ms)filter_set(u_decayms,1,0,&scs->u_decay[i]);
+ if(b_attackms!=scs->b_attack[i].ms)filter_set(b_attackms,2,1,&scs->b_attack[i]);
+ if(b_decayms!=scs->b_decay[i].ms)filter_set(b_decayms,1,0,&scs->b_decay[i]);
if(!active0 && !activeC){
@@ -548,7 +577,7 @@
scs->o_attack+i,scs->o_decay+i,
scs->o_iir+i,scs->o_peak+i,
active0);
-
+
/* feedback before base */
if(scset[i]->panel_visible){
int k;
@@ -572,7 +601,7 @@
rms/=input_size;
rmsfeed[i]=todB_a(&rms)*.5;
}
-
+
base_compand(scs->cache[i],in->data[i],adj,
1.-1000./scs->prevset[i].b_ratio,
1.-1000./scs->currset[i].b_ratio,
@@ -627,6 +656,7 @@
}
+
if(out){
/* feedback is also triggered off of output */
singlecomp_feedback *ff=
@@ -652,7 +682,7 @@
scs->prevset=scs->currset;
scs->currset=temp;
}
-
+
scs->cache_samples=in->samples;
scs->mutemaskP=mutemask0;
scs->mutemask0=mutemaskC;
@@ -730,6 +760,6 @@
/* local copy required to avoid concurrency problems */
for(i=0;i<channel_state.ch;i++)
active[i]=singlecomp_channel_set[i].panel_active;
-
+
return singlecomp_read_helper(in, &channel_state, channel_set_bundle,active);
}
Modified: trunk/postfish/subband.c
===================================================================
--- trunk/postfish/subband.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/subband.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -293,21 +293,9 @@
break;
}
-
/* window; assume the edges are already zeroed */
- {
- float scale=.25/f->qblocksize;
- float *workoff2=workoff+f->qblocksize*2;
- /* odd-symmetry window */
- workoff[0]*=f->window[0]*scale;
- for(k=1;k<f->qblocksize;k++){
- float w=f->window[k]*scale;
- workoff[k]*=w;
- *(--workoff2)*=w;
- }
- workoff[k]*=f->window[k]*scale;
- }
-
+ window_apply(workoff,f->window,.25/f->qblocksize,f->qblocksize);
+
fftwf_execute(f->fftwf_forward);
/* repeatedly filter and transform back */
Modified: trunk/postfish/version.h
===================================================================
--- trunk/postfish/version.h 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/version.h 2004-10-05 06:09:08 UTC (rev 7913)
@@ -1,2 +1,2 @@
#define VERSION "$Id$ "
-/* DO NOT EDIT: Automated versioning hack [Tue Sep 28 01:07:54 EDT 2004] */
+/* DO NOT EDIT: Automated versioning hack [Tue Oct 5 01:45:38 EDT 2004] */
Modified: trunk/postfish/window.c
===================================================================
--- trunk/postfish/window.c 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/window.c 2004-10-05 06:09:08 UTC (rev 7913)
@@ -79,3 +79,16 @@
pthread_mutex_unlock(&window_mutex);
return window_func[type][bits];
}
+
+void window_apply(float *data, float *window, float scale, int halfn){
+ float *data2=data+halfn*2;
+ int i;
+
+ *(data++) *= window[0]*scale;
+ for(i=1;i<halfn;i++){
+ float val=window[i]*scale;
+ *(data++) *= val;
+ *(--data2)*= val;
+ }
+ *(data++) *= window[i]*scale;
+}
Modified: trunk/postfish/window.h
===================================================================
--- trunk/postfish/window.h 2004-10-05 00:25:10 UTC (rev 7912)
+++ trunk/postfish/window.h 2004-10-05 06:09:08 UTC (rev 7913)
@@ -22,3 +22,4 @@
*/
extern float *window_get(int type,int n);
+extern void window_apply(float *data, float *window, float scale, int halfn);
More information about the commits
mailing list