[xiph-cvs] cvs commit: postfish Makefile clippanel.c compandpanel.c compandpanel.h eq.c eqpanel.c freq.c freq.h mainpanel.c multibar.c multicompand.c multicompand.h postfish-gtkrc subpanel.c subpanel.h version.h

Monty xiphmont at xiph.org
Sun Mar 7 18:08:24 PST 2004



xiphmont    04/03/07 21:08:24

  Modified:    .        Makefile clippanel.c compandpanel.c compandpanel.h
                        eq.c eqpanel.c freq.c freq.h mainpanel.c multibar.c
                        multicompand.c multicompand.h postfish-gtkrc
                        subpanel.c subpanel.h version.h
  Log:
  Actually commit some of the compander tinkering.

Revision  Changes    Path
1.15      +18 -6     postfish/Makefile

Index: Makefile
===================================================================
RCS file: /usr/local/cvsroot/postfish/Makefile,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- Makefile	29 Feb 2004 03:16:17 -0000	1.14
+++ Makefile	8 Mar 2004 02:08:23 -0000	1.15
@@ -10,6 +10,16 @@
 ETCDIR=/etc
 MANDIR=$PREFIX/man
 
+# is this a platform that uses IEEE 754/854 32 bit floats?  The
+# following is good for a speedup on most of these systems, otherwise
+# comment it out.  Using this define on a system where a 'float' is
+# *not* an IEEE 32 bit float will destroy, destroy, destroy the audio.
+
+IEEE=-DNASTY_IEEE_FLOAT32_HACK_IS_FASTER_THAN_LOG=1
+
+
+
+
 SRC = main.c mainpanel.c multibar.c readout.c input.c output.c clippanel.c \
         declip.c reconstruct.c multicompand.c windowbutton.c subpanel.c \
         feedback.c freq.c eq.c eqpanel.c compandpanel.c subband.c lpc.c
@@ -19,25 +29,27 @@
 GCF = `pkg-config --cflags gtk+-2.0` -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED
 
 all:	
-	$(MAKE) target CFLAGS="-W -O3 -ffast-math $(GCF)"
+	$(MAKE) target CFLAGS="-W -O3 -ffast-math $(GCF) $(IEEE)"
 
 debug:
-	$(MAKE) target CFLAGS="-g -W -D__NO_MATH_INLINES $(GCF)"
+	$(MAKE) target CFLAGS="-g -W -D__NO_MATH_INLINES $(GCF) $(IEEE)"
 
 profile:
-	$(MAKE) target CFLAGS="-W -pg -g -O3 $(GCF)"
+	$(MAKE) target CFLAGS="-W -pg -g -O3 -ffast-math $(GCF) $(IEEE)" LIBS="-lgprof-helper"
 
 clean:
-	rm -f $(OBJ) *.d 
+	rm -f $(OBJ) *.d gmon.out
 
 %.d: %.c
         $(CC) -M $(GCF) $< > $@.$$$$; sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; rm -f $@.$$$$
 
+ifneq ($(MAKECMDGOALS),clean)
 include $(SRC:.c=.d)
+endif
 
-target: $(OBJ)
+target: $(OBJ) 
         ./touch-version
-	$(LD) $(OBJ) $(CFLAGS) -o postfish `pkg-config --libs gtk+-2.0` -lpthread -lfftw3f -lm
+	$(LD) $(OBJ) $(CFLAGS) -o postfish $(LIBS) `pkg-config --libs gtk+-2.0` -lpthread -lfftw3f -lm
 
 install:
         $(INSTALL) -d -m 0755 $(BINDIR)

<p><p>1.15      +1 -1      postfish/clippanel.c

Index: clippanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/clippanel.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- clippanel.c	29 Feb 2004 03:16:17 -0000	1.14
+++ clippanel.c	8 Mar 2004 02:08:23 -0000	1.15
@@ -313,7 +313,7 @@
 
 
   mainpanel_inbar=mp->inbar;
-
+  subpanel_show_all_but_toplevel(panel);
 }
 
 void clippanel_feedback(int displayit){

<p><p>1.5       +460 -230  postfish/compandpanel.c

Index: compandpanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/compandpanel.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- compandpanel.c	29 Feb 2004 03:16:17 -0000	1.4
+++ compandpanel.c	8 Mar 2004 02:08:23 -0000	1.5
@@ -38,9 +38,11 @@
 extern int input_size;
 extern int input_rate;
 
-extern compand_settings c;
+extern banked_compand_settings bc[multicomp_banks];
+extern other_compand_settings c;
 
 typedef struct {
+  GtkWidget *label;
   GtkWidget *slider;
   GtkWidget *readoutg;
   GtkWidget *readoute;
@@ -48,7 +50,152 @@
   int number;
 } cbar;
 
-static cbar bars[multicomp_freqs];
+static int bank_active=2;
+static cbar bars[multicomp_freqs_max];
+static int inactive_updatep=1;
+
+static void slider_change(GtkWidget *w,gpointer in){
+  char buffer[80];
+  cbar *b=(cbar *)in;
+  float g,e,c;
+
+  g=multibar_get_value(MULTIBAR(b->slider),0);
+  sprintf(buffer,"%3.0f",g);
+  readout_set(READOUT(b->readoutg),buffer);
+  g=rint(g*10.);
+  bc[bank_active].static_g[b->number]=g;
+  
+  e=multibar_get_value(MULTIBAR(b->slider),1);
+  sprintf(buffer,"%+4.0f",e);
+  readout_set(READOUT(b->readoute),buffer);
+  e=rint(e*10.);
+  bc[bank_active].static_e[b->number]=e;
+
+  c=multibar_get_value(MULTIBAR(b->slider),2);
+  sprintf(buffer,"%+4.0f",c);
+  readout_set(READOUT(b->readoutc),buffer);
+  c=rint(c*10.);
+  bc[bank_active].static_c[b->number]=c;
+  
+  if(inactive_updatep){
+    /* keep the inactive banks also tracking settings, but only where it
+       makes sense */
+    
+    switch(bank_active){
+    case 0:
+      bc[1].static_g[b->number*2]=g;
+      bc[1].static_e[b->number*2]=e;
+      bc[1].static_c[b->number*2]=c;
+      bc[2].static_g[b->number*3+1]=g;
+      bc[2].static_e[b->number*3+1]=e;
+      bc[2].static_c[b->number*3+1]=c;
+      break;
+    case 1:
+      if((b->number&1)==0){
+	bc[0].static_g[b->number>>1]=g;
+	bc[0].static_e[b->number>>1]=e;
+	bc[0].static_c[b->number>>1]=c;
+	bc[2].static_g[b->number/2*3+1]=g;
+	bc[2].static_e[b->number/2*3+1]=e;
+	bc[2].static_c[b->number/2*3+1]=c;
+      }else{
+	if(b->number<19){
+	  float val=(bc[2].static_g[b->number/2*3+2]+
+		     bc[2].static_g[b->number/2*3+3])*.5;
+	  bc[2].static_g[b->number/2*3+2]+=(g-val);
+	  bc[2].static_g[b->number/2*3+3]+=(g-val);
+	  
+	  val=(bc[2].static_e[b->number/2*3+2]+
+	       bc[2].static_e[b->number/2*3+3])*.5;
+	  bc[2].static_e[b->number/2*3+2]+=(e-val);
+	  bc[2].static_e[b->number/2*3+3]+=(e-val);
+	  
+	  val=(bc[2].static_c[b->number/2*3+2]+
+	       bc[2].static_c[b->number/2*3+3])*.5;
+	  bc[2].static_c[b->number/2*3+2]+=(c-val);
+	  bc[2].static_c[b->number/2*3+3]+=(c-val);
+	}else{
+	  bc[2].static_g[b->number/2*3+2]=g;
+	  bc[2].static_e[b->number/2*3+2]=e;
+	  bc[2].static_c[b->number/2*3+2]=c;
+	}
+      }
+      break;
+    case 2:
+      if((b->number%3)==1){
+	bc[0].static_g[b->number/3]=g;
+	bc[0].static_e[b->number/3]=e;
+	bc[0].static_c[b->number/3]=c;
+	bc[1].static_g[b->number/3*2]=g;
+	bc[1].static_e[b->number/3*2]=e;
+	bc[1].static_c[b->number/3*2]=c;
+      }else if(b->number>1){
+	if(b->number<29){
+	  bc[1].static_g[(b->number-1)/3*2+1]=
+	    (bc[2].static_g[(b->number-1)/3*3+2]+
+	     bc[2].static_g[(b->number-1)/3*3+3])*.5;
+	  bc[1].static_e[(b->number-1)/3*2+1]=
+	    (bc[2].static_e[(b->number-1)/3*3+2]+
+	     bc[2].static_e[(b->number-1)/3*3+3])*.5;
+	  bc[1].static_c[(b->number-1)/3*2+1]=
+	    (bc[2].static_c[(b->number-1)/3*3+2]+
+	     bc[2].static_c[(b->number-1)/3*3+3])*.5;
+	}else{
+	  bc[1].static_g[(b->number-1)/3*2+1]=g;
+	  bc[1].static_e[(b->number-1)/3*2+1]=e;
+	bc[1].static_c[(b->number-1)/3*2+1]=c;
+	}
+      }
+      break;
+    }
+  }
+}
+
+static void static_octave(GtkWidget *w,gpointer in){
+  int octave=(int)in,i;
+
+  if(!w || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))){
+    if(bank_active!=octave || w==NULL){
+      bank_active=octave;
+      
+      /* map, unmap, relabel */
+      for(i=0;i<multicomp_freqs_max;i++){
+	if(i<multicomp_freqs[bank_active]){
+	  gtk_label_set_text(GTK_LABEL(bars[i].label),
+			     multicomp_freq_labels[bank_active][i]);
+	  gtk_widget_show(bars[i].label);
+	  gtk_widget_show(bars[i].slider);
+	  gtk_widget_show(bars[i].readoutg);
+	  gtk_widget_show(bars[i].readoute);
+	  gtk_widget_show(bars[i].readoutc);
+	  
+	  inactive_updatep=0;
+	  
+	  {
+	    float g=bc[bank_active].static_g[i]/10.;
+	    float e=bc[bank_active].static_e[i]/10.;
+	    float c=bc[bank_active].static_c[i]/10.;
+
+	    multibar_thumb_set(MULTIBAR(bars[i].slider),g,0);
+	    multibar_thumb_set(MULTIBAR(bars[i].slider),e,1);
+	    multibar_thumb_set(MULTIBAR(bars[i].slider),c,2);
+	  }
+
+	  inactive_updatep=1;
+	  
+	}else{
+	  gtk_widget_hide(bars[i].label);
+	  gtk_widget_hide(bars[i].slider);
+	  gtk_widget_hide(bars[i].readoutg);
+	  gtk_widget_hide(bars[i].readoute);
+	  gtk_widget_hide(bars[i].readoutc);
+	}
+      }
+      multicompand_set_bank(bank_active);
+      
+    }
+  }
+}
 
 static void static_compressor_change(GtkWidget *w,gpointer in){
   char buffer[80];
@@ -84,40 +231,87 @@
   c.static_e_ratio=rint(100./val);
 }
 
