[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