[xiph-cvs] cvs commit: postfish bessel.c bessel.h Makefile compandpanel.c multibar.c multicompand.c multicompand.h postfish-gtkrc version.h
Monty
xiphmont at xiph.org
Wed Mar 17 02:32:05 PST 2004
xiphmont 04/03/17 05:32:05
Modified: . Makefile compandpanel.c multibar.c multicompand.c
multicompand.h postfish-gtkrc version.h
Added: . bessel.c bessel.h
Log:
Tweak overall usability of mutiband compander
Changes not yet tested; debug begins now.
Revision Changes Path
1.16 +4 -2 postfish/Makefile
Index: Makefile
===================================================================
RCS file: /usr/local/cvsroot/postfish/Makefile,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- a/Makefile 8 Mar 2004 02:08:23 -0000 1.15
+++ b/Makefile 17 Mar 2004 10:32:04 -0000 1.16
@@ -22,10 +22,12 @@
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
+ feedback.c freq.c eq.c eqpanel.c compandpanel.c subband.c lpc.c \
+ bessel.c
OBJ = main.o mainpanel.o multibar.o readout.o input.o output.o clippanel.o \
declip.o reconstruct.o multicompand.o windowbutton.o subpanel.o \
- feedback.o freq.o eq.o eqpanel.o compandpanel.o subband.o lpc.o
+ feedback.o freq.o eq.o eqpanel.o compandpanel.o subband.o lpc.o \
+ bessel.o
GCF = `pkg-config --cflags gtk+-2.0` -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED
all:
<p><p>1.7 +730 -556 postfish/compandpanel.c
Index: compandpanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/compandpanel.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- a/compandpanel.c 8 Mar 2004 07:20:15 -0000 1.6
+++ b/compandpanel.c 17 Mar 2004 10:32:04 -0000 1.7
@@ -44,111 +44,401 @@
typedef struct {
GtkWidget *label;
GtkWidget *slider;
- GtkWidget *readoutg;
- GtkWidget *readoute;
- GtkWidget *readoutc;
+ GtkWidget *readouto;
+ GtkWidget *readoutu;
int number;
} cbar;
+typedef struct {
+ Readout *r0;
+ Readout *r1;
+ Readout *r2;
+} multireadout;
+
static int bank_active=2;
-static cbar bars[multicomp_freqs_max];
+static cbar bars[multicomp_freqs_max+1];
static int inactive_updatep=1;
+static void under_compand_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ Readout *r=(Readout *)in;
+ float val=1./multibar_get_value(MULTIBAR(w),0);
+
+ if(val>=10){
+ sprintf(buffer,"%4.1f:1",val);
+ }else if(val>=1){
+ sprintf(buffer,"%4.2f:1",val);
+ }else if(val>.10001){
+ sprintf(buffer,"1:%4.2f",1./val);
+ }else{
+ sprintf(buffer,"1:%4.1f",1./val);
+ }
+
+ readout_set(r,buffer);
+
+ c.under_ratio=rint(val*1000.);
+}
+
+static void over_compand_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ Readout *r=(Readout *)in;
+ float val=1./multibar_get_value(MULTIBAR(w),0);
+
+ if(val>=10){
+ sprintf(buffer,"%4.1f:1",val);
+ }else if(val>=1){
+ sprintf(buffer,"%4.2f:1",val);
+ }else if(val>.10001){
+ sprintf(buffer,"1:%4.2f",1./val);
+ }else{
+ sprintf(buffer,"1:%4.1f",1./val);
+ }
+
+ readout_set(r,buffer);
+
+ c.over_ratio=rint(val*1000.);
+}
+
+static void suppress_compand_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ Readout *r=(Readout *)in;
+ float val=1./multibar_get_value(MULTIBAR(w),0);
+
+ if(val>.10001){
+ sprintf(buffer,"1:%4.2f",1./val);
+ }else{
+ sprintf(buffer,"1:%4.1f",1./val);
+ }
+
+ readout_set(r,buffer);
+
+ c.suppress_ratio=rint(val*1000.);
+}
+
+static void under_limit_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ Readout *r=(Readout *)in;
+ float val=140.-multibar_get_value(MULTIBAR(w),0);
+
+ sprintf(buffer,"%3ddB",(int)rint(val));
+ readout_set(r,buffer);
+
+ c.under_limit=rint(val*10.);
+}
+
+static void over_limit_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ Readout *r=(Readout *)in;
+ float val=140.-multibar_get_value(MULTIBAR(w),0);
+
+ sprintf(buffer,"%3ddB",(int)rint(val));
+ readout_set(r,buffer);
+
+ c.over_limit=rint(val*10.);
+}
+
+static void under_timing_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ multireadout *r=(multireadout *)in;
+ float attack=multibar_get_value(MULTIBAR(w),0);
+ float decay=multibar_get_value(MULTIBAR(w),1);
+
+ if(attack<10){
+ sprintf(buffer,"%4.2fms",attack);
+ }else if(attack<100){
+ sprintf(buffer,"%4.1fms",attack);
+ }else if (attack<1000){
+ sprintf(buffer,"%4.0fms",attack);
+ }else if (attack<10000){
+ sprintf(buffer,"%4.2fs",attack/1000.);
+ }else{
+ sprintf(buffer,"%4.1fs",attack/1000.);
+ }
+
+ readout_set(r->r0,buffer);
+
+ if(decay<10){
+ sprintf(buffer,"%4.2fms",decay);
+ }else if (decay<100){
+ sprintf(buffer,"%4.1fms",decay);
+ }else if (decay<1000){
+ sprintf(buffer,"%4.0fms",decay);
+ }else if (decay<10000){
+ sprintf(buffer,"%4.2fs",decay/1000.);
+ }else{
+ sprintf(buffer,"%4.1fs",decay/1000.);
+ }
+
+ readout_set(r->r1,buffer);
+
+ multicompand_under_attack_set(attack);
+ multicompand_under_decay_set(decay);
+
+}
+
+static void over_timing_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ multireadout *r=(multireadout *)in;
+ float attack=multibar_get_value(MULTIBAR(w),0);
+ float decay=multibar_get_value(MULTIBAR(w),1);
+
+ if(attack<10){
+ sprintf(buffer,"%4.2fms",attack);
+ }else if(attack<100){
+ sprintf(buffer,"%4.1fms",attack);
+ }else if (attack<1000){
+ sprintf(buffer,"%4.0fms",attack);
+ }else if (attack<10000){
+ sprintf(buffer,"%4.2fs",attack/1000.);
+ }else{
+ sprintf(buffer,"%4.1fs",attack/1000.);
+ }
+
+ readout_set(r->r0,buffer);
+
+ if(decay<10){
+ sprintf(buffer,"%4.2fms",decay);
+ }else if (decay<100){
+ sprintf(buffer,"%4.1fms",decay);
+ }else if (decay<1000){
+ sprintf(buffer,"%4.0fms",decay);
+ }else if (decay<10000){
+ sprintf(buffer,"%4.2fs",decay/1000.);
+ }else{
+ sprintf(buffer,"%4.1fs",decay/1000.);
+ }
+
+ readout_set(r->r1,buffer);
+
+ multicompand_over_attack_set(attack);
+ multicompand_over_decay_set(decay);
+
+}
+
+static void suppress_timing_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ multireadout *r=(multireadout *)in;
+ float attack=multibar_get_value(MULTIBAR(w),0);
+ float decay=multibar_get_value(MULTIBAR(w),1);
+ float release=multibar_get_value(MULTIBAR(w),2);
+
+ if(attack<10){
+ sprintf(buffer,"%4.2fms",attack);
+ }else if(attack<100){
+ sprintf(buffer,"%4.1fms",attack);
+ }else if (attack<1000){
+ sprintf(buffer,"%4.0fms",attack);
+ }else if (attack<10000){
+ sprintf(buffer,"%4.2fs",attack/1000.);
+ }else{
+ sprintf(buffer,"%4.1fs",attack/1000.);
+ }
+
+ readout_set(r->r0,buffer);
+
+ if(decay<10){
+ sprintf(buffer,"%4.2fms",decay);
+ }else if (decay<100){
+ sprintf(buffer,"%4.1fms",decay);
+ }else if (decay<1000){
+ sprintf(buffer,"%4.0fms",decay);
+ }else if (decay<10000){
+ sprintf(buffer,"%4.2fs",decay/1000.);
+ }else{
+ sprintf(buffer,"%4.1fs",decay/1000.);
+ }
+
+ readout_set(r->r1,buffer);
+
+ if(release<10){
+ sprintf(buffer,"%4.2fms",release);
+ }else if (release<100){
+ sprintf(buffer,"%4.1fms",release);
+ }else if (release<1000){
+ sprintf(buffer,"%4.0fms",release);
+ }else if (release<10000){
+ sprintf(buffer,"%4.2fs",release/1000.);
+ }else{
+ sprintf(buffer,"%4.1fs",release/1000.);
+ }
+
+ readout_set(r->r2,buffer);
+
+ multicompand_suppress_attack_set(attack);
+ multicompand_suppress_decay_set(decay);
+ multicompand_suppress_release_set(release);
+
+}
+
+static void under_lookahead_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ Readout *r=(Readout *)in;
+ float val=multibar_get_value(MULTIBAR(w),0);
+
+ sprintf(buffer,"%5.1f%%",val);
+ readout_set(r,buffer);
+
+ c.under_lookahead=rint(val*10.);
+}
+
+static void over_lookahead_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ Readout *r=(Readout *)in;
+ float val=multibar_get_value(MULTIBAR(w),0);
+
+ sprintf(buffer,"%5.1f%%",val);
+ readout_set(r,buffer);
+
+ c.over_lookahead=rint(val*10.);
+}
+
+
+static int updating_av_slider=0;
+static void average_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ cbar *b=bars+multicomp_freqs_max;
+ float o,u;
+ float oav=0,uav=0;
+ int i;
+
+ u=rint(multibar_get_value(MULTIBAR(b->slider),0));
+ o=rint(multibar_get_value(MULTIBAR(b->slider),1));
+
+ /* compute the current average */
+ for(i=0;i<multicomp_freqs[bank_active];i++){
+ oav+=rint(bc[bank_active].static_o[i]/10.);
+ uav+=rint(bc[bank_active].static_u[i]/10.);
+ }
+ oav=rint(oav/multicomp_freqs[bank_active]);
+ uav=rint(uav/multicomp_freqs[bank_active]);
+
+ u-=uav;
+ o-=oav;
+
+ if(!updating_av_slider){
+ updating_av_slider=1;
+ if(o!=0.){
+ /* update o sliders */
+ for(i=0;i<multicomp_freqs[bank_active];i++){
+ float val=multibar_get_value(MULTIBAR(bars[i].slider),1);
+ multibar_thumb_set(MULTIBAR(bars[i].slider),val+o,1);
+ }
+ /* update u average (might have pushed it) */
+ uav=0;
+ for(i=0;i<multicomp_freqs[bank_active];i++)
+ uav+=rint(bc[bank_active].static_u[i]/10.);
+ uav=rint(uav/multicomp_freqs[bank_active]);
+ multibar_thumb_set(MULTIBAR(bars[multicomp_freqs_max].slider),uav,0);
+ }else{
+ /* update u sliders */
+ for(i=0;i<multicomp_freqs[bank_active];i++){
+ float val=multibar_get_value(MULTIBAR(bars[i].slider),0);
+ multibar_thumb_set(MULTIBAR(bars[i].slider),val+u,0);
+ }
+ /* update o average (might have pushed it) */
+ oav=0;
+ for(i=0;i<multicomp_freqs[bank_active];i++)
+ oav+=rint(bc[bank_active].static_o[i]/10.);
+ oav=rint(oav/multicomp_freqs[bank_active]);
+ multibar_thumb_set(MULTIBAR(bars[multicomp_freqs_max].slider),oav,1);
+ }
+ updating_av_slider=0;
+ }
+}
+
static void slider_change(GtkWidget *w,gpointer in){
char buffer[80];
cbar *b=(cbar *)in;
- float g,e,c;
+ float o,u;
+ int i;
- 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;
+ u=multibar_get_value(MULTIBAR(b->slider),0);
+ sprintf(buffer,"%+4.0fdB",u);
+ readout_set(READOUT(b->readoutu),buffer);
+ u=rint(u*10.);
+ bc[bank_active].static_u[b->number]=u;
+ o=multibar_get_value(MULTIBAR(b->slider),1);
+ sprintf(buffer,"%+4.0fdB",o);
+ readout_set(READOUT(b->readouto),buffer);
+ o=rint(o*10.);
+ bc[bank_active].static_o[b->number]=o;
+
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;
+ bc[1].static_o[b->number*2]=o;
+ bc[1].static_u[b->number*2]=u;
+ bc[2].static_o[b->number*3+1]=o;
+ bc[2].static_u[b->number*3+1]=u;
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;
+ bc[0].static_o[b->number>>1]=o;
+ bc[0].static_u[b->number>>1]=u;
+ bc[2].static_o[b->number/2*3+1]=o;
+ bc[2].static_u[b->number/2*3+1]=u;
}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);
+ float val=(bc[2].static_o[b->number/2*3+2]+
+ bc[2].static_o[b->number/2*3+3])*.5;
+ bc[2].static_o[b->number/2*3+2]+=(o-val);
+ bc[2].static_o[b->number/2*3+3]+=(o-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_u[b->number/2*3+2]+
+ bc[2].static_u[b->number/2*3+3])*.5;
+ bc[2].static_u[b->number/2*3+2]+=(u-val);
+ bc[2].static_u[b->number/2*3+3]+=(u-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;
+ bc[2].static_o[b->number/2*3+2]=o;
+ bc[2].static_u[b->number/2*3+2]=u;
}
}
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;
+ bc[0].static_o[b->number/3]=o;
+ bc[0].static_u[b->number/3]=u;
+ bc[1].static_o[b->number/3*2]=o;
+ bc[1].static_u[b->number/3*2]=u;
}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;
+ bc[1].static_o[(b->number-1)/3*2+1]=
+ (bc[2].static_o[(b->number-1)/3*3+2]+
+ bc[2].static_o[(b->number-1)/3*3+3])*.5;
+ bc[1].static_u[(b->number-1)/3*2+1]=
+ (bc[2].static_u[(b->number-1)/3*3+2]+
+ bc[2].static_u[(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;
+ bc[1].static_o[(b->number-1)/3*2+1]=o;
+ bc[1].static_u[(b->number-1)/3*2+1]=u;
}
}
break;
}
}
+
+ /* update average slider */
+ if(!updating_av_slider && bars[multicomp_freqs_max].slider){
+ float oav=0,uav=0;
+ updating_av_slider=1;
+
+ /* compute the current average */
+ for(i=0;i<multicomp_freqs[bank_active];i++){
+ oav+=rint(bc[bank_active].static_o[i]/10.);
+ uav+=rint(bc[bank_active].static_u[i]/10.);
+ }
+ oav=rint(oav/multicomp_freqs[bank_active]);
+ uav=rint(uav/multicomp_freqs[bank_active]);
+
+ multibar_thumb_set(MULTIBAR(bars[multicomp_freqs_max].slider),uav,0);
+ multibar_thumb_set(MULTIBAR(bars[multicomp_freqs_max].slider),oav,1);
+ updating_av_slider=0;
+ }
}
static void static_octave(GtkWidget *w,gpointer in){
@@ -165,20 +455,17 @@
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);
+ gtk_widget_show(bars[i].readouto);
+ gtk_widget_show(bars[i].readoutu);
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);
+ float o=bc[bank_active].static_o[i]/10.;
+ float u=bc[bank_active].static_u[i]/10.;
+
+ multibar_thumb_set(MULTIBAR(bars[i].slider),u,0);
+ multibar_thumb_set(MULTIBAR(bars[i].slider),o,1);
}
inactive_updatep=1;
@@ -186,9 +473,8 @@
}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);
+ gtk_widget_hide(bars[i].readouto);
+ gtk_widget_hide(bars[i].readoutu);
}
}
multicompand_set_bank(bank_active);
@@ -197,211 +483,34 @@
}
}
-static void static_compressor_change(GtkWidget *w,gpointer in){
- char buffer[80];
- Readout *r=READOUT(in);
- float val=-multibar_get_value(MULTIBAR(w),0);
-
- if(rint(1./val)>=10.)
- sprintf(buffer,"%3.1f:1",1./val);
- else
- sprintf(buffer,"%3.2f:1",1./val);
-
- if(val==1.)
- sprintf(buffer," off");
-
- readout_set(r,buffer);
- c.static_c_ratio=rint(100./val);
-}
-
-static void static_expander_change(GtkWidget *w,gpointer in){
- char buffer[80];
- Readout *r=READOUT(in);
- float val=-multibar_get_value(MULTIBAR(w),0);
-
- if(rint(1./val)>=10.)
- sprintf(buffer,"%3.1f:1",1./val);
- else
- sprintf(buffer,"%3.2f:1",1./val);
-
- if(val==1.)
- sprintf(buffer," off");
-
- readout_set(r,buffer);
- c.static_e_ratio=rint(100./val);
-}
-
-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 set=val/input_rate*(1024*1024);
- float ms =-100000./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(ms<=10)
- sprintf(buffer," fast");
-
- if(ms>99999.)
- sprintf(buffer," slow");
-
- readout_set(r,buffer);
- *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,sig_atomic_t *v){
- char buffer[80];
- Readout *r=READOUT(in);
- float val=multibar_get_value(MULTIBAR(w),0);
-
- sprintf(buffer,"%+3.0fdB",val);
-
- readout_set(r,buffer);
- *v=rint(val*10.);
-}
-
-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 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);
- }
-
- 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){
int active=gtk_toggle_button_get_active(b);
c.link_mode=active;
}
-static void static_mode(GtkButton *b,gpointer in){
+static void over_mode(GtkButton *b,gpointer in){
int mode=(int)in;
- c.static_mode=mode;
+ c.over_mode=mode;
}
-static void suppressor_mode(GtkButton *b,gpointer in){
+static void under_mode(GtkButton *b,gpointer in){
int mode=(int)in;
- c.suppress_mode=mode;
+ c.under_mode=mode;
}
-static void envelope_mode(GtkButton *b,gpointer in){
+static void under_knee(GtkButton *b,gpointer in){
int mode=(int)in;
- c.envelope_mode=mode;
-}
-
-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 set=val/input_rate*(1024*1024);
- float ms =-100000./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(ms<=10)
- sprintf(buffer," fast");
-
- if(ms>99999.)
- sprintf(buffer," slow");
-
- readout_set(r,buffer);
- c.suppress_decay=rint(set);
-}
-
-static void suppress_ratio_change(GtkWidget *w,gpointer in){
- char buffer[80];
- Readout *r=READOUT(in);
- float val=-multibar_get_value(MULTIBAR(w),0);
-
- if(rint(1./val)>=10.)
- sprintf(buffer,"%3.1f:1",1./val);
- else
- sprintf(buffer,"%3.2f:1",1./val);
-
- if(val==1.)
- sprintf(buffer," off");
-
- readout_set(r,buffer);
- c.suppress_ratio=rint(100./val);
+ c.under_softknee=mode;
}
-static void suppress_depth_change(GtkWidget *w,gpointer in){
- char buffer[80];
- Readout *r=READOUT(in);
- float val=-140.-multibar_get_value(MULTIBAR(w),0);
-
- sprintf(buffer,"%3.0fdB",-val);
-
- if(val==0.)
- sprintf(buffer," off");
-
- if(val==-140)
- sprintf(buffer," deep");
-
- readout_set(r,buffer);
- c.suppress_depth=rint(val*10.);
+static void over_knee(GtkButton *b,gpointer in){
+ int mode=(int)in;
+ c.over_softknee=mode;
}
-static void envelope_compander_change(GtkWidget *w,gpointer in){
- char buffer[80];
- Readout *r=READOUT(in);
- float val=multibar_get_value(MULTIBAR(w),0);
-
- sprintf(buffer,"%+5.1f%%",val);
- readout_set(r,buffer);
- c.envelope_c=rint(val*10.);
+static void suppress_mode(GtkButton *b,gpointer in){
+ int mode=(int)in;
+ c.suppress_mode=mode;
}
void compandpanel_create(postfish_mainpanel *mp,
@@ -413,41 +522,51 @@
float levels[15]={-140,-130,-120,-110,-100,-90,-80,-70,-60,-50,-40,
-30,-20,-10,0};
- float ratio_levels[7]={-1.,-.833,-.667,-.5,-.33,-.2,-.1};
- char *ratio_labels[6]={"1.2:1","1.5:1","2:1","3:1","5:1","10:1"};
+ float compand_levels[9]={.1,.25,.5,.667,1,1.5,2,4,10};
+ char *compand_labels[8]={"4:1","2:1","1:1.5","1:1","1:1.5","1:2","1:4","1:10"};
- float decay_levels[7]={-10000,-1000,-100,-30,-10,-3,-1};
- char *decay_labels[6]={".1","1","3","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 compand_levels_low[5]={1,1.2,1.5,2,3};
+ char *compand_labels_low[4]={"1:1.2","1:1.5","1:2","1:3"};
+
+ float timing_levels[6]={.5,1,10,100,1000,10000};
+ char *timing_labels[5]={"1ms","10ms","100ms","1s","10s"};
- float depth_levels[7]={-140,-130,-120,-110,-100,-80,-0};
- char *depth_labels[6]={"10","20","30","40","60","deep"};
+ float limit_levels[9]={0,40,60,80,100,110,120,130,135};
+ char *limit_labels[8]={"100dB","80dB","60dB","40dB","30dB","20dB","10dB","5dB"};
+
+ float per_levels[9]={0,12.5,25,37.5,50,62.5,75,87.5,100};
+ char *per_labels[8]={"","25%","","50%","","75%","","100%"};
subpanel_generic *panel=subpanel_create(mp,windowbutton,activebutton,
&compand_active,
&compand_visible,
- "_Multiband Compand and Noise Gate"," [m] ");
+ "_Multiband Compand"," [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 *slidertable=gtk_table_new(multicomp_freqs_max+2,4,0);
+
+ GtkWidget *overlabel=gtk_label_new("Over threshold compand");
+ GtkWidget *overtable=gtk_table_new(6,4,0);
- GtkWidget *envelopeframe=gtk_frame_new(" Dynamic Range ");
- GtkWidget *suppressframe=gtk_frame_new(" Reverberation Suppressor ");
+ GtkWidget *underlabel=gtk_label_new("Under threshold compand");
+ GtkWidget *undertable=gtk_table_new(5,4,0);
- GtkWidget *envelopetable=gtk_table_new(3,3,0);
- GtkWidget *suppresstable=gtk_table_new(4,3,0);
- GtkWidget *statictable=gtk_table_new(10,4,0);
+ GtkWidget *suppressframe=gtk_frame_new(" Reverb suppression ");
+ GtkWidget *suppresstable=gtk_table_new(4,5,0);
GtkWidget *link_box=gtk_hbox_new(0,0);
GtkWidget *link_check=gtk_check_button_new_with_mnemonic("_link channel envelopes");
+ gtk_widget_set_name(overlabel,"framelabel");
+ gtk_widget_set_name(underlabel,"framelabel");
+ gtk_container_set_border_width(GTK_CONTAINER(suppresstable),4);
+
+
+
{
GtkWidget *octave_box=gtk_hbox_new(0,0);
@@ -458,9 +577,14 @@
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");
+ GtkWidget *label2=gtk_label_new("under");
+ GtkWidget *label3=gtk_label_new("over");
+
+ gtk_misc_set_alignment(GTK_MISC(label2),.5,1.);
+ gtk_misc_set_alignment(GTK_MISC(label3),.5,1.);
+ gtk_widget_set_name(label2,"scalemarker");
+ gtk_widget_set_name(label3,"scalemarker");
+
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(octave_c),1);
@@ -471,14 +595,13 @@
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_table_attach(GTK_TABLE(slidertable),label2,1,2,0,1,GTK_FILL,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(slidertable),label3,3,4,0,1,GTK_FILL,GTK_FILL|GTK_EXPAND,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_table_attach(GTK_TABLE(slidertable),octave_box,2,3,0,1,
GTK_EXPAND,0,0,0);
gtk_box_pack_start(GTK_BOX(sliderbox),sliderframe,0,0,0);
@@ -503,314 +626,347 @@
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);
+ gtk_box_pack_start(GTK_BOX(staticbox),overtable,0,0,0);
+ gtk_box_pack_start(GTK_BOX(staticbox),undertable,0,0,10);
+
+
gtk_box_pack_end(GTK_BOX(staticbox),suppressframe,0,0,0);
- gtk_box_pack_end(GTK_BOX(staticbox),envelopeframe,0,0,0);
- gtk_container_add(GTK_CONTAINER(staticframe),statictable);
- gtk_container_add(GTK_CONTAINER(envelopeframe),envelopetable);
gtk_container_add(GTK_CONTAINER(suppressframe),suppresstable);
gtk_container_set_border_width(GTK_CONTAINER(suppressframe),5);
- gtk_container_set_border_width(GTK_CONTAINER(envelopeframe),5);
- gtk_container_set_border_width(GTK_CONTAINER(envelopeframe),5);
- gtk_frame_set_shadow_type(GTK_FRAME(staticframe),GTK_SHADOW_NONE);
+ gtk_container_set_border_width(GTK_CONTAINER(overtable),5);
+ gtk_container_set_border_width(GTK_CONTAINER(undertable),5);
- /* static compand */
+ /* under compand: mode and knee */
{
-
- //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");
+ GtkWidget *knee_button=gtk_check_button_new_with_label("soft knee");
- GtkWidget *labelR=gtk_label_new("Ratio");
- GtkWidget *labelR1=gtk_label_new("cmpr:");
- GtkWidget *labelR2=gtk_label_new("expd:");
- GtkWidget *readoutR1=readout_new("1.50:1");
- GtkWidget *readoutR2=readout_new("1.50: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_start(GTK_BOX(envelopebox),underlabel,0,0,5);
gtk_box_pack_end(GTK_BOX(envelopebox),peak_button,0,0,5);
gtk_box_pack_end(GTK_BOX(envelopebox),rms_button,0,0,5);
+ gtk_box_pack_end(GTK_BOX(envelopebox),knee_button,0,0,5);
+
+ g_signal_connect (G_OBJECT (knee_button), "clicked",
+ G_CALLBACK (under_knee), (gpointer)0);
g_signal_connect (G_OBJECT (rms_button), "clicked",
- G_CALLBACK (static_mode), (gpointer)0); //To Hell I Go
+ G_CALLBACK (under_mode), (gpointer)0);
g_signal_connect (G_OBJECT (peak_button), "clicked",
- G_CALLBACK (static_mode), (gpointer)1);
+ G_CALLBACK (under_mode), (gpointer)1); //To Hell I Go
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rms_button),1);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(knee_button),1);
+ gtk_table_attach(GTK_TABLE(undertable),envelopebox,0,4,0,1,GTK_FILL,0,0,0);
+ }
- 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);
-
- 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_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),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),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),sliderD2,1,3,5,6,
- GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
- 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),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_container_set_border_width(GTK_CONTAINER(statictable),4);
- }
-
- /* envelope compand */
- {
- float levels[11]={-50,-40,-30,-20,-10,0,10,20,30,40,50};
- char *labels[10]={"40%","30%","20%","10%","0%","10%","20%",
- "30%","40%","50%"};
-
- //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%");
- GtkWidget *envelope_compress_slider=multibar_slider_new(10,labels,levels,1);
+ /* under compand: ratio */
+ {
+ GtkWidget *label=gtk_label_new("compand ratio:");
+ GtkWidget *readout=readout_new("1.55:1");
+ GtkWidget *slider=multibar_slider_new(8,compand_labels,compand_levels,1);
+
+ multibar_callback(MULTIBAR(slider),under_compand_change,readout);
+ multibar_thumb_set(MULTIBAR(slider),1.,0);
+ multibar_thumb_increment(MULTIBAR(slider),.01,.1);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1.,.5);
+
+ gtk_table_set_row_spacing(GTK_TABLE(undertable),0,4);
+ gtk_table_attach(GTK_TABLE(undertable),label,0,1,1,2,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(undertable),slider,1,3,1,2,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(undertable),readout,3,4,1,2,GTK_FILL,0,0,0);
+
+ }
+
+ /* under compand: limit */
+ {
+
+ GtkWidget *label=gtk_label_new("compand limit:");
+ GtkWidget *readout=readout_new("140dB");
+ GtkWidget *slider=multibar_slider_new(8,limit_labels,limit_levels,1);
+
+ multibar_callback(MULTIBAR(slider),under_limit_change,readout);
+ multibar_thumb_set(MULTIBAR(slider),0.,0);
+ multibar_thumb_increment(MULTIBAR(slider),1.,10.);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1,.5);
+
+ gtk_table_set_row_spacing(GTK_TABLE(undertable),1,4);
+ gtk_table_attach(GTK_TABLE(undertable),label,0,1,2,3,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(undertable),slider,1,3,2,3,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(undertable),readout,3,4,2,3,GTK_FILL,0,0,0);
+ }
+
+ /* under compand: timing */
+ {
+
+ GtkWidget *label=gtk_label_new("attack/decay:");
+ GtkWidget *readout1=readout_new(" 100ms");
+ GtkWidget *readout2=readout_new(" 100ms");
+ GtkWidget *slider=multibar_slider_new(5,timing_labels,timing_levels,2);
+ multireadout *r=calloc(1,sizeof(*r));
+
+ r->r0=(Readout *)readout1;
+ r->r1=(Readout *)readout2;
+
+ multibar_callback(MULTIBAR(slider),under_timing_change,r);
+ multibar_thumb_set(MULTIBAR(slider),1,0);
+ multibar_thumb_set(MULTIBAR(slider),100,1);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1,.5);
+
+ gtk_table_set_row_spacing(GTK_TABLE(undertable),2,4);
+ gtk_table_attach(GTK_TABLE(undertable),label,0,1,4,5,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(undertable),slider,1,2,4,5,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(undertable),readout1,2,3,4,5,GTK_FILL,0,0,0);
+ gtk_table_attach(GTK_TABLE(undertable),readout2,3,4,4,5,GTK_FILL,0,0,0);
+
+ }
+
+ /* under compand: lookahead */
+ {
+
+ GtkWidget *label=gtk_label_new("lookahead:");
+ GtkWidget *readout=readout_new("100%");
+ GtkWidget *slider=multibar_slider_new(8,per_labels,per_levels,1);
+ GtkWidget *labelbox=gtk_hbox_new(0,0);
+
+ multibar_callback(MULTIBAR(slider),under_lookahead_change,readout);
+ multibar_thumb_set(MULTIBAR(slider),100.,0);
+ multibar_thumb_increment(MULTIBAR(slider),1.,10.);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1,.5);
+
+ gtk_table_set_row_spacing(GTK_TABLE(undertable),3,4);
+ gtk_table_attach(GTK_TABLE(undertable),label,0,1,3,4,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(undertable),slider,1,3,3,4,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(undertable),readout,3,4,3,4,GTK_FILL,0,0,0);
+ }
+
+ /* over compand: mode and knee */
+ {
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");
+ GtkWidget *knee_button=gtk_check_button_new_with_label("soft knee");
- //gtk_box_pack_start(GTK_BOX(envelopebox),label0,0,0,1);
+ gtk_box_pack_start(GTK_BOX(envelopebox),overlabel,0,0,5);
gtk_box_pack_end(GTK_BOX(envelopebox),peak_button,0,0,5);
gtk_box_pack_end(GTK_BOX(envelopebox),rms_button,0,0,5);
+ gtk_box_pack_end(GTK_BOX(envelopebox),knee_button,0,0,5);
+ g_signal_connect (G_OBJECT (knee_button), "clicked",
+ G_CALLBACK (over_knee), (gpointer)0);
g_signal_connect (G_OBJECT (rms_button), "clicked",
- G_CALLBACK (envelope_mode), (gpointer)0); //To Hell I Go
+ G_CALLBACK (over_mode), (gpointer)0);
g_signal_connect (G_OBJECT (peak_button), "clicked",
- G_CALLBACK (envelope_mode), (gpointer)1);
+ G_CALLBACK (over_mode), (gpointer)1); //To Hell I Go
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rms_button),1);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(knee_button),1);
+ gtk_table_attach(GTK_TABLE(overtable),envelopebox,0,4,0,1,GTK_FILL,0,0,0);
+ }
+ /* over compand: ratio */
+ {
+
+ GtkWidget *label=gtk_label_new("compand ratio:");
+ GtkWidget *readout=readout_new("1.55:1");
+ GtkWidget *slider=multibar_slider_new(8,compand_labels,compand_levels,1);
- gtk_container_set_border_width(GTK_CONTAINER(envelopetable),4);
- multibar_callback(MULTIBAR(envelope_compress_slider),
- envelope_compander_change,
- envelope_compress_readout);
- multibar_thumb_increment(MULTIBAR(envelope_compress_slider),.1,1.);
-
- gtk_widget_set_name(label1,"smallmarker");
- gtk_widget_set_name(label2,"smallmarker");
- gtk_misc_set_alignment(GTK_MISC(label1),0,.5);
- gtk_misc_set_alignment(GTK_MISC(label2),1,.5);
-
- 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,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);
- gtk_table_attach(GTK_TABLE(envelopetable),envelope_compress_readout,
- 2,3,1,2,GTK_FILL,0,0,0);
+ multibar_callback(MULTIBAR(slider),over_compand_change,readout);
+ multibar_thumb_set(MULTIBAR(slider),1.,0);
+ multibar_thumb_increment(MULTIBAR(slider),.01,.1);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1.,.5);
+
+ gtk_table_set_row_spacing(GTK_TABLE(overtable),0,4);
+ gtk_table_attach(GTK_TABLE(overtable),label,0,1,1,2,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(overtable),slider,1,3,1,2,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(overtable),readout,3,4,1,2,GTK_FILL,0,0,0);
}
- /* suppressor */
- {
-
- 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_decay_readout=readout_new("fast");
- GtkWidget *suppress_ratio_readout=readout_new("1.50:1");
- GtkWidget *suppress_depth_readout=readout_new("gate");
-
- //GtkWidget *label1=gtk_label_new("mode:");
- GtkWidget *label3=gtk_label_new("decay:");
- GtkWidget *label4=gtk_label_new("ratio:");
- GtkWidget *label5=gtk_label_new("depth:");
+ /* over compand: limit */
+ {
+
+ GtkWidget *label=gtk_label_new("compand limit:");
+ GtkWidget *readout=readout_new("140dB");
+ GtkWidget *slider=multibar_slider_new(8,limit_labels,limit_levels,1);
+
+ multibar_callback(MULTIBAR(slider),over_limit_change,readout);
+ multibar_thumb_set(MULTIBAR(slider),0.,0);
+ multibar_thumb_increment(MULTIBAR(slider),1.,10.);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1,.5);
+ gtk_table_set_row_spacing(GTK_TABLE(overtable),1,4);
+ gtk_table_attach(GTK_TABLE(overtable),label,0,1,2,3,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(overtable),slider,1,3,2,3,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(overtable),readout,3,4,2,3,GTK_FILL,0,0,0);
+ }
+
+ /* over compand: timing */
+ {
+
+ GtkWidget *label=gtk_label_new("attack/decay:");
+ GtkWidget *readout1=readout_new(" 100ms");
+ GtkWidget *readout2=readout_new(" 100ms");
+ GtkWidget *slider=multibar_slider_new(5,timing_labels,timing_levels,2);
+
+ multireadout *r=calloc(1,sizeof(*r));
+ r->r0=(Readout *)readout1;
+ r->r1=(Readout *)readout2;
+
+ multibar_callback(MULTIBAR(slider),over_timing_change,r);
+ multibar_thumb_set(MULTIBAR(slider),1,0);
+ multibar_thumb_set(MULTIBAR(slider),100,1);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1,.5);
+
+ gtk_table_set_row_spacing(GTK_TABLE(overtable),2,4);
+ gtk_table_attach(GTK_TABLE(overtable),label,0,1,5,6,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(overtable),slider,1,2,5,6,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(overtable),readout1,2,3,5,6,GTK_FILL,0,0,0);
+ gtk_table_attach(GTK_TABLE(overtable),readout2,3,4,5,6,GTK_FILL,0,0,0);
+
+ }
+
+ /* over compand: lookahead */
+ {
+
+ GtkWidget *label=gtk_label_new("lookahead:");
+ GtkWidget *readout=readout_new("100%");
+ GtkWidget *slider=multibar_slider_new(8,per_labels,per_levels,1);
+ GtkWidget *labelbox=gtk_hbox_new(0,0);
+
+ multibar_callback(MULTIBAR(slider),over_lookahead_change,readout);
+ multibar_thumb_set(MULTIBAR(slider),100.,0);
+ multibar_thumb_increment(MULTIBAR(slider),1.,10.);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1,.5);
+
+ gtk_table_set_row_spacing(GTK_TABLE(overtable),3,4);
+ gtk_table_attach(GTK_TABLE(overtable),label,0,1,3,4,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(overtable),slider,1,3,3,4,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(overtable),readout,3,4,3,4,GTK_FILL,0,0,0);
+ }
+
+ /* base compand: ratio */
+ {
+
+ GtkWidget *label=gtk_label_new("global ratio:");
+ GtkWidget *readout=readout_new("1.55:1");
+ GtkWidget *slider=multibar_slider_new(8,compand_labels,compand_levels,1);
+
+ //multibar_callback(MULTIBAR(slider),over_compand_change,readout);
+ multibar_thumb_set(MULTIBAR(slider),1.,0);
+ multibar_thumb_increment(MULTIBAR(slider),.01,.1);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1.,.5);
+
+ gtk_table_set_row_spacing(GTK_TABLE(overtable),4,4);
+
+ gtk_table_attach(GTK_TABLE(overtable),label,0,1,4,5,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(overtable),slider,1,3,4,5,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(overtable),readout,3,4,4,5,GTK_FILL,0,0,0);
+
+ }
+
+ /* suppress: mode */
+ {
GtkWidget *envelopebox=gtk_hbox_new(0,0);
- GtkWidget *suppress_rms_button=gtk_radio_button_new_with_label(NULL,"RMS");
- GtkWidget *suppress_peak_button=
- gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(suppress_rms_button),
+ 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_end(GTK_BOX(envelopebox),suppress_peak_button,0,0,5);
- gtk_box_pack_end(GTK_BOX(envelopebox),suppress_rms_button,0,0,5);
+ 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 (suppress_rms_button), "clicked",
- G_CALLBACK (suppressor_mode), (gpointer)0); //To Hell I Go
- g_signal_connect (G_OBJECT (suppress_peak_button), "clicked",
- G_CALLBACK (suppressor_mode), (gpointer)1);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(suppress_rms_button),1);
-
-
- gtk_container_set_border_width(GTK_CONTAINER(suppresstable),4);
-
- //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),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_decay_slider),
- suppress_decay_change,
- suppress_decay_readout);
- multibar_thumb_set(MULTIBAR(suppress_decay_slider),-1.,0);
-
- multibar_callback(MULTIBAR(suppress_ratio_slider),
- suppress_ratio_change,
- suppress_ratio_readout);
- multibar_thumb_set(MULTIBAR(suppress_ratio_slider),-1.,0);
-
- multibar_callback(MULTIBAR(suppress_depth_slider),
- suppress_depth_change,
- suppress_depth_readout);
- multibar_thumb_set(MULTIBAR(suppress_depth_slider),0.,0);
-
- gtk_table_attach(GTK_TABLE(suppresstable),
- 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,2,3,GTK_FILL|GTK_EXPAND,
- GTK_FILL|GTK_EXPAND,2,0);
- gtk_table_attach(GTK_TABLE(suppresstable),
- suppress_depth_slider,1,2,3,4,GTK_FILL|GTK_EXPAND,
- GTK_FILL|GTK_EXPAND,2,0);
-
- gtk_table_attach(GTK_TABLE(suppresstable),
- suppress_decay_readout,2,3,1,2,GTK_FILL,0,0,0);
- gtk_table_attach(GTK_TABLE(suppresstable),
- suppress_ratio_readout,2,3,2,3,GTK_FILL,0,0,0);
- gtk_table_attach(GTK_TABLE(suppresstable),
- suppress_depth_readout,2,3,3,4,GTK_FILL,0,0,0);
+ g_signal_connect (G_OBJECT (rms_button), "clicked",
+ G_CALLBACK (suppress_mode), (gpointer)0);
+ g_signal_connect (G_OBJECT (peak_button), "clicked",
+ G_CALLBACK (suppress_mode), (gpointer)1); //To Hell I Go
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rms_button),1);
+ gtk_table_attach(GTK_TABLE(suppresstable),envelopebox,1,5,0,1,GTK_FILL,0,0,0);
+ }
+
+ /* suppress: ratio */
+ {
+
+ GtkWidget *label=gtk_label_new("ratio:");
+ GtkWidget *readout=readout_new("1.55:1");
+ GtkWidget *slider=multibar_slider_new(4,compand_labels_low,compand_levels_low,1);
+
+ multibar_callback(MULTIBAR(slider),suppress_compand_change,readout);
+ multibar_thumb_set(MULTIBAR(slider),1.,0);
+ multibar_thumb_increment(MULTIBAR(slider),.01,.1);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1.,.5);
+
+ gtk_table_set_row_spacing(GTK_TABLE(suppresstable),0,4);
+ gtk_table_attach(GTK_TABLE(suppresstable),label,0,1,1,2,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(suppresstable),slider,1,4,1,2,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(suppresstable),readout,4,5,1,2,GTK_FILL,0,0,0);
}
+ /* suppress: timing */
+ {
+
+ GtkWidget *label=gtk_label_new("timing:");
+ GtkWidget *label2=gtk_label_new("attack / decay / release");
+ GtkWidget *readout1=readout_new(" 100ms");
+ GtkWidget *readout2=readout_new(" 100ms");
+ GtkWidget *readout3=readout_new(" 100ms");
+ GtkWidget *slider=multibar_slider_new(5,timing_labels,timing_levels,3);
+
+ multireadout *r=calloc(1,sizeof(*r));
+ r->r0=(Readout *)readout1;
+ r->r1=(Readout *)readout2;
+ r->r2=(Readout *)readout3;
+
+ gtk_widget_set_name(label2,"scalemarker");
+
+ multibar_callback(MULTIBAR(slider),suppress_timing_change,r);
+ multibar_thumb_set(MULTIBAR(slider),1,0);
+ multibar_thumb_set(MULTIBAR(slider),100,1);
+ multibar_thumb_set(MULTIBAR(slider),1000,2);
+
+ gtk_misc_set_alignment(GTK_MISC(label),1,.5);
+
+ gtk_table_set_row_spacing(GTK_TABLE(suppresstable),1,4);
+ gtk_table_attach(GTK_TABLE(suppresstable),label,0,1,2,3,GTK_FILL,0,2,0);
+ gtk_table_attach(GTK_TABLE(suppresstable),slider,1,2,2,3,GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,2,0);
+ gtk_table_attach(GTK_TABLE(suppresstable),readout1,2,3,2,3,GTK_FILL,0,0,0);
+ gtk_table_attach(GTK_TABLE(suppresstable),readout2,3,4,2,3,GTK_FILL,0,0,0);
+ gtk_table_attach(GTK_TABLE(suppresstable),readout3,4,5,2,3,GTK_FILL,0,0,0);
+ gtk_table_attach(GTK_TABLE(suppresstable),label2,1,2,3,4,GTK_FILL,0,0,0);
+
+ }
+
+ /* threshold controls */
+
for(i=0;i<multicomp_freqs_max;i++){
GtkWidget *label=gtk_label_new(NULL);
- gtk_widget_set_name(label,"smallmarker");
+ gtk_widget_set_name(label,"scalemarker");
- 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,
+ bars[i].readoutu=readout_new(" +0");
+ bars[i].readouto=readout_new(" +0");
+ bars[i].slider=multibar_new(14,labels,levels,2,
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);
- multibar_thumb_set(MULTIBAR(bars[i].slider),-140.,1);
- multibar_thumb_set(MULTIBAR(bars[i].slider),0.,2);
+ multibar_thumb_set(MULTIBAR(bars[i].slider),0.,1);
multibar_thumb_bounds(MULTIBAR(bars[i].slider),-140,0);
multibar_thumb_increment(MULTIBAR(bars[i].slider),1.,10.);
@@ -818,16 +974,34 @@
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_table_attach(GTK_TABLE(slidertable),bars[i].readoutu,1,2,i+1,i+2,
+ 0,0,0,0);
+ gtk_table_attach(GTK_TABLE(slidertable),bars[i].slider,2,3,i+1,i+2,
+ GTK_FILL|GTK_EXPAND,GTK_EXPAND,0,0);
+ gtk_table_attach(GTK_TABLE(slidertable),bars[i].readouto,3,4,i+1,i+2,
0,0,0,0);
- gtk_table_attach(GTK_TABLE(slidertable),bars[i].readoute,3,4,i+1,i+2,
- 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);
}
+ /* "average" slider */
+ {
+ GtkWidget *label=gtk_label_new("average");
+
+ bars[multicomp_freqs_max].slider=multibar_slider_new(14,labels,levels,2);
+
+ multibar_callback(MULTIBAR(bars[multicomp_freqs_max].slider),average_change,bars+multicomp_freqs_max);
+
+ multibar_thumb_set(MULTIBAR(bars[multicomp_freqs_max].slider),-140.,0);
+ multibar_thumb_set(MULTIBAR(bars[multicomp_freqs_max].slider),0.,1);
+ multibar_thumb_bounds(MULTIBAR(bars[multicomp_freqs_max].slider),-140,0);
+
+ gtk_table_attach(GTK_TABLE(slidertable),label,0,2,multicomp_freqs_max+1,multicomp_freqs_max+2,
+ GTK_FILL,0,0,0);
+ gtk_table_attach(GTK_TABLE(slidertable),bars[i].slider,2,3,multicomp_freqs_max+1,multicomp_freqs_max+2,
+ GTK_FILL|GTK_EXPAND,GTK_EXPAND,0,0);
+ gtk_table_set_row_spacing(GTK_TABLE(slidertable),multicomp_freqs_max,10);
+ }
+
+
subpanel_show_all_but_toplevel(panel);
/* Now unmap the sliders we don't want */
<p><p>1.25 +152 -111 postfish/multibar.c
Index: multibar.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/multibar.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- a/multibar.c 8 Mar 2004 02:08:23 -0000 1.24
+++ b/multibar.c 17 Mar 2004 10:32:04 -0000 1.25
@@ -68,10 +68,7 @@
if(m->thumbs<1){
xpad=2;
}else{
- if(m->thumbs>1)
- xpad=((height+1)/2)+(height/2-3)*3/2+1;
- else
- xpad=height/2+1;
+ xpad=((height+1)/2)+(height/2-3)*3/2+1;
}
m->xpad=xpad;
@@ -362,10 +359,15 @@
if(m->levels[i]>0.)gc=1;
- gdk_draw_line (m->backing,
- widget->style->text_gc[gc],
- x, upad, x, y+upad);
-
+ if(m->readout)
+ gdk_draw_line (m->backing,
+ widget->style->text_gc[gc],
+ x, upad, x, y+upad);
+ else
+ gdk_draw_line (m->backing,
+ widget->style->text_gc[gc],
+ x, y/4+upad, x, y+upad);
+
if(i>0){
pango_layout_get_pixel_size(m->layout[i-1],&px,&py);
x-=px+2;
@@ -383,7 +385,7 @@
{
int width=widget->allocation.width;
int height=widget->allocation.height;
- int apad=(m->thumbs<2?-height/2+2:3-xpad);
+ int apad=3-xpad;
GdkGC *gc=parent->style->bg_gc[0];
GdkGC *light_gc=parent->style->light_gc[0];
GdkGC *dark_gc=parent->style->dark_gc[0];
@@ -455,12 +457,14 @@
int height=widget->allocation.height;
GdkGC *black_gc=widget->style->black_gc;
int y=height/2-3;
+ int y0=height/3-1;
int y1=height-3;
- int y0=y-(y1-y-1);
+ int yM=(y1+y0)/2-y0;
GdkColor yellow={0,0xff00,0xd000,0};
-
- if(m->thumbs>1){
+
+ if(m->thumbs==1){
+ /* single thumb: wide center */
GdkGC *gc=widget->style->bg_gc[m->thumbstate[0]];
GdkGC *light_gc=widget->style->light_gc[m->thumbstate[0]];
GdkGC *dark_gc=widget->style->dark_gc[m->thumbstate[0]];
@@ -470,123 +474,163 @@
int x1=x+(y1-y-2);
int x2=x0-y*3/2;
int x3=x1+y*3/2;
-
- GdkPoint tp[6]={ {x-1,y},{x2+3,y},{x2,y+3},
- {x2,y1+1},{x0-1,y1+1},{x0-1,y1-2}};
-
- gdk_draw_polygon(m->backing,gc,TRUE,tp,6);
-
- gdk_draw_line(m->backing,light_gc,x-2,y,x2+3,y);
- gdk_draw_line(m->backing,light_gc,x2+3,y,x2,y+3);
- gdk_draw_line(m->backing,light_gc,x2,y+3,x2,y1);
-
- gdk_draw_line(m->backing,dark_gc,x2+1,y1,x0-2,y1);
- gdk_draw_line(m->backing,dark_gc,x0-2,y1,x0-2,y1-2);
- gdk_draw_line(m->backing,dark_gc,x0-2,y1-2,x-3,y+1);
-
- gdk_draw_line(m->backing,black_gc,x2,y1+1,x0-1,y1+1);
- gdk_draw_line(m->backing,black_gc,x0-1,y1+1,x0-1,y1-2);
- gdk_draw_line(m->backing,black_gc,x0,y1-3,x-2,y+1);
-
- gdk_gc_set_rgb_fg_color(m->boxcolor,&yellow);
- gdk_draw_line(m->backing,m->boxcolor,x,0,x,height-lpad);
-
+
+ GdkPoint tp[7]={ {x,y0},{x-yM,y0+yM},{x2,y0+yM},{x2,y1+1},{x3,y1+1},{x3,y0+yM},{x+yM,y0+yM} };
+
+ gdk_draw_polygon(m->backing,gc,TRUE,tp,7);
+
+ gdk_draw_line(m->backing,dark_gc,x2+1,y1,x3-1,y1);
+ gdk_draw_line(m->backing,dark_gc,x3-1,y1,x3-1,y0+yM+1);
+
if(m->thumbfocus==0){
- GdkPoint tp[6]={ {x-3,y+1},{x2+3,y+1},{x2+1,y+3},
- {x2+1,y1+1},{x0-1,y1+1},{x0-1,y1-2}};
-
if(x&1)
gdk_gc_set_stipple(black_gc,stipple);
else
gdk_gc_set_stipple(black_gc,stippleB);
gdk_gc_set_fill(black_gc,GDK_STIPPLED);
- gdk_draw_polygon(m->backing,black_gc,TRUE,tp,6);
+ gdk_draw_polygon(m->backing,black_gc,TRUE,tp,7);
gdk_gc_set_fill(black_gc,GDK_SOLID);
}
-
+
+ gdk_draw_line(m->backing,light_gc,x3-1,y0+yM,x+yM,y0+yM);
+ gdk_draw_line(m->backing,light_gc,x+yM,y0+yM,x,y0);
+ gdk_draw_line(m->backing,light_gc,x,y0,x-yM,y0+yM);
+ gdk_draw_line(m->backing,light_gc,x-yM,y0+yM,x2,y0+yM);
+ gdk_draw_line(m->backing,light_gc,x2,y0+yM,x2,y1);
+
+ gdk_draw_line(m->backing,black_gc,x2,y1+1,x3,y1+1);
+ gdk_draw_line(m->backing,black_gc,x3,y1+1,x3,y0+yM);
+
+ gdk_gc_set_rgb_fg_color(m->boxcolor,&yellow);
+ gdk_draw_line(m->backing,m->boxcolor,x,y1-1,x,0);
+
}
-
+
if(m->thumbs>1){
- int num=(m->thumbs>2?2:1);
- GdkGC *gc=widget->style->bg_gc[m->thumbstate[num]];
- GdkGC *light_gc=widget->style->light_gc[m->thumbstate[num]];
- GdkGC *dark_gc=widget->style->dark_gc[m->thumbstate[num]];
- int x=m->thumbpixel[num]+xpad;
- int x0=x-(y1-y-2);
- int x1=x+(y1-y-2);
- int x2=x0-y*3/2;
- int x3=x1+y*3/2;
-
- GdkPoint tp[6]={ {x+1,y},{x3-3,y},{x3,y+3},
- {x3,y1+1},{x1+1,y1+1},{x1+1,y1-2}};
-
- gdk_draw_polygon(m->backing,gc,TRUE,tp,6);
-
- gdk_draw_line(m->backing,light_gc,x+1,y,x3-3,y);
- gdk_draw_line(m->backing,light_gc,x3-3,y,x3-1,y+2);
- gdk_draw_line(m->backing,light_gc,x1+1,y1-2,x1+1,y1);
-
- gdk_draw_line(m->backing,dark_gc,x+3,y+1,x1+1,y1-3);
- gdk_draw_point(m->backing,dark_gc,x1+1,y1-2);
- gdk_draw_line(m->backing,dark_gc,x1+2,y1,x3-1,y1);
- gdk_draw_line(m->backing,dark_gc,x3-1,y1,x3-1,y+3);
-
- gdk_draw_line(m->backing,black_gc,x+2,y+1,x1,y1-3);
- gdk_draw_line(m->backing,black_gc,x1+1,y1+1,x3,y1+1);
- gdk_draw_line(m->backing,black_gc,x3,y1+1,x3,y+4);
+ /* two thumbs: left */
+ {
+ GdkGC *gc=widget->style->bg_gc[m->thumbstate[0]];
+ GdkGC *light_gc=widget->style->light_gc[m->thumbstate[0]];
+ GdkGC *dark_gc=widget->style->dark_gc[m->thumbstate[0]];
+
+ int x=m->thumbpixel[0]+xpad;
+ int x0=x-(y1-y-2);
+ int x1=x+(y1-y-2);
+ int x2=x0-y*3/2;
+ int x3=x1+y*3/2;
+
+ GdkPoint tp[5]={ {x,y0},{x-yM,y0+yM},{x2,y0+yM},{x2,y1+1},
+ {x,y1+1}};
+
+ gdk_draw_polygon(m->backing,gc,TRUE,tp,5);
- gdk_gc_set_rgb_fg_color(m->boxcolor,&yellow);
- gdk_draw_line(m->backing,m->boxcolor,x,0,x,height-lpad);
+ gdk_draw_line(m->backing,dark_gc,x2+1,y1,x-1,y1);
+ gdk_draw_line(m->backing,dark_gc,x-1,y1,x-1,y0+1);
- if(m->thumbfocus==num){
- GdkPoint tp[6]={ {x+3,y+1},{x3-2,y+1},{x3,y+3},
- {x3,y1+1},{x1+1,y1+1},{x1+1,y1-2}};
+ if(m->thumbfocus==0){
+ if(x&1)
+ gdk_gc_set_stipple(black_gc,stipple);
+ else
+ gdk_gc_set_stipple(black_gc,stippleB);
+ gdk_gc_set_fill(black_gc,GDK_STIPPLED);
+ gdk_draw_polygon(m->backing,black_gc,TRUE,tp,5);
+ gdk_gc_set_fill(black_gc,GDK_SOLID);
+ }
+
+ gdk_draw_line(m->backing,light_gc,x,y0,x-yM,y0+yM);
+ gdk_draw_line(m->backing,light_gc,x-yM-1,y0+yM,x2,y0+yM);
+ gdk_draw_line(m->backing,light_gc,x2,y0+yM,x2,y1+1);
- if(x&1)
- gdk_gc_set_stipple(black_gc,stipple);
- else
- gdk_gc_set_stipple(black_gc,stippleB);
- gdk_gc_set_fill(black_gc,GDK_STIPPLED);
- gdk_draw_polygon(m->backing,black_gc,TRUE,tp,6);
- gdk_gc_set_fill(black_gc,GDK_SOLID);
+ gdk_draw_line(m->backing,black_gc,x2,y1+1,x,y1+1);
+ gdk_draw_line(m->backing,black_gc,x,y1+1,x,y0);
+
+ gdk_gc_set_rgb_fg_color(m->boxcolor,&yellow);
+ gdk_draw_line(m->backing,m->boxcolor,x,y1-1,x,0);
+
}
- }
-
- if(m->thumbs==1 || m->thumbs==3){
- int num=(m->thumbs>1?1:0);
-
- GdkGC *gc=widget->style->bg_gc[m->thumbstate[num]];
- GdkGC *light_gc=widget->style->light_gc[m->thumbstate[num]];
- GdkGC *dark_gc=widget->style->dark_gc[m->thumbstate[num]];
-
- int x=m->thumbpixel[num]+xpad;
- int x0=x-(y1-y-2);
- int x1=x+(y1-y-2);
+ /* two thumbs: right */
+ {
+ int num=(m->thumbs>2?2:1);
+ GdkGC *gc=widget->style->bg_gc[m->thumbstate[num]];
+ GdkGC *light_gc=widget->style->light_gc[m->thumbstate[num]];
+ GdkGC *dark_gc=widget->style->dark_gc[m->thumbstate[num]];
+
+ int x=m->thumbpixel[num]+xpad;
+ int x0=x-(y1-y-2);
+ int x1=x+(y1-y-2);
+ int x2=x0-y*3/2;
+ int x3=x1+y*3/2;
+
+ GdkPoint tp[5]={ {x,y0},{x+yM,y0+yM},{x3,y0+yM},{x3,y1+1},
+ {x,y1+1}};
- GdkPoint tp[5]={ {x,y},{x0,y1-2},{x0,y1+1},{x1,y1+1},{x1,y1-2} };
+ gdk_draw_polygon(m->backing,gc,TRUE,tp,5);
- gdk_draw_polygon(m->backing,gc,TRUE,tp,5);
+ gdk_draw_line(m->backing,dark_gc,x+1,y1,x3-1,y1);
+ gdk_draw_line(m->backing,dark_gc,x3-1,y1,x3-1,y0+yM+1);
- gdk_draw_line(m->backing,light_gc,x,y,x1,y1-2);
- gdk_draw_line(m->backing,light_gc,x,y,x0,y1-2);
- gdk_draw_line(m->backing,light_gc,x0,y1-2,x0,y1+1);
+ if(m->thumbfocus==num){
+ if(x&1)
+ gdk_gc_set_stipple(black_gc,stipple);
+ else
+ gdk_gc_set_stipple(black_gc,stippleB);
+ gdk_gc_set_fill(black_gc,GDK_STIPPLED);
+ gdk_draw_polygon(m->backing,black_gc,TRUE,tp,5);
+ gdk_gc_set_fill(black_gc,GDK_SOLID);
+ }
- gdk_draw_line(m->backing,dark_gc,x0+1,y1,x1-1,y1);
- gdk_draw_line(m->backing,dark_gc,x1-1,y1,x1-1,y1-2);
+ gdk_draw_line(m->backing,light_gc,x3-1,y0+yM,x+yM,y0+yM);
+ gdk_draw_line(m->backing,light_gc,x+yM,y0+yM,x,y0);
+ gdk_draw_line(m->backing,light_gc,x,y0,x,y1);
+
+ gdk_draw_line(m->backing,black_gc,x,y1+1,x3,y1+1);
+ gdk_draw_line(m->backing,black_gc,x3,y1+1,x3,y0+yM);
+
+ gdk_gc_set_rgb_fg_color(m->boxcolor,&yellow);
+ gdk_draw_line(m->backing,m->boxcolor,x,y1-1,x,0);
+
+ }
- gdk_draw_line(m->backing,black_gc,x0,y1+1,x1,y1+1);
- gdk_draw_line(m->backing,black_gc,x1,y1+1,x1,y1-1);
+ if(m->thumbs==3){
+ /* three thumbs: minimal center */
+ GdkGC *gc=widget->style->bg_gc[m->thumbstate[1]];
+ GdkGC *light_gc=widget->style->light_gc[m->thumbstate[1]];
+ GdkGC *dark_gc=widget->style->dark_gc[m->thumbstate[1]];
+
+ int x=m->thumbpixel[1]+xpad;
+ int x0=x-(y1-y0-3);
+ int x1=x+(y1-y0-3);
+
+ GdkPoint tp[5]={ {x,y0},{x0,y1-3},{x0,y1+1},{x1,y1+1},{x1,y1-3} };
+
+ gdk_draw_polygon(m->backing,gc,TRUE,tp,5);
+
+
+ gdk_draw_line(m->backing,dark_gc,x0+1,y1,x1-1,y1);
+ gdk_draw_line(m->backing,dark_gc,x1-1,y1,x1-1,y1-3);
+
+ if(m->thumbfocus==1){
+ 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,y0+i+2);
+ for(j=0;j<=(i-1)*2;j++)
+ if((j&1))
+ gdk_draw_point(m->backing,black_gc,x-(i-1)+j,y0+i+2);
+ }
- gdk_gc_set_rgb_fg_color(m->boxcolor,&yellow);
- gdk_draw_line(m->backing,m->boxcolor,x,y+(y1-y)/2,x,0);
+ gdk_draw_line(m->backing,light_gc,x,y0,x1,y1-3);
+ gdk_draw_line(m->backing,light_gc,x,y0,x0,y1-3);
+ gdk_draw_line(m->backing,light_gc,x0,y1-3,x0,y1+1);
- if(m->thumbfocus==num){
- 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);
- }
+ gdk_draw_line(m->backing,black_gc,x0,y1+1,x1,y1+1);
+ gdk_draw_line(m->backing,black_gc,x1,y1+1,x1,y1-2);
+
+ gdk_gc_set_rgb_fg_color(m->boxcolor,&yellow);
+ gdk_draw_line(m->backing,m->boxcolor,x,y1-1,x,0);
+
+ }
}
}
}
@@ -635,10 +679,7 @@
xpad=2;
}else{
maxy+=3;
- if(m->thumbs>1)
- xpad=((maxy+1)/2)+(maxy/2-3)*3/2+1;
- else
- xpad=maxy/2+1+2;
+ xpad=((maxy+1)/2)+(maxy/2-3)*3/2+1;
}
requisition->width = (maxx*1.5+2)*m->labels+xpad*2;
<p><p>1.5 +438 -469 postfish/multicompand.c
Index: multicompand.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/multicompand.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- a/multicompand.c 8 Mar 2004 11:07:06 -0000 1.4
+++ b/multicompand.c 17 Mar 2004 10:32:04 -0000 1.5
@@ -26,6 +26,7 @@
#include "multicompand.h"
#include <fftw3.h>
#include "subband.h"
+#include "bessel.h"
static int offset=0;
static void _analysis(char *base,int i,float *v,int n,int bark,int dB){
@@ -80,37 +81,35 @@
extern int input_rate;
extern int input_ch;
-/* An array of two tap Bessel filters for bandlimiting our followers
- and performing continuous RMS estimation. Why Bessel filters? Two
- reasons: They exhibit very little ringing in the time domain and
- about a half-order of magnitude less roundoff noise from gain
- (compared to other IIR families) */
-
-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
- 2.764099277e+02 // 700
-};
-
-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.7881166933, -0.8025879536} // 700
-};
-
-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};
+/* lookup table this soon */
+static float soft_knee(float x){
+ return atanf(-x*.2)*x/3.14159-x*.5-(5./M_PI);
+}
+
+static float hard_knee(float x){
+ return (x>0?-x:0.);
+}
+
+typedef struct {
+ double c0;
+ double c1;
+ double g;
+ float alpha;
+ //int impulseahead; // 5764 == 1Hz @ 44.1
+ //int stepahead; // 14850 == 1Hz @ 44.1
+} iir_filter;
+
+static inline long impulse_ahead(float alpha){
+ return rint(.1307f/alpha);
+}
+
+static inline long step_ahead(float alpha){
+ return rint(.3367f/alpha);
+}
+
+static inline float step_freq(long ahead){
+ return input_rate*.3367/ahead;
+}
#if NASTY_IEEE_FLOAT32_HACK_IS_FASTER_THAN_LOG
@@ -123,34 +122,38 @@
#endif
typedef struct {
- /* RMS follower state */
- float rms_smooth_y[2];
- float rms_smooth_x[2];
-
- float static_c_decay_chase;
- float static_e_decay_chase;
- float static_g_decay_chase;
- float suppress_decay_chase;
-
- float env1_x[2];
- float env1_y[2];
- float env2_x[2];
- float env2_y[2];
-
- int dummymarker;
-} envelope_state;
+ double x[2];
+ double y[2];
+ int state;
+} iir_state;
typedef struct {
subband_state ss;
subband_window sw[multicomp_banks];
+
+ iir_filter over_attack[multicomp_banks][multicomp_freqs_max];
+ iir_filter over_decay[multicomp_banks][multicomp_freqs_max];
+
+ iir_filter under_attack[multicomp_banks][multicomp_freqs_max];
+ iir_filter under_decay[multicomp_banks][multicomp_freqs_max];
- int rmschoice[multicomp_banks][multicomp_freqs_max];
- int attack[multicomp_banks][multicomp_freqs_max];
- int decay[multicomp_banks][multicomp_freqs_max];
+ iir_filter suppress_attack[multicomp_banks][multicomp_freqs_max];
+ iir_filter suppress_decay[multicomp_banks][multicomp_freqs_max];
+ iir_filter suppress_release[multicomp_banks][multicomp_freqs_max];
+
+ iir_state *over_iir[multicomp_freqs_max];
+ iir_state *under_iir[multicomp_freqs_max];
+ iir_state *suppress_iirA[multicomp_freqs_max];
+ iir_state *suppress_iirB[multicomp_freqs_max];
- envelope_state **e;
sig_atomic_t pending_bank;
sig_atomic_t active_bank;
+
+ int previous_over_mode; // RMS or peak? The iir follower domains
+ // are different, and upon transition, must be converted.
+ int previous_under_mode; // as above
+ int previous_suppress_mode; // as above
+
} multicompand_state;
sig_atomic_t compand_visible;
@@ -170,15 +173,14 @@
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.;
+
+ for(i=0;i<multicomp_freqs_max;i++)
+ for(j=0;j<input_ch;j++){
+ memset(&ms.over_iir[i][j],0,sizeof(iir_state));
+ memset(&ms.under_iir[i][j],0,sizeof(iir_state));
+ memset(&ms.suppress_iirA[i][j],0,sizeof(iir_state));
+ memset(&ms.suppress_iirB[i][j],0,sizeof(iir_state));
}
-
}
int multicompand_load(void){
@@ -188,140 +190,182 @@
subband_load(&ms.ss,multicomp_freqs_max,qblocksize);
- for(h=0;h<multicomp_banks;h++){
+ 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;
- }
- }
- }
-
- 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.over_iir[i]=calloc(input_ch,sizeof(iir_state));
+ ms.under_iir[i]=calloc(input_ch,sizeof(iir_state));
+ ms.suppress_iirA[i]=calloc(input_ch,sizeof(iir_state));
+ ms.suppress_iirB[i]=calloc(input_ch,sizeof(iir_state));
}
-
+
ms.active_bank=0;
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);
+int multicompand_filterbank_set(float msec,iir_filter filterbank[multicomp_banks][multicomp_freqs_max]){
+ int i,j;
+ for(j=0;j<multicomp_banks;j++){
+ float *freqs=multicomp_freq_list[j];
+ int bands=multicomp_freqs[j];
+ iir_filter *filters=filterbank[j];
- 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(i=0;i<bands;i++){
+ float alpha;
+ float corner_freq=500./msec;
+
+ /* limit the filter corner frequency to prevent fast attacks
+ from destroying low frequencies */
+ if(corner_freq>freqs[i]/2)corner_freq=freqs[i]/2;
- 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;
- }
+ /* 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)*.95<freqs[i])
+ corner_freq=step_freq(input_size*2-ms.ss.qblocksize*3);
+
+ alpha=corner_freq/input_rate*2.;
+ filters[i].g=mkbessel_2(alpha,&filters[i].c0,&filters[i].c1);
+ filters[i].alpha=alpha;
+ }
+ }
+}
+
- 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;
+int multicompand_over_attack_set(float msec){
+ multicompand_filterbank_set(msec,ms.over_attack);
+}
+
+int multicompand_over_decay_set(float msec){
+ multicompand_filterbank_set(msec,ms.over_decay);
+}
+
+int multicompand_under_attack_set(float msec){
+ multicompand_filterbank_set(msec,ms.under_attack);
+}
+
+int multicompand_under_decay_set(float msec){
+ multicompand_filterbank_set(msec,ms.under_decay);
+}
+
+int multicompand_suppress_attack_set(float msec){
+ multicompand_filterbank_set(msec,ms.suppress_attack);
+}
+
+int multicompand_suppress_decay_set(float msec){
+ multicompand_filterbank_set(msec,ms.suppress_decay);
+}
+
+int multicompand_suppress_release_set(float msec){
+ multicompand_filterbank_set(msec,ms.suppress_release);
+}
+
+/* assymetrical attack/decay filter; the z-space fixup is designed for
+ the case where decay is the same or slower than attack */
+/* The Bessel filter followers are inlined here as later to avoid some
+ really shockingly bad code generation by gcc on x86 */
+static void compute_iir(float *y, float *x, int n,
+ iir_state *is, iir_filter *attack, iir_filter *decay){
+ double a_c0=attack->c0;
+ double d_c0=decay->c0;
+ double a_c1=attack->c1;
+ double d_c1=decay->c1;
+ double a_g=attack->g;
+ double d_g=decay->g;
+
+ double x0=is->x[0];
+ double x1=is->x[1];
+ double y0=is->y[0];
+ double y1=is->y[1];
+ int state=is->state;
+
+ int i=0;
+
+ if(x[0]>y0)state=0;
- }
+ while(i<n){
- {
- float scale=(linkp?1./input_ch:1);
- for(k=0;k<input_size;k++){
- val=fabs(rms[k]*scale);
- rms[k]=sqrt(val);
+ if(state==0){
+ /* attack case */
+ while(i<n){
+ y[i] = (x[i]+x0*2.+x1)/a_g + y0*a_c0+y1*a_c1;
+
+ if(y[i]<y0){
+ /* decay fixup; needed because we're in discontinuous time. In a
+ physical time-assymmetric Bessel follower, the decay case would
+ take over at the instant the attack filter peaks. In z-space,
+ the attack filter has already begun to decay, and the decay
+ filter otherwise takes over with an already substantial
+ negative slope in the filter state, or if it takes over in the
+ preceeding time quanta, a substantial positive slope. Fix this
+ up to take over at zero y slope. */
+ y1=y0;
+ state=1;
+ break;
+ }
+ x1=x0;x0=x[i];
+ y1=y0;y0=y[i];
+ i++;
}
- }
+ }
- for(k=0;k<input_size;k++)
- rms[k]=todB_p(rms+k);
+ if(state==1){
+ /* decay case */
+ while(1){
+ y[i] = (x[i]+x0*2+x1)/d_g + y0*d_c0+y1*d_c1;
+
+ x1=x0;x0=x[i];
+ y1=y0;y0=y[i];
+ i++;
+
+ if(i>=n)break;
+ if(x[i]>y0){
+ state=0;
+ break;
+ }
+ }
+ }
+ }
+
+ is->x[0]=x0;
+ is->x[1]=x1;
+ is->y[0]=y0;
+ is->y[1]=y1;
+ is->state=state;
+
+}
+
+static void prepare_rms(float *rms, float **xx, int n, int ch,int ahead){
+ if(ch){
+ int i,j;
+
+ memset(rms,0,sizeof(*rms)*n);
+ for(j=0;j<ch;j++){
+ float *x=xx[j]+ahead;
+ for(i=0;i<n;i++)
+ rms[i]+=x[i]*x[i];
+ }
+ if(ch>1)
+ for(i=0;i<n;i++)
+ rms[i]/=ch;
}
}
-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++){
+static void prepare_peak(float *peak, float **xx, int n, int ch,int ahead){
+ if(ch){
+ int j,k,l;
+
+ memset(peak,0,sizeof(*peak)*n);
+
+ for(l=0;l<ch;l++){
- float *x=xxi[l];
+ float *x=xx[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++)
@@ -331,7 +375,7 @@
}
if(val>peak[0])peak[0]=val;
- for(ii=1;ii<input_size;ii++){
+ for(ii=1;ii<n;ii++){
if(fabs(x[ii+ahead])>val){
val=fabs(x[ii+ahead]);
loc=ii+ahead;
@@ -341,118 +385,170 @@
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;
+ if(jj<n && 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);
}
+
+ for(j=0;j<n;j++)
+ peak[j]=todB_p(peak+j);
}
}
-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;
+static void run_filter_only(float *dB,float *work,float **x,int n,int mode,
+ iir_state *iir,iir_filter *attack,iir_filter *decay){
+ int i;
- 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);
+ compute_iir(dB, work, n, &iir[i], attack, decay);
- 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(mode==0)
+ for(i=0;i<n;i++)
+ dB[i]=todB_p(dB+i)*.5f;
+}
-
- if(adj<-150.)adj=-150;
- gain[ii]=adj;
+static void run_filter(float *dB,float *work,float **x,int n, int ch, int i,
+ float lookahead,int link,int mode,
+ iir_state *iir,iir_filter *attack,iir_filter *decay){
+ if(link){
+ if(i==0){
+ if(mode)
+ prepare_peak(work, x, n, ch, step_ahead(attack->alpha)*lookahead);
+
+ else
+ prepare_rms(work, x, n, ch, impulse_ahead(attack->alpha)*lookahead);
+
+ }
+ }else{
+ if(mode)
+ prepare_peak(work, x+i, n, 1, step_ahead(attack->alpha)*lookahead);
+ else
+ prepare_rms(work, x+i, n, 1, impulse_ahead(attack->alpha)*lookahead);
}
-
- e->static_c_decay_chase=current_c;
- e->static_e_decay_chase=current_e;
- e->static_g_decay_chase=current_g;
-
+
+ run_filter_only(dB,work,x,n,mode,iir,attack,decay);
}
-static void range_compand(float *peak, float *rms, float *gain){
- int ii;
- float *envelope;
- float ratio=1.+c.envelope_c/1000.;
+static void over_compand(float ***x){
+ int i,j,k;
+ float work[input_size];
+ float dB[input_size];
+ float lookahead=c.over_lookahead/1000.;
+ int link=c.link_mode;
+ int mode=c.over_mode;
+
+ float (*knee)(float)=(c.over_softknee?soft_knee:hard_knee);
- switch(c.envelope_mode){
- case 0:
- envelope=rms;
- break;
- default:
- envelope=peak;
- break;
+ float corner_multiplier=(1.-1./(c.over_ratio/1000.));
+ float base_multiplier=(1.-1./(c.base_ratio/1000.));
+
+ if(ms.previous_over_mode!=mode){
+ /* the followers for RMS are in linear^2 mode, the followers for
+ peak are dB. If the mode has changed, we need to convert from
+ one to the other to avoid pops */
+ if(mode==0){
+ /* from dB to linear^2 */
+ for(i=0;i<multicomp_freqs_max;i++){
+ for(j=0;j<input_ch;j++){
+ ms.over_iir[i][j].x[0]=fromdB(ms.over_iir[i][j].x[0]*2.);
+ ms.over_iir[i][j].x[1]=fromdB(ms.over_iir[i][j].x[1]*2.);
+ ms.over_iir[i][j].y[0]=fromdB(ms.over_iir[i][j].y[0]*2.);
+ ms.over_iir[i][j].y[1]=fromdB(ms.over_iir[i][j].y[1]*2.);
+ }
+ }
+ }else{
+ /* from linear^2 to dB */
+ for(i=0;i<multicomp_freqs_max;i++){
+ for(j=0;j<input_ch;j++){
+ ms.over_iir[i][j].x[0]=todB(ms.over_iir[i][j].x[0])*.5;
+ ms.over_iir[i][j].x[1]=todB(ms.over_iir[i][j].x[1])*.5;
+ ms.over_iir[i][j].y[0]=todB(ms.over_iir[i][j].y[0])*.5;
+ ms.over_iir[i][j].y[1]=todB(ms.over_iir[i][j].y[1])*.5;
+ }
+ }
+ }
}
+
+ ms.previous_over_mode=mode;
+
+ for(i=0;i<multicomp_freqs[ms.active_bank];i++){
+ float zerocorner=bc[ms.active_bank].static_o[i]/10.;
+ float limitcorner=zerocorner + fabs((c.over_limit*10.)/corner_multiplier);
+
+ for(j=0;j<input_ch;j++){
+ float *lx=x[i][j];
+ run_filter(dB,work,x[i],input_size,input_ch,j,lookahead,link,mode,
+ ms.over_iir[i],&ms.over_attack[ms.active_bank][i],&ms.over_decay[ms.active_bank][i]);
+
+ if(compand_active)
+ for(k=0;k<input_size;k++){
+ float adj=(knee(dB[i]-zerocorner)-knee(dB[i]-limitcorner))*corner_multiplier;
+ adj-= (dB[i]+adj)*base_multiplier;
+ lx[k]*=fromdB(adj);
+ }
+ }
+ }
+}
+
+static void under_compand(float ***x){
+ int i,j,k;
+ float work[input_size];
+ float dB[input_size];
+ float lookahead=c.under_lookahead/1000.;
+ int link=c.link_mode;
+ int mode=c.under_mode;
+
+ float (*knee)(float)=(c.under_softknee?soft_knee:hard_knee);
- for(ii=0;ii<input_size;ii++){
- float adj=0.;
- float current=envelope[ii];
- float target=current*ratio;
-
- gain[ii]+=target-current;
+ float corner_multiplier=(1.-1./(c.under_ratio/1000.));
+
+ if(ms.previous_under_mode!=mode){
+ /* the followers for RMS are in linear^2 mode, the followers for
+ peak are dB. If the mode has changed, we need to convert from
+ one to the other to avoid pops */
+ if(mode==0){
+ /* from dB to linear^2 */
+ for(i=0;i<multicomp_freqs_max;i++){
+ for(j=0;j<input_ch;j++){
+ ms.under_iir[i][j].x[0]=fromdB(ms.under_iir[i][j].x[0]*2.);
+ ms.under_iir[i][j].x[1]=fromdB(ms.under_iir[i][j].x[1]*2.);
+ ms.under_iir[i][j].y[0]=fromdB(ms.under_iir[i][j].y[0]*2.);
+ ms.under_iir[i][j].y[1]=fromdB(ms.under_iir[i][j].y[1]*2.);
+ }
+ }
+ }else{
+ /* from linear^2 to dB */
+ for(i=0;i<multicomp_freqs_max;i++){
+ for(j=0;j<input_ch;j++){
+ ms.under_iir[i][j].x[0]=todB(ms.under_iir[i][j].x[0])*.5;
+ ms.under_iir[i][j].x[1]=todB(ms.under_iir[i][j].x[1])*.5;
+ ms.under_iir[i][j].y[0]=todB(ms.under_iir[i][j].y[0])*.5;
+ ms.under_iir[i][j].y[1]=todB(ms.under_iir[i][j].y[1])*.5;
+ }
+ }
+ }
+ }
+
+ ms.previous_under_mode=mode;
+
+ for(i=0;i<multicomp_freqs[ms.active_bank];i++){
+ float zerocorner=bc[ms.active_bank].static_o[i]/10.;
+ float limitcorner=zerocorner- fabs((c.under_limit*10.)/corner_multiplier);
+
+ for(j=0;j<input_ch;j++){
+ float *lx=x[i][j];
+ run_filter(dB,work,x[i],input_size,input_ch,j,lookahead,link,mode,
+ ms.under_iir[i],&ms.under_attack[ms.active_bank][i],&ms.under_decay[ms.active_bank][i]);
+ if(compand_active)
+ for(k=0;k<input_size;k++)
+ lx[k]*=fromdB((knee(zerocorner-dB[i])-knee(limitcorner-dB[i]))*corner_multiplier);
+ }
}
}
-static void suppress(float *peak, float *rms, float *gain,
- envelope_state *e){
/* (since this one is kinda unique) The Suppressor....
Reverberation in a measurably live environment displays
@@ -472,231 +568,114 @@
Thus, the suppressor can be used to 'dry out' a very 'wet'
reverberative track. */
- int ii;
- float *envelope;
- float ratio=c.suppress_ratio/100.;
- float decay=c.suppress_decay/(float)(1024*1024);
- float depth=-c.suppress_depth/10.;
- float chase=e->suppress_decay_chase;
- float undepth=depth/ratio;
-
- switch(c.suppress_mode){
- case 0:
- envelope=rms;
- break;
- default:
- envelope=peak;
- break;
- }
-
- for(ii=0;ii<input_size;ii++){
- float current=envelope[ii];
-
- chase+=decay;
- if(current>chase){
- chase=current;
- }else{
- /* yes, need to expand */
- float difference = chase - current;
- float expanded = difference * ratio;
+static void suppress(float ***x){
+ int i,j,k;
+ float work[input_size];
+ float dB_fast[input_size];
+ float dB_slow[input_size];
+ int link=c.link_mode;
+ int mode=c.suppress_mode;
- if(expanded>depth){
- chase=current+undepth;
- gain[ii]-=depth-undepth;
- }else{
- gain[ii]-=expanded-difference;
+ float multiplier=(1.-1./(c.suppress_ratio/1000.));
+ if(ms.previous_suppress_mode!=mode){
+ /* the followers for RMS are in linear^2 mode, the followers for
+ peak are dB. If the mode has changed, we need to convert from
+ one to the other to avoid pops */
+ if(mode==0){
+ /* from dB to linear^2 */
+ for(i=0;i<multicomp_freqs_max;i++){
+ for(j=0;j<input_ch;j++){
+ ms.suppress_iirA[i][j].x[0]=fromdB(ms.suppress_iirA[i][j].x[0]*2.);
+ ms.suppress_iirA[i][j].x[1]=fromdB(ms.suppress_iirA[i][j].x[1]*2.);
+ ms.suppress_iirA[i][j].y[0]=fromdB(ms.suppress_iirA[i][j].y[0]*2.);
+ ms.suppress_iirA[i][j].y[1]=fromdB(ms.suppress_iirA[i][j].y[1]*2.);
+ ms.suppress_iirB[i][j].x[0]=fromdB(ms.suppress_iirB[i][j].x[0]*2.);
+ ms.suppress_iirB[i][j].x[1]=fromdB(ms.suppress_iirB[i][j].x[1]*2.);
+ ms.suppress_iirB[i][j].y[0]=fromdB(ms.suppress_iirB[i][j].y[0]*2.);
+ ms.suppress_iirB[i][j].y[1]=fromdB(ms.suppress_iirB[i][j].y[1]*2.);
+ }
+ }
+ }else{
+ /* from linear^2 to dB */
+ for(i=0;i<multicomp_freqs_max;i++){
+ for(j=0;j<input_ch;j++){
+ ms.suppress_iirA[i][j].x[0]=todB(ms.suppress_iirA[i][j].x[0])*.5;
+ ms.suppress_iirA[i][j].x[1]=todB(ms.suppress_iirA[i][j].x[1])*.5;
+ ms.suppress_iirA[i][j].y[0]=todB(ms.suppress_iirA[i][j].y[0])*.5;
+ ms.suppress_iirA[i][j].y[1]=todB(ms.suppress_iirA[i][j].y[1])*.5;
+ ms.suppress_iirB[i][j].x[0]=todB(ms.suppress_iirB[i][j].x[0])*.5;
+ ms.suppress_iirB[i][j].x[1]=todB(ms.suppress_iirB[i][j].x[1])*.5;
+ ms.suppress_iirB[i][j].y[0]=todB(ms.suppress_iirB[i][j].y[0])*.5;
+ ms.suppress_iirB[i][j].y[1]=todB(ms.suppress_iirB[i][j].y[1])*.5;
+ }
}
}
}
- e->suppress_decay_chase=chase;
-}
-
-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];
+ ms.previous_suppress_mode=mode;
- /* assymetrical filter; in general, fast attack, slow decay */
- 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;
- }
+ for(i=0;i<multicomp_freqs[ms.active_bank];i++){
+ for(j=0;j<input_ch;j++){
+ float *lx=x[i][j];
- 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;
+ run_filter(dB_fast,work,x[i],input_size,input_ch,j,1.,link,mode,
+ ms.suppress_iirA[i],&ms.suppress_attack[ms.active_bank][i],&ms.suppress_decay[ms.active_bank][i]);
+ run_filter_only(dB_slow,work,x[i],input_size,mode,
+ ms.suppress_iirB[i],&ms.suppress_attack[ms.active_bank][i],&ms.suppress_release[ms.active_bank][i]);
+
+ if(compand_active && multiplier!=0.)
+ for(k=0;k<input_size;k++){
+ float adj=(dB_fast[i]-dB_slow[i])*multiplier;
+ lx[k]*=fromdB(adj);
+ }
}
}
-
- e->env2_x[0]=iirx0;
- e->env2_x[1]=iirx1;
- e->env2_y[0]=iiry0;
- e->env2_y[1]=iiry1;
-
}
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];
- 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 */
+ int i,j,k;
- for(j=0;j<bands;j++){
- for(i=0;i<input_ch;i++){
-
- //_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]);
+ under_compand(ms.ss.lap);
+ over_compand(ms.ss.lap);
- /* 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;
+ /* feedback displays the results of the static compander */
+ if(c.link_mode==0){
+ for(i=0;i<multicomp_freqs[ms.active_bank];i++){
+ for(j=0;j<input_ch;j++){
+ float *x=ms.ss.lap[i][j];
+ float rms=0,peak=0;
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]);
+ rms+=x[k]*x[k];
+ if(fabs(x[k])>peak)peak=fabs(x[k]);
}
- peakfeed[j][i]=todB(peakmax);
- rmsfeed[j][i]=rmsmax;
+ peakfeed[i][j]=todB(peak);
+ rmsfeed[i][j]=todB(rms/input_size)*.5;
}
-
- if(compand_active){
- float *x=ms.ss.lap[j][i];
-
- /* run the range compander */
- range_compand(peak,rms,gain);
-
- /* run the suppressor */
- suppress(peak,rms,gain,ms.e[j]);
-
- //_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]);
+ }
+ }else{
+ for(i=0;i<multicomp_freqs[ms.active_bank];i++){
+ float rms=0,peak=0;
+ for(j=0;j<input_ch;j++){
+ float *x=ms.ss.lap[i][j];
- //_analysis_append("gain",j,gain,input_size,offset);
+ for(k=0;k<input_size;k++){
+ rms+=x[k]*x[k];
+ if(fabs(x[k])>peak)peak=fabs(x[k]);
+ }
+ }
-
- /* 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.;
+ for(j=0;j<input_ch;j++){
+ peakfeed[i][j]=todB(peak);
+ rmsfeed[i][j]=todB(rms/input_size/input_ch)*.5;
}
}
}
+ suppress(ms.ss.lap);
+
offset+=input_size;
}
@@ -712,17 +691,7 @@
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;
<p><p>1.3 +32 -18 postfish/multicompand.h
Index: multicompand.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/multicompand.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- a/multicompand.h 8 Mar 2004 02:08:23 -0000 1.2
+++ b/multicompand.h 17 Mar 2004 10:32:04 -0000 1.3
@@ -46,31 +46,39 @@
};
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];
+ sig_atomic_t static_o[multicomp_freqs_max];
+ sig_atomic_t static_u[multicomp_freqs_max];
} banked_compand_settings;
typedef struct {
- sig_atomic_t link_mode;
-
- sig_atomic_t static_mode;
- 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 envelope_mode;
- sig_atomic_t envelope_c;
+ sig_atomic_t over_mode;
+ sig_atomic_t over_softknee;
+ sig_atomic_t over_ratio;
+ sig_atomic_t over_limit;
+ sig_atomic_t base_ratio;
+ sig_atomic_t over_attack;
+ sig_atomic_t over_decay;
+ sig_atomic_t over_lookahead;
+ sig_atomic_t over_trim;
+
+ sig_atomic_t under_mode;
+ sig_atomic_t under_softknee;
+ sig_atomic_t under_ratio;
+ sig_atomic_t under_limit;
+ sig_atomic_t under_attack;
+ sig_atomic_t under_decay;
+ sig_atomic_t under_lookahead;
+ sig_atomic_t under_trim;
sig_atomic_t suppress_mode;
sig_atomic_t suppress_ratio;
+
+ sig_atomic_t suppress_attack;
sig_atomic_t suppress_decay;
- sig_atomic_t suppress_depth;
+ sig_atomic_t suppress_release;
+
+ sig_atomic_t link_mode;
} other_compand_settings;
@@ -80,4 +88,10 @@
extern void multicompand_set_bank(int bank);
extern int pull_multicompand_feedback(float **peak,float **rms,int *bands);
-
+extern int multicompand_over_attack_set(float msec);
+extern int multicompand_over_decay_set(float msec);
+extern int multicompand_under_attack_set(float msec);
+extern int multicompand_under_decay_set(float msec);
+extern int multicompand_suppress_attack_set(float msec);
+extern int multicompand_suppress_decay_set(float msec);
+extern int multicompand_suppress_release_set(float msec);
<p><p>1.10 +8 -2 postfish/postfish-gtkrc
Index: postfish-gtkrc
===================================================================
RCS file: /usr/local/cvsroot/postfish/postfish-gtkrc,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- a/postfish-gtkrc 8 Mar 2004 02:08:23 -0000 1.9
+++ b/postfish-gtkrc 17 Mar 2004 10:32:04 -0000 1.10
@@ -20,7 +20,12 @@
}
style "small-marker" {
- font_name = "sans 8"
+ fg[NORMAL]="#905050"
+ font_name = "sans 6"
+}
+
+style "scale-marker" {
+ font_name = "sans 7"
}
style "frame-label" {
@@ -59,7 +64,7 @@
text[NORMAL]="#c0c0d0"
text[ACTIVE]="#ffb0b0"
- font_name = "sans 6"
+ font_name = "sans 7"
}
style "multislide" {
@@ -138,6 +143,7 @@
}
widget "*.GtkLabel" style "panel-text"
+widget "*.scalemarker" style "scale-marker"
widget "*.smallmarker" style "small-marker"
widget "*.color0" style "left"
<p><p>1.43 +2 -2 postfish/version.h
Index: version.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/version.h,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -r1.42 -r1.43
--- a/version.h 8 Mar 2004 11:07:06 -0000 1.42
+++ b/version.h 17 Mar 2004 10:32:04 -0000 1.43
@@ -1,2 +1,2 @@
-#define VERSION "$Id: version.h,v 1.42 2004/03/08 11:07:06 xiphmont Exp $ "
-/* DO NOT EDIT: Automated versioning hack [Mon Mar 8 06:01:38 EST 2004] */
+#define VERSION "$Id: version.h,v 1.43 2004/03/17 10:32:04 xiphmont Exp $ "
+/* DO NOT EDIT: Automated versioning hack [Wed Mar 17 05:30:15 EST 2004] */
<p><p>1.1 postfish/bessel.c
Index: bessel.c
===================================================================
/*
*
* postfish
*
* Copyright (C) 2002-2004 Monty
*
* Postfish is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* Postfish is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
/* code derived directly from mkfilter by the late A.J. Fisher,
University of York <fisher at minster.york.ac.uk> September 1992; this
is only the minimum code needed to build an arbitrary 2nd order
Bessel filter */
#include "postfish.h"
#define TWOPI (2.0 * M_PIl)
#define EPS 1e-10
#define MAXORDER 2
#define MAXPZ 4
typedef struct {
double re, im;
} complex;
typedef struct {
complex poles[MAXPZ], zeros[MAXPZ];
int numpoles, numzeros;
} pzrep;
tatic complex cdiv(complex z1, complex z2){
double mag = (z2.re * z2.re) + (z2.im * z2.im);
complex ret={((z1.re * z2.re) + (z1.im * z2.im)) / mag,
((z1.im * z2.re) - (z1.re * z2.im)) / mag};
return ret;
}
tatic complex cmul(complex z1, complex z2){
complex ret={z1.re*z2.re - z1.im*z2.im,
z1.re*z2.im + z1.im*z2.re};
return ret;
}
static complex cadd(complex z1, complex z2){
z1.re+=z2.re;
z1.im+=z2.im;
return z1;
}
tatic complex csub(complex z1, complex z2){
z1.re-=z2.re;
z1.im-=z2.im;
return z1;
}
tatic complex eval(complex coeffs[], int npz, complex z){
complex sum = (complex){0.0,0.0};
int i;
for (i = npz; i >= 0; i--) sum = cadd(cmul(sum, z), coeffs[i]);
return sum;
}
tatic complex evaluate(complex topco[], int nz, complex botco[], int np, complex z){
return cdiv(eval(topco, nz, z),eval(botco, np, z));
}
tatic complex blt(complex pz){
complex two={2.,0.};
return cdiv(cadd(two, pz), csub(two, pz));
}
tatic void multin(complex w, int npz, complex coeffs[]){
int i;
complex nw = (complex){-w.re , -w.im};
for (i = npz; i >= 1; i--)
coeffs[i] = cadd(cmul(nw, coeffs[i]), coeffs[i-1]);
coeffs[0] = cmul(nw, coeffs[0]);
}
static void expand(complex pz[], int npz, complex coeffs[]){
/* compute product of poles or zeros as a polynomial of z */
int i;
coeffs[0] = (complex){1.0,0.0};
for (i=0; i < npz; i++) coeffs[i+1] = (complex){0.0,0.0};
for (i=0; i < npz; i++) multin(pz[i], npz, coeffs);
/* check computed coeffs of z^k are all real */
for (i=0; i < npz+1; i++){
if (fabs(coeffs[i].im) > EPS){
fprintf(stderr, "mkfilter: coeff of z^%d is not real; poles/zeros are not complex conjugates\n", i);
exit(1);
}
}
}
double mkbessel_2(double raw_alpha,double *ycoeff0,double *ycoeff1){
int i;
pzrep splane, zplane;
complex topcoeffs[MAXPZ+1], botcoeffs[MAXPZ+1];
double warped_alpha;
complex dc_gain;
memset(&splane,0,sizeof(splane));
memset(&zplane,0,sizeof(zplane));
splane.poles[splane.numpoles++] = (complex){ -1.10160133059e+00, 6.36009824757e-01};
splane.poles[splane.numpoles++] = (complex){ -1.10160133059e+00, -6.36009824757e-01};
warped_alpha = tan(M_PIl * raw_alpha) / M_PIl;
for (i = 0; i < splane.numpoles; i++){
splane.poles[i].re *= TWOPI * warped_alpha;
splane.poles[i].im *= TWOPI * warped_alpha;
}
zplane.numpoles = splane.numpoles;
zplane.numzeros = splane.numzeros;
for (i=0; i < zplane.numpoles; i++)
zplane.poles[i] = blt(splane.poles[i]);
for (i=0; i < zplane.numzeros; i++)
zplane.zeros[i] = blt(splane.zeros[i]);
while (zplane.numzeros < zplane.numpoles)
zplane.zeros[zplane.numzeros++] = (complex){-1.0,0.};
expand(zplane.zeros, zplane.numzeros, topcoeffs);
expand(zplane.poles, zplane.numpoles, botcoeffs);
dc_gain = evaluate(topcoeffs, zplane.numzeros, botcoeffs, zplane.numpoles, (complex){1.0,0.0});
*ycoeff0 = -(botcoeffs[0].re / botcoeffs[zplane.numpoles].re);
*ycoeff1 = -(botcoeffs[1].re / botcoeffs[zplane.numpoles].re);
return hypot(dc_gain.re,dc_gain.im);
}
<p><p><p><p><p>1.1 postfish/bessel.h
Index: bessel.h
===================================================================
/*
*
* postfish
*
* Copyright (C) 2002-2004 Monty
*
* Postfish is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* Postfish is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
extern double mkbessel_2(double raw_alpha,double *ycoeff0,double *ycoeff1);
<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