-static void static_decay_change(GtkWidget *w,gpointer in){
+static void static_decay_change(GtkWidget *w,gpointer in,sig_atomic_t *v){
   char buffer[80];
   Readout *r=READOUT(in);
-  float val=-multibar_get_value(MULTIBAR(w),0);
+  float val=multibar_get_value(MULTIBAR(w),0);
+  float set=val/input_rate*(1024*1024);
+  float ms =-100000./val;
 
-  sprintf(buffer,"%.2f",val);
+  if(ms<100)
+    sprintf(buffer,".%04d",(int)rint(ms*10.));
+  else if(ms<1000)
+    sprintf(buffer,".%03d",(int)rint(ms));
+  else if(ms<10000)
+    sprintf(buffer,"%4.2f",ms/1000);
+  else
+    sprintf(buffer,"%4.1f",ms/1000);
 
-  if(val==1.)
+  if(ms<=1)
     sprintf(buffer," fast");
 
-  if(val==.01)
+  if(ms>99999.)
     sprintf(buffer," slow");
 
   readout_set(r,buffer);
-  c.static_decay=rint(100./val);
+  *v=rint(set);
+}
+
+static void static_c_decay_change(GtkWidget *w,gpointer in){
+  static_decay_change(w,in,&c.static_c_decay);
+}
+static void static_e_decay_change(GtkWidget *w,gpointer in){
+  static_decay_change(w,in,&c.static_e_decay);
+}
+static void static_g_decay_change(GtkWidget *w,gpointer in){
+  static_decay_change(w,in,&c.static_g_decay);
 }
 
-static void static_trim_change(GtkWidget *w,gpointer in){
+static void static_trim_change(GtkWidget *w,gpointer in,sig_atomic_t *v){
   char buffer[80];
   Readout *r=READOUT(in);
   float val=multibar_get_value(MULTIBAR(w),0);
 
-  sprintf(buffer,"%+2.0fdB",val);
+  sprintf(buffer,"%+3.0fdB",val);
 
   readout_set(r,buffer);
-  c.static_trim=rint(val*10.);
+  *v=rint(val*10.);
 }
 
-static void static_trim_apply(GtkWidget *w,gpointer in){
+static void static_c_trim_change(GtkWidget *w,gpointer in){
+  static_trim_change(w,in,&c.static_c_trim);
+}
+static void static_e_trim_change(GtkWidget *w,gpointer in){
+  static_trim_change(w,in,&c.static_e_trim);
+}
+static void static_g_trim_change(GtkWidget *w,gpointer in){
+  static_trim_change(w,in,&c.static_g_trim);
+
+}
+
+static void static_trim_apply(GtkWidget *w,gpointer in,int gec){
   char buffer[80];
+  int i,j;
   Multibar *m=MULTIBAR(in);
-  float val=multibar_get_value(m,0);
+  float trim=multibar_get_value(m,0);
+
+  /* apply the trim to all sliders */
+  for(j=0;j<multicomp_freqs[bank_active];j++){
+    float sv=multibar_get_value(MULTIBAR(bars[j].slider),gec);
+    multibar_thumb_set(MULTIBAR(bars[j].slider),sv+trim,gec);
+  }
 
-  /* XXXXX */
+  multibar_thumb_set(m,0,0);
+}
+
+static void static_c_trim_apply(GtkWidget *w,gpointer in){
+  static_trim_apply(w,in,2);
+}
+static void static_e_trim_apply(GtkWidget *w,gpointer in){
+  static_trim_apply(w,in,1);
+}
+static void static_g_trim_apply(GtkWidget *w,gpointer in){
+  static_trim_apply(w,in,0);
 }
 
 static void link_toggled(GtkToggleButton *b,gpointer in){
@@ -140,31 +334,30 @@
   c.envelope_mode=mode;
 }
 
-static void suppress_bias_change(GtkWidget *w,gpointer in){
-  char buffer[80];
-  Readout *r=READOUT(in);
-  float val=multibar_get_value(MULTIBAR(w),0);
-
-  sprintf(buffer,"%+2.0fdB",val);
-  readout_set(r,buffer);
-  c.suppress_bias=rint(val*10.);
-}
-
 static void suppress_decay_change(GtkWidget *w,gpointer in){
   char buffer[80];
   Readout *r=READOUT(in);
-  float val=-multibar_get_value(MULTIBAR(w),0);
+  float val=multibar_get_value(MULTIBAR(w),0);
+  float set=val/input_rate*(1024*1024);
+  float ms =-100000./val;
 
-  sprintf(buffer,"%.2f",val);
+  if(ms<100)
+    sprintf(buffer,".%04d",(int)rint(ms*10.));
+  else if(ms<1000)
+    sprintf(buffer,".%03d",(int)rint(ms));
+  else if(ms<10000)
+    sprintf(buffer,"%4.2f",ms/1000);
+  else
+    sprintf(buffer,"%4.1f",ms/1000);
 
-  if(val==1.)
+  if(ms<=1)
     sprintf(buffer," fast");
 
-  if(val==.01)
+  if(ms>99999.)
     sprintf(buffer," slow");
 
   readout_set(r,buffer);
-  c.suppress_decay=rint(100./val);
+  c.suppress_decay=rint(set);
 }
 
 static void suppress_ratio_change(GtkWidget *w,gpointer in){
@@ -172,14 +365,14 @@
   Readout *r=READOUT(in);
   float val=-multibar_get_value(MULTIBAR(w),0);
 
-  sprintf(buffer,"%3.1f:1",1./val);
+  if(rint(1./val)>=10.)
+    sprintf(buffer,"%3.0f:1",1./val);
+  else
+    sprintf(buffer,"%3.1f:1",1./val);
 
   if(val==1.)
     sprintf(buffer,"  off");
 
-  if(val==.1)
-    sprintf(buffer," gate");
-
   readout_set(r,buffer);
   c.suppress_ratio=rint(100./val);
 }
@@ -211,56 +404,92 @@
   c.envelope_c=rint(val*10.);
 }
 
-static void slider_change(GtkWidget *w,gpointer in){
-  char buffer[80];
-  cbar *b=(cbar *)in;
-
-  float val=multibar_get_value(MULTIBAR(b->slider),0);
-  sprintf(buffer,"%3.0fdB",val);
-  readout_set(READOUT(b->readoutg),buffer);
-  c.static_g[b->number]=rint(val*10.);
-  
-  val=multibar_get_value(MULTIBAR(b->slider),1);
-  sprintf(buffer,"%+4.0fdB",val);
-  readout_set(READOUT(b->readoute),buffer);
-  c.static_e[b->number]=rint(val*10.);
-
-  val=multibar_get_value(MULTIBAR(b->slider),2);
-  sprintf(buffer,"%+4.0fdB",val);
-  readout_set(READOUT(b->readoutc),buffer);
-  c.static_c[b->number]=rint(val*10.);
-
-}
-
 void compandpanel_create(postfish_mainpanel *mp,
                          GtkWidget *windowbutton,
                          GtkWidget *activebutton){
-  int i;
+  int i,j;
   char *labels[14]={"130","120","110","100","90","80","70",
                     "60","50","40","30","20","10","0"};
   float levels[15]={-140,-130,-120,-110,-100,-90,-80,-70,-60,-50,-40,
                      -30,-20,-10,0};
 
+  float ratio_levels[7]={-1.,-.67,-.5,-.33,-.25,-.17,-.1};
+  char  *ratio_labels[6]={"1.5:1","2:1","3:1","4:1","6:1","10:1"};
+
+  float decay_levels[7]={-100000,-10000,-1000,-100,-10,-3,-1};
+  char  *decay_labels[6]={".01",".1","1","10","30","slow"};
+    
+  float bias_levels[7]={-30,-20,-10,0,10,20,30};
+  char  *bias_labels[6]={"20","10","0","10","20","30"};
+
+  float depth_levels[7]={-140,-130,-120,-110,-100,-80,-0};
+  char  *depth_labels[6]={"10","20","30","40","60","deep"};
+
+
   subpanel_generic *panel=subpanel_create(mp,windowbutton,activebutton,
                                           &compand_active,
                                           &compand_visible,
-					  "_Compander and Noise Gate"," [c] ");
+					  "_Multiband Compand and Noise Gate"," [m] ");
   
   GtkWidget *hbox=gtk_hbox_new(0,0);
+  GtkWidget *sliderbox=gtk_vbox_new(0,0);
+  GtkWidget *sliderframe=gtk_frame_new(NULL);
   GtkWidget *staticbox=gtk_vbox_new(0,0);
   GtkWidget *staticframe=gtk_frame_new(NULL);
+  GtkWidget *slidertable=gtk_table_new(multicomp_freqs_max+1,5,0);
+
   GtkWidget *envelopeframe=gtk_frame_new(" Envelope Compander ");
-  GtkWidget *suppressframe=gtk_frame_new(" Suppressor ");
+  GtkWidget *suppressframe=gtk_frame_new(" Reverberation Suppressor ");
 
   GtkWidget *envelopetable=gtk_table_new(3,3,0);
-  GtkWidget *suppresstable=gtk_table_new(5,3,0);
-  GtkWidget *statictable=gtk_table_new(6,4,0);
+  GtkWidget *suppresstable=gtk_table_new(4,3,0);
+  GtkWidget *statictable=gtk_table_new(10,4,0);
 
-  GtkWidget *slidertable=gtk_table_new(multicomp_freqs+1,5,0);
-  
   GtkWidget *link_box=gtk_hbox_new(0,0);
   GtkWidget *link_check=gtk_check_button_new_with_mnemonic("_link channel envelopes");
 
+  {
+  
+    GtkWidget *octave_box=gtk_hbox_new(0,0);
+    GtkWidget *octave_a=gtk_radio_button_new_with_label(NULL,"full-octave");
+    GtkWidget *octave_b=
+      gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(octave_a),
+						  "half-octave");
+    GtkWidget *octave_c=
+      gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(octave_b),
+						  "third-octave");
+    GtkWidget *label2=gtk_label_new("gate");
+    GtkWidget *label3=gtk_label_new("expd");
+    GtkWidget *label4=gtk_label_new("cmpr");
+
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(octave_c),1);
+
+    g_signal_connect (G_OBJECT (octave_a), "clicked",
+		      G_CALLBACK (static_octave), (gpointer)0);
+    g_signal_connect (G_OBJECT (octave_b), "clicked",
+		      G_CALLBACK (static_octave), (gpointer)1);
+    g_signal_connect (G_OBJECT (octave_c), "clicked",
+		      G_CALLBACK (static_octave), (gpointer)2);
+   
+    gtk_table_attach(GTK_TABLE(slidertable),label2,2,3,0,1,GTK_FILL,0,2,0);
+    gtk_table_attach(GTK_TABLE(slidertable),label3,3,4,0,1,GTK_FILL,0,2,0);
+    gtk_table_attach(GTK_TABLE(slidertable),label4,4,5,0,1,GTK_FILL,0,2,0);
+
+    gtk_box_pack_start(GTK_BOX(octave_box),octave_a,0,1,3);
+    gtk_box_pack_start(GTK_BOX(octave_box),octave_b,0,1,3);
+    gtk_box_pack_start(GTK_BOX(octave_box),octave_c,0,1,3);
+    gtk_table_attach(GTK_TABLE(slidertable),octave_box,1,2,0,1,
+		     GTK_EXPAND,0,0,0);
+
+    gtk_box_pack_start(GTK_BOX(sliderbox),sliderframe,0,0,0);
+    gtk_container_add(GTK_CONTAINER(sliderframe),slidertable);
+
+    gtk_frame_set_shadow_type(GTK_FRAME(sliderframe),GTK_SHADOW_NONE);
+    
+    gtk_container_set_border_width(GTK_CONTAINER(sliderframe),4);
+
+  }
+
   if(input_ch>1)
     gtk_box_pack_end(GTK_BOX(link_box),link_check,0,0,0);  
 
@@ -268,11 +497,10 @@
   gtk_container_set_border_width(GTK_CONTAINER(link_box),5);
   g_signal_connect (G_OBJECT (link_check), "toggled",
                     G_CALLBACK (link_toggled), (gpointer)0);
-  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(link_check),1);
-
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(link_check),0);
 
   gtk_box_pack_start(GTK_BOX(panel->subpanel_box),hbox,0,0,0);
-  gtk_box_pack_start(GTK_BOX(hbox),slidertable,0,0,0);
+  gtk_box_pack_start(GTK_BOX(hbox),sliderbox,0,0,0);
   gtk_box_pack_start(GTK_BOX(hbox),staticbox,0,0,0);
 
   gtk_box_pack_start(GTK_BOX(staticbox),staticframe,0,0,0);
@@ -289,108 +517,151 @@
 
   /* static compand */
   {
-    float ratio_levels[7]={-1.,-.67,-.5,-.33,-.25,-.17,-.1};
-    char  *ratio_labels[6]={"1.5:1","2:1","3:1","4:1","6:1","10:1"};
-
-    float decay_levels[7]={-1.,-.5,-.2,-.1,-.05,-.02,-.01};
-    char  *decay_labels[6]={".5",".2",".1",".05",".02","slow"};
-
-    float bias_levels[7]={-30,-20,-10,0,10,20,30};
-    char  *bias_labels[6]={"20","10","0","10","20","30"};
-
-    GtkWidget *label0=gtk_label_new("mode");
-
-    GtkWidget *label1=gtk_label_new("cmpr:");
-    GtkWidget *label2=gtk_label_new("expd:");
-    GtkWidget *label3=gtk_label_new("decay:");
-    GtkWidget *label4=gtk_label_new("trim:");
-
-    GtkWidget *readout1=readout_new("1.5:1");
-    GtkWidget *readout2=readout_new("1.5:1");
-    GtkWidget *readout3=readout_new(" fast");
-    GtkWidget *readout4=readout_new("-40dB");
-
-    GtkWidget *slider1=multibar_slider_new(6,ratio_labels,ratio_levels,1);
-    GtkWidget *slider2=multibar_slider_new(6,ratio_labels,ratio_levels,1);
-    GtkWidget *slider3=multibar_slider_new(6,decay_labels,decay_levels,1);
-    GtkWidget *slider4=multibar_slider_new(6,bias_labels,bias_levels,1);
-
-    GtkWidget *button4=gtk_button_new_with_label("a[p]ply trim");
 
+    //GtkWidget *label0=gtk_label_new("mode:");
     GtkWidget *envelopebox=gtk_hbox_new(0,0);
     GtkWidget *rms_button=gtk_radio_button_new_with_label(NULL,"RMS");
     GtkWidget *peak_button=
       gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rms_button),
                                                   "peak");
 
-    gtk_box_pack_start(GTK_BOX(envelopebox),rms_button,0,0,5);
-    gtk_box_pack_start(GTK_BOX(envelopebox),peak_button,0,0,5);
-
-    g_signal_connect (G_OBJECT (button4), "clicked",
-		      G_CALLBACK (static_trim_apply), (gpointer)slider4);
+    GtkWidget *labelR=gtk_label_new("Ratio");
+    GtkWidget *labelR1=gtk_label_new("cmpr:");
+    GtkWidget *labelR2=gtk_label_new("expd:");
+    GtkWidget *readoutR1=readout_new("1.5:1");
+    GtkWidget *readoutR2=readout_new("1.5:1");
+    GtkWidget *sliderR1=multibar_slider_new(6,ratio_labels,ratio_levels,1);
+    GtkWidget *sliderR2=multibar_slider_new(6,ratio_labels,ratio_levels,1);
+
+    GtkWidget *labelD=gtk_label_new("Decay");
+    GtkWidget *labelD1=gtk_label_new("cmpr:");
+    GtkWidget *labelD2=gtk_label_new("expd:");
+    GtkWidget *labelD3=gtk_label_new("gate:");
+    GtkWidget *readoutD1=readout_new(" fast");
+    GtkWidget *readoutD2=readout_new(" fast");
+    GtkWidget *readoutD3=readout_new(" fast");
+    GtkWidget *sliderD1=multibar_slider_new(6,decay_labels,decay_levels,1);
+    GtkWidget *sliderD2=multibar_slider_new(6,decay_labels,decay_levels,1);
+    GtkWidget *sliderD3=multibar_slider_new(6,decay_labels,decay_levels,1);
+
+    GtkWidget *labelT=gtk_label_new("Trim");
+    GtkWidget *labelT1=gtk_label_new("cmpr:");
+    GtkWidget *labelT2=gtk_label_new("expd:");
+    GtkWidget *labelT3=gtk_label_new("gate:");
+    GtkWidget *readoutT1=readout_new("-40dB");
+    GtkWidget *readoutT2=readout_new("-40dB");
+    GtkWidget *readoutT3=readout_new("-40dB");
+    GtkWidget *sliderT1=multibar_slider_new(6,bias_labels,bias_levels,1);
+    GtkWidget *sliderT2=multibar_slider_new(6,bias_labels,bias_levels,1);
+    GtkWidget *sliderT3=multibar_slider_new(6,bias_labels,bias_levels,1);
+    GtkWidget *buttonT1=gtk_button_new_with_label("apply");
+    GtkWidget *buttonT2=gtk_button_new_with_label("apply");
+    GtkWidget *buttonT3=gtk_button_new_with_label("apply");
 
+    gtk_box_pack_end(GTK_BOX(envelopebox),peak_button,0,0,5);
+    gtk_box_pack_end(GTK_BOX(envelopebox),rms_button,0,0,5);
     g_signal_connect (G_OBJECT (rms_button), "clicked",
                       G_CALLBACK (static_mode), (gpointer)0); //To Hell I Go
     g_signal_connect (G_OBJECT (peak_button), "clicked",
                       G_CALLBACK (static_mode), (gpointer)1);
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rms_button),1);
 
-    gtk_container_set_border_width(GTK_CONTAINER(statictable),4);
+    g_signal_connect (G_OBJECT (buttonT1), "clicked",
+		      G_CALLBACK (static_c_trim_apply), sliderT1);
+    g_signal_connect (G_OBJECT (buttonT2), "clicked",
+		      G_CALLBACK (static_e_trim_apply), sliderT2);
+    g_signal_connect (G_OBJECT (buttonT3), "clicked",
+		      G_CALLBACK (static_g_trim_apply), sliderT3);
 
-    multibar_callback(MULTIBAR(slider1),
-		      static_compressor_change,
-		      readout1);
-    multibar_thumb_set(MULTIBAR(slider1),-1.,0);
-
-    multibar_callback(MULTIBAR(slider2),
-		      static_expander_change,
-		      readout2);
-    multibar_thumb_set(MULTIBAR(slider2),-1.,0);
-
-    multibar_callback(MULTIBAR(slider3),
-		      static_decay_change,
-		      readout3);
-    multibar_thumb_set(MULTIBAR(slider3),-1.,0);
-
-    multibar_callback(MULTIBAR(slider4),
-		      static_trim_change,
-		      readout4);
-    multibar_thumb_increment(MULTIBAR(slider4),1.,10.);
+    gtk_container_set_border_width(GTK_CONTAINER(statictable),4);
 
+    multibar_callback(MULTIBAR(sliderR1),static_compressor_change,readoutR1);
+    multibar_thumb_set(MULTIBAR(sliderR1),-1.,0);
+    multibar_callback(MULTIBAR(sliderR2),static_expander_change,readoutR2);
+    multibar_thumb_set(MULTIBAR(sliderR2),-1.,0);
+
+    multibar_callback(MULTIBAR(sliderD1),static_c_decay_change,readoutD1);
+    multibar_thumb_set(MULTIBAR(sliderD1),-100000.,0);
+    multibar_callback(MULTIBAR(sliderD2),static_e_decay_change,readoutD2);
+    multibar_thumb_set(MULTIBAR(sliderD2),-100.,0);
+    multibar_callback(MULTIBAR(sliderD3),static_g_decay_change,readoutD3);
+    multibar_thumb_set(MULTIBAR(sliderD3),-10.,0);
+
+    multibar_callback(MULTIBAR(sliderT1),static_c_trim_change,readoutT1);
+    multibar_thumb_increment(MULTIBAR(sliderT1),1.,10.);
+    multibar_callback(MULTIBAR(sliderT2),static_e_trim_change,readoutT2);
+    multibar_thumb_increment(MULTIBAR(sliderT2),1.,10.);
+    multibar_callback(MULTIBAR(sliderT3),static_g_trim_change,readoutT3);
+    multibar_thumb_increment(MULTIBAR(sliderT3),1.,10.);
+
+    //gtk_misc_set_alignment(GTK_MISC(labelR),0,.5);
+    //gtk_misc_set_alignment(GTK_MISC(labelD),0,.5);
+    //gtk_misc_set_alignment(GTK_MISC(labelT),0,.5);
+    gtk_widget_set_name(labelR,"framelabel");
+    gtk_widget_set_name(labelD,"framelabel");
+    gtk_widget_set_name(labelT,"framelabel");
+
+    gtk_misc_set_alignment(GTK_MISC(labelR1),1,.5);
+    gtk_misc_set_alignment(GTK_MISC(labelR2),1,.5);
+    gtk_misc_set_alignment(GTK_MISC(labelD1),1,.5);
+    gtk_misc_set_alignment(GTK_MISC(labelD2),1,.5);
+    gtk_misc_set_alignment(GTK_MISC(labelD3),1,.5);
+    gtk_misc_set_alignment(GTK_MISC(labelT1),1,.5);
+    gtk_misc_set_alignment(GTK_MISC(labelT2),1,.5);
+    gtk_misc_set_alignment(GTK_MISC(labelT3),1,.5);
 
-    gtk_misc_set_alignment(GTK_MISC(label0),1,.5);
-    gtk_misc_set_alignment(GTK_MISC(label1),1,.5);
-    gtk_misc_set_alignment(GTK_MISC(label2),1,.5);
-    gtk_misc_set_alignment(GTK_MISC(label3),1,.5);
-    gtk_misc_set_alignment(GTK_MISC(label4),1,.5);
+    //gtk_table_attach(GTK_TABLE(statictable),label0,0,1,0,1,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),envelopebox,1,4,0,1,GTK_FILL,0,0,0);
 
 
-    gtk_table_attach(GTK_TABLE(statictable),label0,0,1,0,1,GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(statictable),label1,0,1,1,2,GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(statictable),label2,0,1,2,3,GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(statictable),label3,0,1,3,4,GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(statictable),label4,0,1,4,5,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),labelR,0,4,0,1,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),labelR1,0,1,1,2,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),labelR2,0,1,2,3,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),sliderR1,1,3,1,2,
+		     GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+    gtk_table_attach(GTK_TABLE(statictable),sliderR2,1,3,2,3,
+		     GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+    gtk_table_attach(GTK_TABLE(statictable),readoutR1,3,4,1,2,GTK_FILL,0,0,2);
+    gtk_table_attach(GTK_TABLE(statictable),readoutR2,3,4,2,3,GTK_FILL,0,0,2);
 
-    gtk_table_attach(GTK_TABLE(statictable),envelopebox,1,4,0,1,GTK_FILL,0,0,0);
 
-    gtk_table_attach(GTK_TABLE(statictable),slider1,1,3,1,2,
+    gtk_table_attach(GTK_TABLE(statictable),labelD,0,4,3,4,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),labelD1,0,1,4,5,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),labelD2,0,1,5,6,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),labelD3,0,1,6,7,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),sliderD1,1,3,4,5,
                      GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
-    gtk_table_attach(GTK_TABLE(statictable),slider2,1,3,2,3,
+    gtk_table_attach(GTK_TABLE(statictable),sliderD2,1,3,5,6,
                      GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
-    gtk_table_attach(GTK_TABLE(statictable),slider3,1,3,3,4,
+    gtk_table_attach(GTK_TABLE(statictable),sliderD3,1,3,6,7,
                      GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
-    gtk_table_attach(GTK_TABLE(statictable),slider4,1,3,4,5,
-		     GTK_FILL|GTK_EXPAND,GTK_FILL,2,0);
-
-    gtk_table_attach(GTK_TABLE(statictable),button4,1,3,5,6,GTK_EXPAND,0,2,5);
+    gtk_table_attach(GTK_TABLE(statictable),readoutD1,3,4,4,5,GTK_FILL,0,0,2);
+    gtk_table_attach(GTK_TABLE(statictable),readoutD2,3,4,5,6,GTK_FILL,0,0,2);
+    gtk_table_attach(GTK_TABLE(statictable),readoutD3,3,4,6,7,GTK_FILL,0,0,2);
+
+    gtk_table_attach(GTK_TABLE(statictable),labelT,0,4,7,8,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),labelT1,0,1,8,9,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),labelT2,0,1,9,10,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),labelT3,0,1,10,11,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),sliderT1,1,2,8,9,
+		     GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+    gtk_table_attach(GTK_TABLE(statictable),sliderT2,1,2,9,10,
+		     GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+    gtk_table_attach(GTK_TABLE(statictable),sliderT3,1,2,10,11,
+		     GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+    gtk_table_attach(GTK_TABLE(statictable),buttonT1,3,4,8,9,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),buttonT2,3,4,9,10,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),buttonT3,3,4,10,11,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(statictable),readoutT1,2,3,8,9,GTK_FILL,0,0,2);
+    gtk_table_attach(GTK_TABLE(statictable),readoutT2,2,3,9,10,GTK_FILL,0,0,2);
+    gtk_table_attach(GTK_TABLE(statictable),readoutT3,2,3,10,11,GTK_FILL,0,0,2);
+
+    gtk_table_set_row_spacing(GTK_TABLE(statictable),2,5);
+    gtk_table_set_row_spacing(GTK_TABLE(statictable),6,5);
+    gtk_table_set_row_spacing(GTK_TABLE(statictable),10,10);
 
-    gtk_table_attach(GTK_TABLE(statictable),readout1,3,4,1,2,GTK_FILL,0,0,2);
-    gtk_table_attach(GTK_TABLE(statictable),readout2,3,4,2,3,GTK_FILL,0,0,2);
-    gtk_table_attach(GTK_TABLE(statictable),readout3,3,4,3,4,GTK_FILL,0,0,2);
-    gtk_table_attach(GTK_TABLE(statictable),readout4,3,4,4,5,GTK_FILL,0,0,2);
     gtk_container_set_border_width(GTK_CONTAINER(statictable),4);
-
-  }
+ }
 
   /* envelope compand */
   {
@@ -398,7 +669,7 @@
     char *labels[10]={"40%","30%","20%","10%","0%","10%","20%",
                       "30%","40%","50%"};
 
-    GtkWidget *label0=gtk_label_new("mode:");
+    //GtkWidget *label0=gtk_label_new("mode:");
     GtkWidget *label1=gtk_label_new("compress");
     GtkWidget *label2=gtk_label_new("expand");
     GtkWidget *envelope_compress_readout=readout_new(" 0.0%");
@@ -409,21 +680,15 @@
     GtkWidget *peak_button=
       gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rms_button),
                                                   "peak");
-    GtkWidget *total_button=
-      gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rms_button),
-						  "total");
 
-    gtk_box_pack_start(GTK_BOX(envelopebox),label0,0,0,1);
-    gtk_box_pack_start(GTK_BOX(envelopebox),rms_button,0,0,5);
-    gtk_box_pack_start(GTK_BOX(envelopebox),peak_button,0,0,5);
-    gtk_box_pack_start(GTK_BOX(envelopebox),total_button,0,0,5);
+    //gtk_box_pack_start(GTK_BOX(envelopebox),label0,0,0,1);
+    gtk_box_pack_end(GTK_BOX(envelopebox),peak_button,0,0,5);
+    gtk_box_pack_end(GTK_BOX(envelopebox),rms_button,0,0,5);
 
     g_signal_connect (G_OBJECT (rms_button), "clicked",
                       G_CALLBACK (envelope_mode), (gpointer)0); //To Hell I Go
     g_signal_connect (G_OBJECT (peak_button), "clicked",
                       G_CALLBACK (envelope_mode), (gpointer)1);
-    g_signal_connect (G_OBJECT (peak_button), "clicked",
-		      G_CALLBACK (envelope_mode), (gpointer)2);
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rms_button),1);
 
    
@@ -441,7 +706,7 @@
     gtk_table_attach(GTK_TABLE(envelopetable),label1,0,1,2,3,GTK_FILL,0,2,0);
     gtk_table_attach(GTK_TABLE(envelopetable),label2,1,2,2,3,GTK_FILL,0,2,0);
     gtk_table_attach(GTK_TABLE(envelopetable),envelopebox,
-		     0,2,0,1,GTK_FILL,0,0,0);
+		     0,3,0,1,GTK_FILL,0,0,0);
 
     gtk_table_attach(GTK_TABLE(envelopetable),envelope_compress_slider,
                      0,2,1,2,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
@@ -453,29 +718,14 @@
   /* suppressor */
   {
 
-    float bias_levels[7]={-30,-20,-10,0,10,20,30};
-    char  *bias_labels[6]={"20","10","0","10","20","30"};
-
-    float decay_levels[7]={-1.,-.5,-.2,-.1,-.05,-.02,-.01};
-    char  *decay_labels[6]={".5",".2",".1",".05",".02","slow"};
-
-    float ratio_levels[7]={-1.,-.67,-.5,-.33,-.25,-.17,-.1};
-    char  *ratio_labels[6]={"1.5:1","2:1","3:1","4:1","6:1","gate"};
-
-    float depth_levels[7]={-140,-130,-120,-110,-100,-80,-0};
-    char  *depth_labels[6]={"10","20","30","40","60","deep"};
-
-    GtkWidget *suppress_bias_slider=multibar_slider_new(6,bias_labels,bias_levels,1);
     GtkWidget *suppress_decay_slider=multibar_slider_new(6,decay_labels,decay_levels,1);
     GtkWidget *suppress_ratio_slider=multibar_slider_new(6,ratio_labels,ratio_levels,1);
     GtkWidget *suppress_depth_slider=multibar_slider_new(6,depth_labels,depth_levels,1);
-    GtkWidget *suppress_bias_readout=readout_new(" +0dB");
     GtkWidget *suppress_decay_readout=readout_new("fast");
     GtkWidget *suppress_ratio_readout=readout_new("1.5:1");
     GtkWidget *suppress_depth_readout=readout_new("gate");
 
-    GtkWidget *label1=gtk_label_new("mode:");
-    GtkWidget *label2=gtk_label_new("bias:");
+    //GtkWidget *label1=gtk_label_new("mode:");
     GtkWidget *label3=gtk_label_new("decay:");
     GtkWidget *label4=gtk_label_new("ratio:");
     GtkWidget *label5=gtk_label_new("depth:");
@@ -485,8 +735,8 @@
     GtkWidget *suppress_peak_button=
       gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(suppress_rms_button),
                                                   "peak");
-    gtk_box_pack_start(GTK_BOX(envelopebox),suppress_rms_button,0,0,5);
-    gtk_box_pack_start(GTK_BOX(envelopebox),suppress_peak_button,0,0,5);
+    gtk_box_pack_end(GTK_BOX(envelopebox),suppress_peak_button,0,0,5);
+    gtk_box_pack_end(GTK_BOX(envelopebox),suppress_rms_button,0,0,5);
 
 
     g_signal_connect (G_OBJECT (suppress_rms_button), "clicked",
@@ -498,26 +748,19 @@
 
     gtk_container_set_border_width(GTK_CONTAINER(suppresstable),4);
 
-    gtk_misc_set_alignment(GTK_MISC(label1),1,.5);
-    gtk_misc_set_alignment(GTK_MISC(label2),1,.5);
+    //gtk_misc_set_alignment(GTK_MISC(label1),1,.5);
     gtk_misc_set_alignment(GTK_MISC(label3),1,.5);
     gtk_misc_set_alignment(GTK_MISC(label4),1,.5);
     gtk_misc_set_alignment(GTK_MISC(label5),1,.5);
 
 
-    gtk_table_attach(GTK_TABLE(suppresstable),label1,0,1,0,1,GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(suppresstable),label2,0,1,1,2,GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(suppresstable),label3,0,1,2,3,GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(suppresstable),label4,0,1,3,4,GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(suppresstable),label5,0,1,4,5,GTK_FILL,0,0,0);
+    //gtk_table_attach(GTK_TABLE(suppresstable),label1,0,1,0,1,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(suppresstable),label3,0,1,1,2,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(suppresstable),label4,0,1,2,3,GTK_FILL,0,0,0);
+    gtk_table_attach(GTK_TABLE(suppresstable),label5,0,1,3,4,GTK_FILL,0,0,0);
 
     gtk_table_attach(GTK_TABLE(suppresstable),envelopebox,1,3,0,1,GTK_FILL,0,0,0);
 
-    multibar_callback(MULTIBAR(suppress_bias_slider),
-		      suppress_bias_change,
-		      suppress_bias_readout);
-    multibar_thumb_set(MULTIBAR(suppress_bias_slider),0.,0);
-
     multibar_callback(MULTIBAR(suppress_decay_slider),
                       suppress_decay_change,
                       suppress_decay_readout);
@@ -534,52 +777,35 @@
     multibar_thumb_set(MULTIBAR(suppress_depth_slider),0.,0);
 
     gtk_table_attach(GTK_TABLE(suppresstable),
-		     suppress_bias_slider,1,2,1,2,GTK_FILL|GTK_EXPAND,
-		     GTK_FILL|GTK_EXPAND,2,0);
-    gtk_table_attach(GTK_TABLE(suppresstable),
-		     suppress_decay_slider,1,2,2,3,GTK_FILL|GTK_EXPAND,
+		     suppress_decay_slider,1,2,1,2,GTK_FILL|GTK_EXPAND,
                      GTK_FILL|GTK_EXPAND,2,0);
     gtk_table_attach(GTK_TABLE(suppresstable),
-		     suppress_ratio_slider,1,2,3,4,GTK_FILL|GTK_EXPAND,
+		     suppress_ratio_slider,1,2,2,3,GTK_FILL|GTK_EXPAND,
                      GTK_FILL|GTK_EXPAND,2,0);
     gtk_table_attach(GTK_TABLE(suppresstable),
-		     suppress_depth_slider,1,2,4,5,GTK_FILL|GTK_EXPAND,
+		     suppress_depth_slider,1,2,3,4,GTK_FILL|GTK_EXPAND,
                      GTK_FILL|GTK_EXPAND,2,0);
 
     gtk_table_attach(GTK_TABLE(suppresstable),
-		     suppress_bias_readout,2,3,1,2,GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(suppresstable),
-		     suppress_decay_readout,2,3,2,3,GTK_FILL,0,0,0);
+		     suppress_decay_readout,2,3,1,2,GTK_FILL,0,0,0);
     gtk_table_attach(GTK_TABLE(suppresstable),
-		     suppress_ratio_readout,2,3,3,4,GTK_FILL,0,0,0);
+		     suppress_ratio_readout,2,3,2,3,GTK_FILL,0,0,0);
     gtk_table_attach(GTK_TABLE(suppresstable),
-		     suppress_depth_readout,2,3,4,5,GTK_FILL,0,0,0);
+		     suppress_depth_readout,2,3,3,4,GTK_FILL,0,0,0);
 
   }
 
-  {
-    GtkWidget *label2=gtk_label_new("gate");
-    GtkWidget *label3=gtk_label_new("expd");
-    GtkWidget *label4=gtk_label_new("cmpr");
-
-    gtk_table_attach(GTK_TABLE(slidertable),label2,2,3,0,1,GTK_FILL,0,10,0);
-    gtk_table_attach(GTK_TABLE(slidertable),label3,3,4,0,1,GTK_FILL,0,10,0);
-    gtk_table_attach(GTK_TABLE(slidertable),label4,4,5,0,1,GTK_FILL,0,10,0);
-    
-  }
-
-  for(i=0;i<multicomp_freqs;i++){
-    const char *labeltext=multicomp_freq_labels[i];
-
-    GtkWidget *label=gtk_label_new(labeltext);
+  for(i=0;i<multicomp_freqs_max;i++){
+    GtkWidget *label=gtk_label_new(NULL);
     gtk_widget_set_name(label,"smallmarker");
-
-    bars[i].readoutg=readout_new("  +0dB");
-    bars[i].readoute=readout_new("  +0dB");
-    bars[i].readoutc=readout_new("  +0dB");
+    
+    bars[i].readoutg=readout_new("  +0");
+    bars[i].readoute=readout_new("  +0");
+    bars[i].readoutc=readout_new("  +0");
     bars[i].slider=multibar_new(14,labels,levels,3,
-				LO_DECAY|HI_DECAY|LO_ATTACK|HI_ATTACK);
+				LO_DECAY|HI_DECAY|LO_ATTACK);
     bars[i].number=i;
+    bars[i].label=label;
 
     multibar_callback(MULTIBAR(bars[i].slider),slider_change,bars+i);
     multibar_thumb_set(MULTIBAR(bars[i].slider),-140.,0);
@@ -587,49 +813,53 @@
     multibar_thumb_set(MULTIBAR(bars[i].slider),0.,2);
     multibar_thumb_bounds(MULTIBAR(bars[i].slider),-140,0);
     multibar_thumb_increment(MULTIBAR(bars[i].slider),1.,10.);
-
+    
     gtk_misc_set_alignment(GTK_MISC(label),1,.5);
-
+      
     gtk_table_attach(GTK_TABLE(slidertable),label,0,1,i+1,i+2,
                      GTK_FILL,0,10,0);
     gtk_table_attach(GTK_TABLE(slidertable),bars[i].readoutg,2,3,i+1,i+2,
-		     GTK_FILL,0,0,0);
+		     0,0,0,0);
     gtk_table_attach(GTK_TABLE(slidertable),bars[i].readoute,3,4,i+1,i+2,
-		     GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(slidertable),bars[i].readoutc,4,5,i+1,i+2,
-		     GTK_FILL,0,0,0);
-    gtk_table_attach(GTK_TABLE(slidertable),bars[i].slider,1,2,i+1,i+2,
-		     GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,0,0);
+		       0,0,0,0);
+      gtk_table_attach(GTK_TABLE(slidertable),bars[i].readoutc,4,5,i+1,i+2,
+		       0,0,0,0);
+      gtk_table_attach(GTK_TABLE(slidertable),bars[i].slider,1,2,i+1,i+2,
+		       GTK_FILL|GTK_EXPAND,GTK_EXPAND,0,0);
   }
 
+  subpanel_show_all_but_toplevel(panel);
+
+  /* Now unmap the sliders we don't want */
+  static_octave(NULL,(gpointer)2);
+
 }
 
 static float **peakfeed=0;
 static float **rmsfeed=0;
 
 void compandpanel_feedback(int displayit){
-  int i;
+  int i,bands;
   if(!peakfeed){
-    peakfeed=malloc(sizeof(*peakfeed)*multicomp_freqs);
-    rmsfeed=malloc(sizeof(*rmsfeed)*multicomp_freqs);
+    peakfeed=malloc(sizeof(*peakfeed)*multicomp_freqs_max);
+    rmsfeed=malloc(sizeof(*rmsfeed)*multicomp_freqs_max);
 
-    for(i=0;i<multicomp_freqs;i++){
+    for(i=0;i<multicomp_freqs_max;i++){
       peakfeed[i]=malloc(sizeof(**peakfeed)*input_ch);
       rmsfeed[i]=malloc(sizeof(**rmsfeed)*input_ch);
     }
   }
 
-#if 0  
-  if(pull_compand_feedback(peakfeed,rmsfeed)==1)
-    for(i=0;i<multicomp_freqs;i++)
+  if(pull_multicompand_feedback(peakfeed,rmsfeed,&bands)==1)
+    for(i=0;i<bands;i++)
       multibar_set(MULTIBAR(bars[i].slider),rmsfeed[i],peakfeed[i],
                    input_ch,(displayit && compand_visible));
-#endif
 }
 
 void compandpanel_reset(void){
-  int i;
-  for(i=0;i<multicomp_freqs;i++)
+  int i,j;
+  for(i=0;i<multicomp_freqs_max;i++)
     multibar_reset(MULTIBAR(bars[i].slider));
 }
 
+

<p><p>1.2       +1 -0      postfish/compandpanel.h

Index: compandpanel.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/compandpanel.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- compandpanel.h	20 Feb 2004 02:09:39 -0000	1.1
+++ compandpanel.h	8 Mar 2004 02:08:23 -0000	1.2
@@ -27,5 +27,6 @@
 
 extern void compandpanel_feedback(int displayit);
 extern void compandpanel_reset(void);
+extern void compandpanel_set_play(int playp);
 
 

<p><p>1.6       +1 -1      postfish/eq.c

Index: eq.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/eq.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- eq.c	29 Feb 2004 03:16:17 -0000	1.5
+++ eq.c	8 Mar 2004 02:08:23 -0000	1.6
@@ -43,7 +43,7 @@
 
 /* called only by initial setup */
 int eq_load(void){
-  return freq_load(&eq,eq_freq_list,eq_freqs,input_size);
+  return freq_load(&eq,eq_freq_list,eq_freqs);
 }
 
 /* called only in playback thread */

<p><p>1.7       +1 -0      postfish/eqpanel.c

Index: eqpanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/eqpanel.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- eqpanel.c	29 Feb 2004 03:16:17 -0000	1.6
+++ eqpanel.c	8 Mar 2004 02:08:23 -0000	1.7
@@ -101,6 +101,7 @@
   }
 
   gtk_box_pack_start(GTK_BOX(panel->subpanel_box),slidertable,1,1,4);
+  subpanel_show_all_but_toplevel(panel);
 
 }
 

<p><p>1.6       +97 -192   postfish/freq.c

Index: freq.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/freq.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- freq.c	29 Feb 2004 03:16:17 -0000	1.5
+++ freq.c	8 Mar 2004 02:08:23 -0000	1.6
@@ -49,55 +49,6 @@
   return (feedback_generic *)ret;
 }
 
-static int seq=0;
-static void _analysis(char *base,int i,float *v,int n,int bark,int dB){
-  int j;
-  FILE *of;
-  char buffer[80];
-
-  sprintf(buffer,"%s_%d.m",base,i);
-  of=fopen(buffer,"w");
-  
-  if(!of)perror("failed to open data dump file");
-  
-  for(j=0;j<n;j++){
-    if(bark){
-      float b=toBark((4000.f*j/n)+.25);
-      fprintf(of,"%f ",b);
-    }else
-      fprintf(of,"%f ",(float)j);
-    
-    if(dB){
-      float val=todB(hypot(v[j],v[j+1]));
-      if(val<-140)val=-140;
-      fprintf(of,"%f\n",val);
-      j++;
-     
-    }else{
-      fprintf(of,"%f\n",v[j]);
-    }
-  }
-  fclose(of);
-}
-
-static void _analysis_append(char *base,int basemod,float *v,int n,int off){
-  int j;
-  FILE *of;
-  char buffer[80];
-
-  sprintf(buffer,"%s_%d.m",base,basemod);
-  of=fopen(buffer,"a");
-  
-  if(!of)perror("failed to open data dump file");
-  
-  for(j=0;j<n;j++){
-    fprintf(of,"%f ",(float)j+off);    
-    fprintf(of,"%f\n",v[j]);
-  }
-  fprintf(of,"\n");
-  fclose(of);
-}
-
 /* total, peak, rms are pulled in array[freqs][input_ch] order */
 
 int pull_freq_feedback(freq_state *ff,float **peak,float **rms){
@@ -125,13 +76,12 @@
 }
 
 /* called only by initial setup */
-int freq_load(freq_state *f,float *frequencies, int bands, 
-	      int blocksize){
+int freq_load(freq_state *f,float *frequencies, int bands){
   int i,j;
-  
+  int blocksize=input_size*2;
   memset(f,0,sizeof(*f));
 
-  f->qblocksize=blocksize/2;
+  f->qblocksize=input_size;
   f->bands=bands;
   f->frequencies=frequencies;
 
@@ -158,11 +108,6 @@
   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];
 
-  /* unlike old postfish, we offer all frequencies via smoothly
-     supersampling the spectrum */
-  /* I'm too lazy to figure out the integral symbolically, use this
-     fancy CPU-thing for something */
-  
   f->fftwf_buffer = fftwf_malloc(sizeof(*f->fftwf_buffer) * input_ch);
   f->fftwf_backward = fftwf_malloc(sizeof(*f->fftwf_backward) * input_ch);
   f->fftwf_forward = fftwf_malloc(sizeof(*f->fftwf_forward) * input_ch);
@@ -286,7 +231,6 @@
 
   for(i=0;i<f->qblocksize*2+1;i++)
     sq_mags[i]=(work[i*2]*work[i*2]+work[i*2+1]*work[i*2+1])*64.;
-
   
   for(i=0;i<f->bands;i++){
     float *ho_window=f->ho_window[i];
@@ -312,36 +256,21 @@
 }
 
 static void lap_bypass(float *cache,float *in,float *lap,float *out,freq_state *f){
-  int i;
+  int i,j;
   if(out){
     /* we're bypassing, so the input data hasn't spread from the half->block window.
        The lap may well be spread though, so we can't cheat and ignore the last third */
     for(i=0;i<f->qblocksize;i++)
       out[i]=lap[i];
-
-    for(;i<f->qblocksize*2;i++)
-      out[i]=lap[i]+f->window[i-f->qblocksize]*cache[i];
-
-    if(f->qblocksize*2<input_size)
-      for(;i<f->qblocksize*3;i++)
-	out[i]=lap[i]+cache[i];
-    
-    if(f->qblocksize*3<input_size)
-      memcpy(out+f->qblocksize*3,cache+f->qblocksize*3,
-	     sizeof(*out)*(input_size-f->qblocksize*3));
   }
 
   /* keep lap up to date; bypassed data has not spread from the half-block padded window */
-  if(f->qblocksize<input_size/2){
-    memcpy(lap,in,f->qblocksize*sizeof(*lap));
-    for(i=f->qblocksize;i<f->qblocksize*2;i++)
-      lap[i]=in[i]*f->window[i];
-  }else{
-    for(i=0;i<f->qblocksize;i++)
-      lap[i]=lap[i+f->qblocksize*2]+in[i];
-    for(;i<f->qblocksize*2;i++)
-      lap[i]=in[i]*f->window[i];
-  }
+  for(i=0;i<f->qblocksize;i++)
+    lap[i]=lap[i+f->qblocksize]+cache[i]*f->window[i];
+
+  for(j=0;i<f->qblocksize*2;i++,j++)
+    lap[i]=lap[i+f->qblocksize]+in[j]*f->window[i];
+
   memset(lap+f->qblocksize*2,0,f->qblocksize*sizeof(*lap));
 }
 
@@ -361,6 +290,43 @@
   
 }
 
+static void freq_transwork(freq_state *f,time_linkage *in){
+  int i,j;
+  for(i=0;i<input_ch;i++){
+    /* extrapolation mechanism; avoid harsh transients at edges */
+    if(f->fillstate==0)
+      preextrapolate_helper(in->data[i],input_size,
+			    f->cache[i],input_size);
+    
+    if(in->samples<in->size)
+      postextrapolate_helper(f->cache[i],input_size,
+			     in->data[i],in->samples,
+			     in->data[i]+in->samples,
+			     in->size-in->samples);
+    
+    memset(f->fftwf_buffer[i],0,
+	   sizeof(**f->fftwf_buffer)*f->qblocksize);
+    
+    memcpy(f->fftwf_buffer[i]+f->qblocksize,
+	   f->cache[i],
+	   sizeof(**f->fftwf_buffer)*f->qblocksize);
+    
+    memcpy(f->fftwf_buffer[i]+f->qblocksize*2,
+	   in->data[i],
+	   sizeof(**f->fftwf_buffer)*f->qblocksize);
+    
+    memset(f->fftwf_buffer[i]+f->qblocksize*3,0,
+	   sizeof(**f->fftwf_buffer)*f->qblocksize);
+    
+    for(j=0;j<f->qblocksize*2;j++)
+      f->fftwf_buffer[i][j+f->qblocksize]*=.25*f->window[j]/f->qblocksize;
+    /* transform the time data */
+    
+    fftwf_execute(f->fftwf_forward[i]);
+  }
+}
+
+
 /* called only by playback thread */
 time_linkage *freq_read(time_linkage *in, freq_state *f,
                         void (*func)(freq_state *f,float **data,
@@ -414,63 +380,51 @@
 
     }else{
 
-      /* extrapolation mechanism; avoid harsh transients at edges */
+      freq_transwork(f,in);
+      func(f,f->fftwf_buffer,peakp,rmsp);
+      blocks++;	
+      
       for(i=0;i<input_ch;i++){
-	preextrapolate_helper(in->data[i],input_size,
-			      f->cache[i],input_size);
+	feedback_work(f,peak[i],rms[i],feedback_peak[i],feedback_rms[i]);
+	fftwf_execute(f->fftwf_backward[i]);
+	lap_work(f->fftwf_buffer[i],f->lap[i],0,f);
         
-	if(in->samples<in->size)
-	  postextrapolate_helper(f->cache[i],input_size,
-				 in->data[i],in->samples,
-				 in->data[i]+in->samples,
-				 in->size-in->samples);
       }
+    }
 
-      /* only need the last two ops to prime the lapping, but they're
-	 the complex ones that span the cache/in gap.  We'd need
-	 three, but the passed input window is zero for the first/last
-	 quarter block and the 'cache' is zero (so the middle of the
-	 first window is also zero). */
+    for(i=0;i<input_ch;i++){
+      float *temp=in->data[i];
+      memset(f->cache[i],0,sizeof(**f->cache)*input_size);
+      in->data[i]=f->cache[i];
+      f->cache[i]=temp;
+    }
       
-      for(j=0;j<2;j++){
-	for(i=0;i<input_ch;i++){
-	  switch(j){
-	  case 0:
-	    memcpy(f->fftwf_buffer[i]+f->qblocksize,
-		   f->cache[i]+input_size-f->qblocksize,
-		   sizeof(**f->fftwf_buffer)*f->qblocksize);
-	    memcpy(f->fftwf_buffer[i]+f->qblocksize*2,
-		   in->data[i],
-		   sizeof(**f->fftwf_buffer)*f->qblocksize);
-	    break;
-	  case 1:
-	    memcpy(f->fftwf_buffer[i]+f->qblocksize,
-		   in->data[i],
-		   sizeof(**f->fftwf_buffer)*f->qblocksize*2);
-	    break;
-	  }
-	  
-
-	  memset(f->fftwf_buffer[i],0,
-		 sizeof(**f->fftwf_buffer)*f->qblocksize);
-	  memset(f->fftwf_buffer[i]+f->qblocksize*3,0,
-		 sizeof(**f->fftwf_buffer)*f->qblocksize);
-	  for(k=0;k<f->qblocksize*2;k++)
-	    f->fftwf_buffer[i][k+f->qblocksize]*=.25*f->window[k]/f->qblocksize;
-	  /* transform the time data */
+    f->cache_samples=in->samples;
+    f->fillstate=1;
+    f->out.samples=0;
+    if(in->samples==in->size)goto tidy_up;
+    
+    for(i=0;i<input_ch;i++)
+      memset(in->data[i],0,sizeof(**in->data)*in->size);
+    in->samples=0;
+    /* fall through */
+    
+  case 1: /* finish priming the lapping and cache */
 
-	  fftwf_execute(f->fftwf_forward[i]);
-	}
-	
-	func(f,f->fftwf_buffer,peakp,rmsp);
-	blocks++;	
-	
-	for(i=0;i<input_ch;i++){
-	  feedback_work(f,peak[i],rms[i],feedback_peak[i],feedback_rms[i]);
-	  fftwf_execute(f->fftwf_backward[i]);
-	  lap_work(f->fftwf_buffer[i],f->lap[i],0,f);
+    if(bypass){
+      for(i=0;i<input_ch;i++)
+	lap_bypass(f->cache[i],in->data[i],f->lap[i],0,f);
+    }else{
 
-	}
+      freq_transwork(f,in);
+      func(f,f->fftwf_buffer,peakp,rmsp);
+      blocks++;	
+      
+      for(i=0;i<input_ch;i++){
+	feedback_work(f,peak[i],rms[i],feedback_peak[i],feedback_rms[i]);
+	fftwf_execute(f->fftwf_backward[i]);
+	lap_work(f->fftwf_buffer[i],f->lap[i],0,f);
+	
       }
     }
 
@@ -482,7 +436,7 @@
     }
       
     f->cache_samples=in->samples;
-    f->fillstate=1;
+    f->fillstate=2;
     f->out.samples=0;
     if(in->samples==in->size)goto tidy_up;
     
@@ -491,72 +445,23 @@
     in->samples=0;
     /* fall through */
     
-  case 1: /* nominal processing */
+  case 2: /* nominal processing */
 
     if(bypass){
-      /* bypass as above but deal with lapping whole block in and out */
-
       for(i=0;i<input_ch;i++)
         lap_bypass(f->cache[i],in->data[i],f->lap[i],f->out.data[i],f);
 
     }else{
 
-      /* extrapolation mechanism; avoid harsh transients at edges */
+      freq_transwork(f,in);
+      func(f,f->fftwf_buffer,peakp,rmsp);
+      blocks++;	
+      
       for(i=0;i<input_ch;i++){
-	if(in->samples<in->size)
-	  postextrapolate_helper(f->cache[i],input_size,
-				 in->data[i],in->samples,
-				 in->data[i]+in->samples,
-				 in->size-in->samples);
-      }
-
-      for(j=input_size/f->qblocksize-1;j>=0;j--){
-	for(i=0;i<input_ch;i++){
-	  switch(j){
-
-	  case 0:
-	    /* last block, needed because the half-block wide non-zero
-	       data section of the window will spread out to full window
-	       width when we convolve */
-	    memcpy(f->fftwf_buffer[i]+f->qblocksize,in->data[i],
-		   f->qblocksize*2*sizeof(**f->fftwf_buffer));
-	    break;
-	  case 1:
-	    /* second-to-last block, nonzero section of the input
-               spans the cache and input blocks */
-	    memcpy(f->fftwf_buffer[i]+f->qblocksize,
-		   f->cache[i]+input_size-f->qblocksize,
-		   sizeof(**f->fftwf_buffer)*f->qblocksize);
-	    memcpy(f->fftwf_buffer[i]+f->qblocksize*2,
-		   in->data[i],
-		   sizeof(**f->fftwf_buffer)*f->qblocksize);
-	    break;
-	  default:
-	    memcpy(f->fftwf_buffer[i]+f->qblocksize,
-		   f->cache[i]+input_size-(f->qblocksize*j),
-		   f->qblocksize*2*sizeof(**f->fftwf_buffer));
-	    break;
-	  }
-
-	  memset(f->fftwf_buffer[i],0,
-		 sizeof(**f->fftwf_buffer)*f->qblocksize);
-	  memset(f->fftwf_buffer[i]+f->qblocksize*3,0,
-		 sizeof(**f->fftwf_buffer)*f->qblocksize);
-	  for(k=0;k<f->qblocksize*2;k++)
-	    f->fftwf_buffer[i][k+f->qblocksize]*=.25*f->window[k]/f->qblocksize;
-	  /* transform the time data */
-	  fftwf_execute(f->fftwf_forward[i]);
-	}
+	feedback_work(f,peak[i],rms[i],feedback_peak[i],feedback_rms[i]);
+	fftwf_execute(f->fftwf_backward[i]);
+	lap_work(f->fftwf_buffer[i],f->lap[i],f->out.data[i],f);
         
-	func(f,f->fftwf_buffer,peakp,rmsp);
-	blocks++;	
-	
-	for(i=0;i<input_ch;i++){
-	  feedback_work(f,peak[i],rms[i],feedback_peak[i],feedback_rms[i]);
-	  fftwf_execute(f->fftwf_backward[i]);
-	  lap_work(f->fftwf_buffer[i],f->lap[i],
-		   f->out.data[i]+input_size-f->qblocksize*(j+1),f);
-	}
       }
     }
 
@@ -567,14 +472,14 @@
     }
     f->out.samples=f->cache_samples;
     f->cache_samples=in->samples;
-    if(f->out.samples<f->out.size)f->fillstate=2;
+    if(f->out.samples<f->out.size)f->fillstate=3;
     break;
-  case 2: /* we've pushed out EOF already */
+  case 3: /* we've pushed out EOF already */
     f->out.samples=0;
   }
   
   /* finish up the state feedabck */
-  if(!bypass){
+  if(!bypass && blocks){
     int j;
     float scale=1./blocks;
     freq_feedback *ff=

<p><p>1.5       +4 -4      postfish/freq.h

Index: freq.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/freq.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- freq.h	29 Feb 2004 03:16:17 -0000	1.4
+++ freq.h	8 Mar 2004 02:08:23 -0000	1.5
@@ -44,14 +44,14 @@
   float **cache;
   int cache_samples;
   int fillstate;     /* 0: uninitialized
-			1: normal
-			2: eof processed */
+			1: half-primed
+			2: nominal
+			3: eof processed */
 } freq_state;
 
 extern void freq_transform_work(float *work,freq_state *f);
 extern int pull_freq_feedback(freq_state *ff,float **peak,float **rms);
-extern int freq_load(freq_state *f,float *frequencies, int bands, 
-		     int blocksize);
+extern int freq_load(freq_state *f,float *frequencies, int bands);
 extern int freq_reset(freq_state *f);
 extern time_linkage *freq_read(time_linkage *in, freq_state *f,
                                void (*func)(freq_state *f,

<p><p>1.36      +12 -16    postfish/mainpanel.c

Index: mainpanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/mainpanel.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- mainpanel.c	29 Feb 2004 03:16:17 -0000	1.35
+++ mainpanel.c	8 Mar 2004 02:08:23 -0000	1.36
@@ -357,7 +357,7 @@
 
 
   switch(event->keyval){
-  case GDK_m:
+  case GDK_t:
     /* trigger master dB */
     gtk_widget_activate(p->masterdB_a);
     break;
@@ -380,24 +380,21 @@
   case GDK_d:
     gtk_widget_activate(p->buttonactive[0]);
     break;
-  case GDK_t:
+  case GDK_c:
     gtk_widget_activate(p->buttonactive[1]);
     break;
-  case GDK_n:
+  case GDK_m:
     gtk_widget_activate(p->buttonactive[2]);
     break;
-  case GDK_e:
+  case GDK_s:
     gtk_widget_activate(p->buttonactive[3]);
     break;
-  case GDK_c:
+  case GDK_e:
     gtk_widget_activate(p->buttonactive[4]);
     break;
   case GDK_l:
     gtk_widget_activate(p->buttonactive[5]);
     break;
-  case GDK_o:
-    gtk_widget_activate(p->buttonactive[6]);
-    break;
   case GDK_a:
     gtk_widget_activate(p->cue_set[0]);
     break;
@@ -626,7 +623,7 @@
       GtkWidget *box=gtk_hbox_new(0,0);
 
       GtkWidget *masterlabel=gtk_label_new("master:");
-      panel->masterdB_a=gtk_toggle_button_new_with_label("[m] active");
+      panel->masterdB_a=gtk_toggle_button_new_with_label("a[t]ten");
       panel->masterdB_r=readout_new("  0.0dB");
       panel->masterdB_s=multibar_slider_new(10,sliderlabels,sliderlevels,1);
       
@@ -638,9 +635,9 @@
       gtk_table_attach(GTK_TABLE(ttable),masterlabel,0,1,3,4,
                        GTK_FILL,GTK_FILL,0,0);
       
-      gtk_box_pack_start(GTK_BOX(box),panel->masterdB_a,0,0,2);
       gtk_box_pack_start(GTK_BOX(box),panel->masterdB_s,1,1,0);
       gtk_box_pack_start(GTK_BOX(box),panel->masterdB_r,0,0,0);
+      gtk_box_pack_start(GTK_BOX(box),panel->masterdB_a,0,0,0);
       
       gtk_table_attach_defaults(GTK_TABLE(ttable),box,1,3,3,4);
 
@@ -819,12 +816,11 @@
   }
 
   mainpanel_panelentry(panel,"_Declip ","[d]",0,clippanel_create);
-  mainpanel_panelentry(panel,"Cross_Talk ","[t]",1,0);
-  mainpanel_panelentry(panel,"_Compand/Gate ","[c]",2,compandpanel_create);
-  mainpanel_panelentry(panel,"_Equalizer ","[e]",3,eqpanel_create);
-  mainpanel_panelentry(panel,"_Limiter ","[l]",4,0);
-  mainpanel_panelentry(panel,"_Output Cal. ","[o]",5,0);
-
+  mainpanel_panelentry(panel,"_Crosstalk ","[c]",1,0);
+  mainpanel_panelentry(panel,"_Multicomp ","[m]",2,compandpanel_create);
+  mainpanel_panelentry(panel,"_Singlecomp ","[s]",3,0);
+  mainpanel_panelentry(panel,"_Equalizer ","[e]",4,eqpanel_create);
+  mainpanel_panelentry(panel,"_Limiter ","[l]",5,0);
 
   g_signal_connect (G_OBJECT (panel->toplevel), "delete_event",
                     G_CALLBACK (shutdown), NULL);

<p><p>1.24      +3 -3      postfish/multibar.c

Index: multibar.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/multibar.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- multibar.c	29 Feb 2004 03:16:17 -0000	1.23
+++ multibar.c	8 Mar 2004 02:08:23 -0000	1.24
@@ -69,7 +69,7 @@
     xpad=2;
   }else{
     if(m->thumbs>1)
-      xpad=height*3/4+6;
+      xpad=((height+1)/2)+(height/2-3)*3/2+1;
     else
       xpad=height/2+1;
   }
@@ -582,7 +582,7 @@
       gdk_draw_line(m->backing,m->boxcolor,x,y+(y1-y)/2,x,0);
 
       if(m->thumbfocus==num){
-	for(i=0;i<height/2;i++)
+	for(i=0;i<(height-1)/2;i++)
           for(j=0;j<=i*2;j++)
             if(!(j&1))
               gdk_draw_point(m->backing,black_gc,x-i+j,y+i+2);
@@ -636,7 +636,7 @@
   }else{
     maxy+=3;
     if(m->thumbs>1)
-      xpad=maxy+(maxy/2-1)/2-1+2;
+      xpad=((maxy+1)/2)+(maxy/2-3)*3/2+1;
     else
       xpad=maxy/2+1+2;
   }

<p><p>1.2       +525 -76   postfish/multicompand.c

Index: multicompand.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/multicompand.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- multicompand.c	29 Feb 2004 03:16:17 -0000	1.1
+++ multicompand.c	8 Mar 2004 02:08:23 -0000	1.2
@@ -21,10 +21,13 @@
  * 
  */
 
+#include "postfish.h"
+#include "feedback.h"
 #include "multicompand.h"
 #include <fftw3.h>
 #include "subband.h"
 
+static int offset=0;
 static void _analysis(char *base,int i,float *v,int n,int bark,int dB){
   int j;
   FILE *of;
@@ -83,149 +86,595 @@
    about a half-order of magnitude less roundoff noise from gain
    (compared to other IIR families) */
 
-static float iirg_list[7]={
+static float iirg_list[8]={
   4.875178475e+06,  // 5
   1.008216556e+06,  // 11
   2.524889925e+05,  // 22
   6.3053949794e+04, // 44
   1.5872282930e+04, // 88
   4.086422543e+03,  // 175
-  1.049342702e+03   // 350
+  1.049342702e+03,  // 350
+  2.764099277e+02   // 700
 };
 
-static float iirc_list[7][2]={
+static float iirc_list[8][2]={
   {1.9984308946, -.9984317150},  // 5
   {1.9965490514, -.9965530188},  // 11
   {1.9931020727, -.9931179150},  // 22
   {1.9861887623, -.98625220002}, // 44
   {1.9724411246, -.97269313627}, // 88
   {1.9455669653, -.9465458165},  // 175
-  {1.8921217885, -.8959336985}   // 350
+  {1.8921217885, -.8959336985},  // 350
+  {1.7881166933, -0.8025879536}  // 700
 };
 
-static float iir_corner_list[7]={5,11,22,44,88,175,350};
-static float iir_rmsoffset_list[7]={1048,524,262,131,65,32,16};
-static float iir_peakoffset_list[7]={7200,3600,1800,900,450,225,112};
-
-/* ugly, ugly ugly */
-static float iirx[2];
-static float iiry[2];
-static float iirg;
-static float iirc[2];
-
-static inline float iir(float x){ 
-  float y=
-    (iirx[1]+iirx[0]*2.+x)/iirg
-    + iiry[1]*iirc[1]
-    + iiry[0]*iirc[0];
-  iiry[1]=iiry[0];iiry[0]=y;
-  iirx[1]=iirx[0];iirx[0]=x;
-  return y;
-}
+static float iir_corner_list[8]={5,11,22,44,88,175,350,700};
+static float iir_rmsoffset_list[8]={1048,524,262,131,65,32,16,8};
+static float iir_peakoffset_list[8]={5400,2700,1350,675,338,169,84,42};
+
+#if NASTY_IEEE_FLOAT32_HACK_IS_FASTER_THAN_LOG
+
+#define todB_p(x) (((*(int32_t*)(x)) & 0x7fffffff) * 7.1771144e-7f - 764.27118f)
+
+#else
+
+#define todB_p(x) todB(*(x))
+
+#endif
 
 typedef struct {
-  float peak_shelf_y[1];
+  /* RMS follower state */
   float rms_smooth_y[2];
   float rms_smooth_x[2];
 
-  float main_decay_chase;
-  float envelope_decay_chase;
+  float static_c_decay_chase;
+  float static_e_decay_chase;
+  float static_g_decay_chase;
   float suppress_decay_chase;
 
-  float env1[2];
-  float env2[2];
+  float env1_x[2];
+  float env1_y[2];
+  float env2_x[2];
+  float env2_y[2];
 
+  int dummymarker;
 } envelope_state;
 
 typedef struct {
   subband_state ss;
+  subband_window sw[multicomp_banks];
 
-  int rmschoice[multicomp_freqs];
+  int rmschoice[multicomp_banks][multicomp_freqs_max];
+  int attack[multicomp_banks][multicomp_freqs_max];
+  int decay[multicomp_banks][multicomp_freqs_max];
 
   envelope_state **e;
+  sig_atomic_t pending_bank;
+  sig_atomic_t active_bank;
 } multicompand_state;
 
 sig_atomic_t compand_visible;
 sig_atomic_t compand_active;
+
+banked_compand_settings bc[multicomp_banks];
+other_compand_settings c;
 multicompand_state ms;
-compand_settings c;
 
+int pull_multicompand_feedback(float **peak,float **rms,int *bands){
+  return pull_subband_feedback(&ms.ss,peak,rms,bands);
+}
+
+static sig_atomic_t pending_bank=0;
+static sig_atomic_t reading=0;
 void multicompand_reset(){
+  int h,i,j;
+  
+  subband_reset(&ms.ss);
+
+  for(i=0;i<input_ch;i++)
+    for(j=0;j<multicomp_freqs_max;j++){
+      memset(&ms.e[j][i],0,sizeof(**ms.e));
+      ms.e[j][i].static_c_decay_chase=0.;
+      ms.e[j][i].static_e_decay_chase=0.;
+      ms.e[j][i].static_g_decay_chase=0.;
+    }
 
 }
 
 int multicompand_load(void){
-  int i,j;
+  int h,i,j;
+  int qblocksize=input_size/8;
   memset(&ms,0,sizeof(ms));
 
-  subband_load(&ms.ss,multicomp_freq_list,multicomp_freqs);
+  subband_load(&ms.ss,multicomp_freqs_max,qblocksize);
 
-  /* select the RMS follower filters to use according to 
-     sample rate and band frequency */
-  for(i=0;i<multicomp_freqs;i++){
-    /* select a filter with a corner frequency of about 1/8 the
-       band center. Don't go lower than 11 or higher than the 44 */
-    double bf=multicomp_freq_list[i];
+  for(h=0;h<multicomp_banks;h++){
+    subband_load_freqs(&ms.ss,&ms.sw[h],multicomp_freq_list[h],
+		       multicomp_freqs[h]);
+    
+    /* select the RMS follower filters to use according to 
+       sample rate and band frequency */
+    for(i=0;i<multicomp_freqs[h];i++){
+      /* select a filter with a corner frequency of about 1/8 the
+	 band center. Don't go lower than 11 or higher than the 44 */
+      /* also... make sure 'workahead' is within input size restrictions */
+      double bf=multicomp_freq_list[h][i];
+      
+      for(j=7;j>=0;j--)
+	if(iir_peakoffset_list[j]<=input_size*2-qblocksize*3){
+	  ms.rmschoice[h][i]=j;
+	  if(iir_corner_list[j]*input_rate/44100 < bf*.25 &&
+	    iir_corner_list[j]*input_rate/44100 < 100)
+	    break;
+	}
+
+      for(j=7;j>=0;j--)
+	if(iir_peakoffset_list[j]<=input_size*2-qblocksize*3){
+	  ms.attack[h][i]=j;
+	  if(iir_corner_list[j]*input_rate/44100 < bf*.5)
+	    break;
+	}
+      ms.decay[h][i]=j;
+      for(j=7;j>=0;j--)
+	if(iir_peakoffset_list[j]<=input_size*2-qblocksize*3){
+	  ms.decay[h][i]=j;
+	  if(iir_corner_list[j]*input_rate/44100 < 30 &&
+	     j<=ms.attack[h][i])
+	    break;
+	}
+      
+      fprintf(stderr,"band %d: filter %d/%d/%d, corner frequency %f, %f-%f\n",i,
+	      ms.rmschoice[h][i],
+	      ms.attack[h][i],
+	      ms.decay[h][i],
+	      iir_corner_list[ms.rmschoice[h][i]],
+	      iir_corner_list[ms.attack[h][i]],
+	      iir_corner_list[ms.decay[h][i]]);
+      
+    }
+  }
+  
+  ms.e=calloc(multicomp_freqs_max,sizeof(*(ms.e)));
+  
+  for(i=0;i<multicomp_freqs_max;i++){
+    ms.e[i]=calloc(input_ch,sizeof(**(ms.e)));
+    
+    for(j=0;j<input_ch;j++){
+      ms.e[i][j].static_c_decay_chase=0.;
+      ms.e[i][j].static_e_decay_chase=0.;
+      ms.e[i][j].static_g_decay_chase=0.;
+    }
+  }
+  
+  ms.active_bank=0;
 
-    ms.rmschoice[i]=3;
-    for(j=1;j<4;j++)
-      if(iir_corner_list[j]*input_rate/44100 > bf*.125){
-	ms.rmschoice[i]=j;
-	break;
+  return 0;
+}
+
+/* The Bessel filter followers are inlined and unrolled here as later
+   to avoid some really shockingly bad code generation by gcc on x86 */
+static void rms_chase(float *rms, int i, int linkp, int filternum,
+		      envelope_state *e, float **xxi){
+  int k,l;
+  float iirc0,iirc1;
+  float iirg,x,y;
+  float iirx0,iirx1;
+  float iiry0,iiry1;
+
+  if(linkp==0 || i==0){
+    float val;
+    int ahead=iir_rmsoffset_list[filternum];
+    iirg=iirg_list[filternum];
+    iirc0=iirc_list[filternum][0];
+    iirc1=iirc_list[filternum][1];
+    if(linkp)memset(rms,0,sizeof(*rms)*input_size);
+    
+    for(l=i;l<(linkp?input_ch:i+1);l++){
+      float *xx=xxi[l];
+      iirx0=e[l].rms_smooth_x[0];
+      iirx1=e[l].rms_smooth_x[1];
+      iiry0=e[l].rms_smooth_y[0];
+      iiry1=e[l].rms_smooth_y[1];
+      
+      for(k=0;k<input_size;k+=2){
+	y=x=(xx[k+ahead]*xx[k+ahead])/iirg;
+	y+=iirx0;
+	y+=iirx0;
+	y+=iirx1;
+	y+=iiry0*iirc0;
+	y+=iiry1*iirc1;
+	
+	iirx1=x;
+	rms[k]=iiry1=y;
+	
+	y=x=(xx[k+ahead+1]*xx[k+ahead+1])/iirg;
+	y+=iirx1;
+	y+=iirx1;
+	y+=iirx0;
+	y+=iiry1*iirc0;
+	y+=iiry0*iirc1;
+	
+	iirx0=x;
+	rms[k+1]=iiry0=y;
+      }
+
+      e[l].rms_smooth_x[0]=iirx0;
+      e[l].rms_smooth_x[1]=iirx1;
+      e[l].rms_smooth_y[0]=iiry0;
+      e[l].rms_smooth_y[1]=iiry1;
+      
+    }
+    
+    {
+      float scale=(linkp?1./input_ch:1);
+      for(k=0;k<input_size;k++){
+	val=fabs(rms[k]*scale);
+	rms[k]=sqrt(val);
       }
+    } 
 
-    fprintf(stderr,"band %d %fHz filter corner %f\n",
-	    i,bf,iir_corner_list[ms.rmschoice[i]]);
+    for(k=0;k<input_size;k++)
+      rms[k]=todB_p(rms+k);
+    
   }
+}
 
-  ms.e=calloc(input_ch,sizeof(*(ms.e)));
-  for(i=0;i<input_ch;i++)
-    ms.e[i]=calloc(multicomp_freqs,sizeof(**(ms.e)));
+static void peak_chase(float *peak, int i, int linkp, int filternum,
+		       float **xxi){
+  int l;
+  if(linkp==0 || i==0){
+    memset(peak,0,sizeof(*peak)*input_size);
+    for(l=i;l<(linkp?input_ch:i+1);l++){
+      
+      float *x=xxi[l];
+      int ii,jj;
+      int loc=0;
+      float val=fabs(x[0]);
+      int ahead=iir_peakoffset_list[filternum];
+      
+      /* find highest point in next [ahead] */
+      for(ii=1;ii<ahead;ii++)
+	if(fabs(x[ii])>val){
+	  val=fabs(x[ii]);
+	  loc=ii;
+	}
+      if(val>peak[0])peak[0]=val;
+      
+      for(ii=1;ii<input_size;ii++){
+	if(fabs(x[ii+ahead])>val){
+	  val=fabs(x[ii+ahead]);
+	  loc=ii+ahead;
+	}	  
+	if(ii>=loc){
+	  /* backfill */
+	  val=0;
+	  for(jj=ii+ahead-1;jj>=ii;jj--){
+	    if(fabs(x[jj])>val)val=fabs(x[jj]);
+	    if(jj<input_size && val>peak[jj])peak[jj]=val;
+	  }
+	  val=fabs(x[ii+ahead-1]);
+	  loc=ii+ahead;
+	}
+	if(val>peak[ii])peak[ii]=val; 
+      }
+      
+      for(ii=0;ii<input_size;ii++)
+	peak[ii]=todB_p(peak+ii);
+    }
+  }
+}
+
+static void static_compand(float *peak, float *rms, float *gain, 
+			   float gate,float expand, float compress,
+			   envelope_state *e){
+  int ii;
+  float current_c=e->static_c_decay_chase;
+  float current_e=e->static_e_decay_chase;
+  float current_g=e->static_g_decay_chase;
+
+  float decay_c=c.static_c_decay/(float)(1024*1024);
+  float decay_e=c.static_e_decay/(float)(1024*1024);
+  float decay_g=c.static_g_decay/(float)(1024*1024);
+
+  float *envelope=rms;
+  
+  float ratio_c=100./c.static_c_ratio;
+  float ratio_e=c.static_e_ratio/100.;
+  
+  if(c.static_mode)envelope=peak;
+  
+  for(ii=0;ii<input_size;ii++){
+    float adj=0.,local_adj;
+    float current=envelope[ii];
+    
+    /* compressor */
+    local_adj=0.;
+    if(current>compress){
+      float current_over=current-compress;
+      float compress_over=current_over*ratio_c;
+      local_adj=compress_over-current_over;
+    }
+    /* compressor decay is related to how quickly we release
+       attenuation */
+    current_c-=decay_c;
+    if(local_adj<current_c)current_c=local_adj;
+    adj+=current_c;
+
+    /* expander */
+    local_adj=0.;
+    if(current<expand){
+      float current_under=expand-current;
+      float expand_under=current_under*ratio_e;
+      local_adj= current_under-expand_under;
+    }
+    /* expander decay is related to how quickly we engage
+       attenuation */
+    current_e+=decay_e;
+    if(local_adj>current_e)current_e=local_adj;
+    adj+=current_e;
+
+    /* gate */
+    local_adj=0.;
+    if(current<gate){
+      float current_under=gate-current;
+      float gate_under=current_under*10.;
+      local_adj= current_under-gate_under;
+    }
+    /* gate decay is related to how quickly we engage
+       attenuation */
+    current_g+=decay_g;
+    if(local_adj>current_g)current_g=local_adj;
+    adj+=current_g;
+
+    
+    if(adj<-150.)adj=-150;
+    gain[ii]=adj;
+  }
+  
+  e->static_c_decay_chase=current_c;
+  e->static_e_decay_chase=current_e;
+  e->static_g_decay_chase=current_g;
+  
+}
+
+static void range_compand(float *peak, float *rms, float *gain){
+  int ii;
+  float *envelope; 
+  float ratio=1.+c.envelope_c/1000.;
+  
+  switch(c.envelope_mode){
+  case 0:
+    envelope=rms;
+    break;
+  default:
+    envelope=peak;
+    break;
+  }
+  
+  for(ii=0;ii<input_size;ii++){
+    float adj=0.;
+    float current=envelope[ii];
+    float target=current*ratio;
+    
+    gain[ii]+=target-current;
+  }
+}
+
+static void final_followers(float *gain,envelope_state *e,int attack,int decay){
+  float iirx0,iirx1;
+  float iiry0,iiry1;
+
+  float iirg_a;
+  float iirg_d;
+  float iirc0_a,iirc1_a;
+  float iirc0_d,iirc1_d;
+
+  float x,y;
+  int k;
+
+  iirg_a=iirg_list[attack];
+  iirc0_a=iirc_list[attack][0];
+  iirc1_a=iirc_list[attack][1];
+  iirg_d=iirg_list[decay];
+  iirc0_d=iirc_list[decay][0];
+  iirc1_d=iirc_list[decay][1];
+
+  iirx0=e->env1_x[0];
+  iirx1=e->env1_x[1];
+  iiry0=e->env1_y[0];
+  iiry1=e->env1_y[1];
+  
+  for(k=0;k<input_size;k+=2){
+    if(iiry0>iiry1){
+      /* decay */
+      y = (gain[k]+iirx0+iirx0+iirx1)/iirg_d + iiry0*iirc0_d+iiry1*iirc1_d;
+      iirx1=gain[k];
+      gain[k]=iiry1=y;
+    }else{
+      /* attack */
+      y = (gain[k]+iirx0+iirx0+iirx1)/iirg_a + iiry0*iirc0_a+iiry1*iirc1_a;
+      iirx1=gain[k];
+      gain[k]=iiry1=y;
+    }
+
+    if(iiry0>iiry1){
+      /* attack */
+      y = (gain[k+1]+iirx1+iirx1+iirx0)/iirg_a + iiry1*iirc0_a+iiry0*iirc1_a;
+      iirx0=gain[k+1];
+      gain[k+1]=iiry0=y;
+    }else{
+      /* decay */
+      y = (gain[k+1]+iirx1+iirx1+iirx0)/iirg_d + iiry1*iirc0_d+iiry0*iirc1_d;
+      iirx0=gain[k+1];
+      gain[k+1]=iiry0=y;
+    }
+  }
+  
+  e->env1_x[0]=iirx0;
+  e->env1_x[1]=iirx1;
+  e->env1_y[0]=iiry0;
+  e->env1_y[1]=iiry1;
+
+  iirx0=e->env2_x[0];
+  iirx1=e->env2_x[1];
+  iiry0=e->env2_y[0];
+  iiry1=e->env2_y[1];
+
+  for(k=0;k<input_size;k+=2){
+    if(iiry0>iiry1){
+      /* decay */
+      y = (gain[k]+iirx0+iirx0+iirx1)/iirg_d + iiry0*iirc0_d+iiry1*iirc1_d;
+      iirx1=gain[k];
+      gain[k]=iiry1=y;
+    }else{
+      /* attack */
+      y = (gain[k]+iirx0+iirx0+iirx1)/iirg_a + iiry0*iirc0_a+iiry1*iirc1_a;
+      iirx1=gain[k];
+      gain[k]=iiry1=y;
+    }
+
+    if(iiry0>iiry1){
+      /* attack */
+      y = (gain[k+1]+iirx1+iirx1+iirx0)/iirg_a + iiry1*iirc0_a+iiry0*iirc1_a;
+      iirx0=gain[k+1];
+      gain[k+1]=iiry0=y;
+    }else{
+      /* decay */
+      y = (gain[k+1]+iirx1+iirx1+iirx0)/iirg_d + iiry1*iirc0_d+iiry0*iirc1_d;
+      iirx0=gain[k+1];
+      gain[k+1]=iiry0=y;
+    }
+  }
+  
+  e->env2_x[0]=iirx0;
+  e->env2_x[1]=iirx1;
+  e->env2_y[0]=iiry0;
+  e->env2_y[1]=iiry1;
 
-  return 0;
 }
 
-static long offset=0;
-static void multicompand_work(void){
+static void multicompand_work(float **peakfeed,float **rmsfeed){
+  int i,j,k,l;
+  int link=c.link_mode;
   float rms[input_size];
   float peak[input_size];
-  int i,j,k;
+  float gain[input_size];
+  int bands=multicomp_freqs[ms.active_bank];
 
   /* we chase both peak and RMS forward at all times. All portions of
      the compander can use the raw values of one or the other at any
      time */
 
-  for(j=0;j<ms.ss.bands;j++){
+  for(j=0;j<bands;j++){
     for(i=0;i<input_ch;i++){
-      float *x=ms.ss.lap[i][j];
-      int ahead=iir_rmsoffset_list[ms.rmschoice[j]];
-      /* RMS chase [per channel] */
-      iirg=iirg_list[ms.rmschoice[j]];
-      iirc[0]=iirc_list[ms.rmschoice[j]][0];
-      iirc[1]=iirc_list[ms.rmschoice[j]][1];
-      iirx[0]=ms.e[i][j].rms_smooth_x[0];
-      iirx[1]=ms.e[i][j].rms_smooth_x[1];
-      iiry[0]=ms.e[i][j].rms_smooth_y[0];
-      iiry[1]=ms.e[i][j].rms_smooth_y[1];
-
-      for(k=0;k<input_size;k++)
-	rms[k]=sqrt(iir(x[k+ahead]*x[k+ahead]));
-
-      _analysis_append("band",j,x,input_size,offset);
-      _analysis_append("envelope",j,rms,input_size,offset);
-
-      ms.e[i][j].rms_smooth_x[0]=iirx[0];
-      ms.e[i][j].rms_smooth_x[1]=iirx[1];
-      ms.e[i][j].rms_smooth_y[0]=iiry[0];
-      ms.e[i][j].rms_smooth_y[1]=iiry[1];
+      
+      //_analysis_append("band",j,ms.ss.lap[j][i],input_size,offset);
+
+
+      /* RMS chase */
+      rms_chase(rms,i,link,ms.rmschoice[ms.active_bank][j],
+		ms.e[j],ms.ss.lap[j]);
+
+      /* peak shelving */
+      peak_chase(peak,i,link,ms.attack[ms.active_bank][j],
+		 ms.ss.lap[j]);
+
+      if(compand_active)
+	/* run the static compander */
+	static_compand(peak,rms,gain,
+		       (bc[ms.active_bank].static_g[j]+c.static_g_trim)/10.,
+		       (bc[ms.active_bank].static_e[j]+c.static_e_trim)/10.,
+		       (bc[ms.active_bank].static_c[j]+c.static_c_trim)/10.,
+		       &ms.e[j][i]);
+      else
+	memset(gain,0,sizeof(gain));
+
+      /* feedback displays the results of the static compander */
+      {
+	float *x=ms.ss.lap[j][i];
+	float rmsmax=-150,peakmax=-150;
+	
+	for(k=0;k<input_size;k++){
+	  int r=rms[k]+gain[k];
+	  x[k]*=fromdB(gain[k]);
+	  
+	  if(r>rmsmax)rmsmax=r;
+	  if(fabs(x[k])>peakmax)peakmax=fabs(x[k]);
+	}	    
+	
+	peakfeed[j][i]=todB(peakmax);
+	rmsfeed[j][i]=rmsmax;
+      }
+
+      if(compand_active){
+	float *x=ms.ss.lap[j][i];
 
+	/* run the range compander */
+	range_compand(peak,rms,gain);
+	
+	/* run the suppressor */
+	
+	//_analysis_append("peak",j,gain,input_size,offset);
+
+	/* Run the Bessel followers */
+	final_followers(gain,&ms.e[j][i],
+			ms.attack[ms.active_bank][j],
+			ms.decay[ms.active_bank][j]);
+	
+	//_analysis_append("gain",j,gain,input_size,offset);
+	
+
+	/* application to data */
+	for(k=0;k<input_size;k++)
+	  x[k]*=fromdB(gain[k]);
+
+      }else{
+	/* else reset the bessel followers */
+	ms.e[j][i].env1_x[0]=0.;
+	ms.e[j][i].env1_x[1]=0.;
+	ms.e[j][i].env1_y[0]=0.;
+	ms.e[j][i].env1_y[1]=0.;
+	ms.e[j][i].env2_x[0]=0.;
+	ms.e[j][i].env2_x[1]=0.;
+	ms.e[j][i].env2_y[0]=0.;
+	ms.e[j][i].env2_y[1]=0.;
+      }
     }
   }
 
   offset+=input_size;
 }
 
+void multicompand_set_bank(int bank){
+  ms.pending_bank=bank;
+}
+
+static int bypass_state;
+static int active_state;
 time_linkage *multicompand_read(time_linkage *in){
-  return subband_read(in,&ms.ss,multicompand_work,
-		      !(compand_visible||compand_active));
+  int i,j;
+  int pending=ms.pending_bank;
+  int bypass=!(compand_visible||compand_active);
+  
+  if(pending!=ms.active_bank || (bypass && !bypass_state)){
+    /* reset unused envelope followers to a known state for if/when
+       they're brought online */
+    
+    for(j=(bypass?0:multicomp_freqs[pending]);j<multicomp_freqs_max;j++){
+      for(i=0;i<input_ch;i++){
+	memset(&ms.e[j][i],0,sizeof(**ms.e));
+	ms.e[j][i].static_c_decay_chase=0.;
+	ms.e[j][i].static_e_decay_chase=0.;
+	ms.e[j][i].static_g_decay_chase=0.;
+      }
+    }
+  }
+   
+  ms.active_bank=ms.pending_bank;
+  bypass_state=bypass;
+
+  return subband_read(in,&ms.ss,&ms.sw[ms.active_bank],
+		      multicompand_work,bypass);
 }
+
+

<p><p>1.2       +34 -29    postfish/multicompand.h

Index: multicompand.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/multicompand.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- multicompand.h	29 Feb 2004 03:16:17 -0000	1.1
+++ multicompand.h	8 Mar 2004 02:08:23 -0000	1.2
@@ -23,42 +23,46 @@
 
 #include "postfish.h"
 
-#define multicomp_freqs 9
+#define multicomp_freqs_max 30
+#define multicomp_banks 3
 
-static float multicomp_freq_list[multicomp_freqs+1]={
-  63,
-  125,
-  250,
-  500,
-  1000,
-  2000,
-  4000,
-  8000,
-  16000,9e10};
-
-static char *multicomp_freq_labels[multicomp_freqs]={
-  "63",
-  "125",
-  "250",
-  "500",
-  "1k",
-  "2k",
-  "4k",
-  "8k",
-  "16k"
+static int multicomp_freqs[multicomp_banks]={10,20,30};
+static float multicomp_freq_list[multicomp_banks][multicomp_freqs_max+1]={
+  {31.5,63,125,250,500,1000,2000,4000,8000,16000,9e10},
+  {31.5,44,63,88,125,175,250,350,500,700,1000,1400,
+     2000,2800,4000,5600,8000,11000,16000,22000},
+  {25,31.5,40,50,63,80,100,125,160,200,250,315,
+   400,500,630,800,1000,1250,1600,2000,2500,3150,4000,5000,6300,
+   8000,10000,12500,16000,20000,9e10}
 };
 
+static char *multicomp_freq_labels[multicomp_banks][multicomp_freqs_max]={
+  {"31.5","63","125","250","500","1k","2k","4k","8k","16k"},
+  {"31.5","44","63","88","125","175","250","350","500","700","1k","1.4k",
+   "2k","2.8k","4k","5.6k","8k","11k","16k","22k"},
+  {"25","31.5","40","50","63","80","100","125","160","200","250","315",
+   "400","500","630","800","1k","1.2k","1.6k","2k","2.5k","3.1k","4k","5k",
+   "6.3k","8k","10k","12.5k","16k","20k"}
+};
+
+typedef struct {
+  sig_atomic_t static_g[multicomp_freqs_max];
+  sig_atomic_t static_e[multicomp_freqs_max];
+  sig_atomic_t static_c[multicomp_freqs_max];
+} banked_compand_settings;
+
 typedef struct {
   sig_atomic_t link_mode;
 
   sig_atomic_t static_mode;
-  sig_atomic_t static_trim;
-  sig_atomic_t static_decay;
+  sig_atomic_t static_c_trim;
+  sig_atomic_t static_e_trim;
+  sig_atomic_t static_g_trim;
+  sig_atomic_t static_c_decay;
+  sig_atomic_t static_e_decay;
+  sig_atomic_t static_g_decay;
   sig_atomic_t static_c_ratio;
   sig_atomic_t static_e_ratio;
-  sig_atomic_t static_g[multicomp_freqs];
-  sig_atomic_t static_e[multicomp_freqs];
-  sig_atomic_t static_c[multicomp_freqs];
 
   sig_atomic_t envelope_mode;
   sig_atomic_t envelope_c;
@@ -66,13 +70,14 @@
   sig_atomic_t suppress_mode;
   sig_atomic_t suppress_ratio;
   sig_atomic_t suppress_decay;
-  sig_atomic_t suppress_bias;
   sig_atomic_t suppress_depth;
 
-} compand_settings;
+} other_compand_settings;
 
 extern void multicompand_reset();
 extern int multicompand_load(void);
 extern time_linkage *multicompand_read(time_linkage *in);
+extern void multicompand_set_bank(int bank);
+extern int pull_multicompand_feedback(float **peak,float **rms,int *bands);
 
 

<p><p>1.9       +3 -1      postfish/postfish-gtkrc

Index: postfish-gtkrc
===================================================================
RCS file: /usr/local/cvsroot/postfish/postfish-gtkrc,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- postfish-gtkrc	20 Feb 2004 06:06:00 -0000	1.8
+++ postfish-gtkrc	8 Mar 2004 02:08:23 -0000	1.9
@@ -138,7 +138,7 @@
 }
 
 widget "*.GtkLabel" style "panel-text"
-widget "*.smallmarker*" style "small-marker"
+widget "*.smallmarker" style "small-marker"
 
 widget "*.color0" style "left"
 widget "*.color1" style "right"
@@ -150,6 +150,8 @@
 
 widget "*.choiceframe.*" style "frame-text"
 widget "*.GtkFrame.GtkLabel" style "frame-label"
+widget "*.GtkFrame.GtkHBox.GtkLabel" style "frame-label"
+widget "*.framelabel" style "frame-label"
 
 widget "*.Readout*" style "readout"
 widget "*.GtkEntry" style "readout"

<p><p>1.5       +14 -10    postfish/subpanel.c

Index: subpanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/subpanel.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- subpanel.c	20 Feb 2004 00:33:21 -0000	1.4
+++ subpanel.c	8 Mar 2004 02:08:23 -0000	1.5
@@ -28,7 +28,7 @@
 #include "windowbutton.h"
 #include "subpanel.h"
 
-static int clippanel_hide(GtkWidget *widget,
+static int subpanel_hide(GtkWidget *widget,
                           GdkEvent *event,
                           gpointer in){
   subpanel_generic *p=in;
@@ -51,10 +51,10 @@
   
   if(active){
     if(p->mappedvar)*p->mappedvar=1;
-    gtk_widget_show_all(p->subpanel_toplevel);
+    gtk_widget_show(p->subpanel_toplevel);
   }else{
     if(p->mappedvar)*p->mappedvar=0;
-    gtk_widget_hide_all(p->subpanel_toplevel);
+    gtk_widget_hide(p->subpanel_toplevel);
   }
 
   return FALSE;
@@ -104,6 +104,10 @@
   return TRUE;
 }
 
+void subpanel_show_all_but_toplevel(subpanel_generic *s){
+  gtk_widget_show_all(s->subpanel_topframe);
+}
+
 subpanel_generic *subpanel_create(postfish_mainpanel *mp,
                                   GtkWidget *windowbutton,
                                   GtkWidget *activebutton,
@@ -113,7 +117,6 @@
 
   subpanel_generic *panel=calloc(1,sizeof(*panel));
   GdkWindow *root=gdk_get_default_root_window();
-  GtkWidget *topframe=gtk_frame_new (NULL);
 
   GtkWidget *toplabelbox=gtk_event_box_new();
   GtkWidget *toplabelframe=gtk_frame_new(NULL);
@@ -124,6 +127,7 @@
   if(activebutton && activevar)
     toplabelab=gtk_toggle_button_new_with_label(shortcut);
   
+  panel->subpanel_topframe=gtk_frame_new (NULL);
   panel->subpanel_windowbutton=toplabelwb;
   panel->subpanel_activebutton=toplabelab;
 
@@ -146,12 +150,12 @@
   panel->subpanel_toplevel=gtk_window_new (GTK_WINDOW_TOPLEVEL);
   panel->mainpanel=mp;
 
-  gtk_container_add (GTK_CONTAINER (panel->subpanel_toplevel), topframe);
-  gtk_container_add (GTK_CONTAINER (topframe), panel->subpanel_box);
-  gtk_container_set_border_width (GTK_CONTAINER (topframe), 3);
+  gtk_container_add (GTK_CONTAINER (panel->subpanel_toplevel), panel->subpanel_topframe);
+  gtk_container_add (GTK_CONTAINER (panel->subpanel_topframe), panel->subpanel_box);
+  gtk_container_set_border_width (GTK_CONTAINER (panel->subpanel_topframe), 3);
   gtk_container_set_border_width (GTK_CONTAINER (panel->subpanel_box), 5);
-  gtk_frame_set_shadow_type(GTK_FRAME(topframe),GTK_SHADOW_NONE);
-  gtk_frame_set_label_widget(GTK_FRAME(topframe),toplabelbox);
+  gtk_frame_set_shadow_type(GTK_FRAME(panel->subpanel_topframe),GTK_SHADOW_NONE);
+  gtk_frame_set_label_widget(GTK_FRAME(panel->subpanel_topframe),toplabelbox);
 
     
   /* space *always* means play/pause */
@@ -165,7 +169,7 @@
 
   /* delete should == hide */
   g_signal_connect (G_OBJECT (panel->subpanel_toplevel), "delete-event",
-		    G_CALLBACK (clippanel_hide), 
+		    G_CALLBACK (subpanel_hide), 
                     panel);
 
   /* link the mainpanel and subpanel buttons */

<p><p>1.3       +2 -0      postfish/subpanel.h

Index: subpanel.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/subpanel.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- subpanel.h	20 Feb 2004 00:33:21 -0000	1.2
+++ subpanel.h	8 Mar 2004 02:08:23 -0000	1.3
@@ -27,6 +27,7 @@
   GtkWidget *subpanel_windowbutton;
   GtkWidget *subpanel_activebutton;
   GtkWidget *subpanel_toplevel;
+  GtkWidget *subpanel_topframe;
   GtkWidget *subpanel_box;
   sig_atomic_t *activevar;
   sig_atomic_t *mappedvar;
@@ -40,3 +41,4 @@
                                          sig_atomic_t *activevar,
                                          sig_atomic_t *mappedvar,
                                          char *prompt,char *shortcut);
+extern void subpanel_show_all_but_toplevel(subpanel_generic *s);

<p><p>1.40      +2 -2      postfish/version.h

Index: version.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/version.h,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- version.h	29 Feb 2004 03:16:17 -0000	1.39
+++ version.h	8 Mar 2004 02:08:23 -0000	1.40
@@ -1,2 +1,2 @@
-#define VERSION "$Id: version.h,v 1.39 2004/02/29 03:16:17 xiphmont Exp $ "
-/* DO NOT EDIT: Automated versioning hack [Sat Feb 28 22:13:31 EST 2004] */
+#define VERSION "$Id: version.h,v 1.40 2004/03/08 02:08:23 xiphmont Exp $ "
+/* DO NOT EDIT: Automated versioning hack [Sun Mar  7 20:57:40 EST 2004] */

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list