[xiph-cvs] r6712 - trunk/postfish
xiphmont at xiph.org
xiphmont at xiph.org
Mon May 17 01:16:58 PDT 2004
Author: xiphmont
Date: 2004-05-17 04:16:56 -0400 (Mon, 17 May 2004)
New Revision: 6712
Added:
trunk/postfish/mix.c
trunk/postfish/mix.h
trunk/postfish/mixpanel.c
trunk/postfish/mixpanel.h
trunk/postfish/reverb.c
trunk/postfish/reverb.h
Removed:
trunk/postfish/mutedummy.c
Modified:
trunk/postfish/Makefile
trunk/postfish/bessel.c
trunk/postfish/bessel.h
trunk/postfish/clippanel.c
trunk/postfish/compandpanel.c
trunk/postfish/declip.c
trunk/postfish/eq.c
trunk/postfish/eq.h
trunk/postfish/eqpanel.c
trunk/postfish/freq.c
trunk/postfish/freq.h
trunk/postfish/input.c
trunk/postfish/limit.c
trunk/postfish/limit.h
trunk/postfish/limitpanel.c
trunk/postfish/main.c
trunk/postfish/mainpanel.c
trunk/postfish/mainpanel.h
trunk/postfish/multibar.c
trunk/postfish/multicompand.c
trunk/postfish/multicompand.h
trunk/postfish/mute.c
trunk/postfish/output.c
trunk/postfish/postfish.h
trunk/postfish/singlecomp.c
trunk/postfish/singlecomp.h
trunk/postfish/singlepanel.c
trunk/postfish/subband.c
trunk/postfish/subband.h
trunk/postfish/suppress.c
trunk/postfish/suppresspanel.c
trunk/postfish/version.h
Log:
Weekend dabbling in postfish
fromdB_a approximation guarding fix
bounds fix in subband filter setup
Altivec underflow exception disabling
mixdown block implementation
reverberation driver (untested)
<p><p>Modified: trunk/postfish/Makefile
===================================================================
--- trunk/postfish/Makefile 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/Makefile 2004-05-17 08:16:56 UTC (rev 6712)
@@ -2,26 +2,34 @@
# Fuck the horse it rode in on
# and Fuck its little dog Libtool too
-ADD_DEF= -DUGLY_IEEE754_FLOAT32_HACK=1
+
+ADD_DEF= -DUGLY_IEEE754_FLOAT32_HACK=1 -maltivec
+
+# use for PPC with altivec. IF YOU HAVE ALTIVEC, YOU MUST USE THIS
+# LINE, otherwise FFTW3 will randomly crash whenever it uses Altivec
+# and any math denormalizes.
+
+#ADD_DEF= -DUGLY_IEEE754_FLOAT32_HACK=1 -maltivec
+
CC=gcc
LD=gcc
INSTALL=install
PREFIX=/usr/local
BINDIR=$PREFIX/bin
-ETCDIR=/etc
+ETCDIR=/etc/postfish
MANDIR=$PREFIX/man
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 \
bessel.c suppresspanel.c suppress.c singlecomp.c singlepanel.c \
- limit.c limitpanel.c mute.c mutedummy.c
+ limit.c limitpanel.c mute.c mixpanel.c mix.c reverb.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 \
bessel.o suppresspanel.o suppress.o singlecomp.o singlepanel.o \
- limit.o limitpanel.o mute.o mutedummy.o
-GCF = `pkg-config --cflags gtk+-2.0` -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED
+ limit.o limitpanel.o mute.o mixpanel.o mix.o reverb.o
+GCF = -DETCDIR=\\\"$(ETCDIR)\\\" `pkg-config --cflags gtk+-2.0` -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED
all:
$(MAKE) target CFLAGS="-O3 -ffast-math -fomit-frame-pointer $(GCF) $(ADD_DEF)"
@@ -30,27 +38,44 @@
$(MAKE) target CFLAGS="-g -Wall -W -Wno-unused-parameter -D__NO_MATH_INLINES $(GCF) $(ADD_DEF)"
profile:
- $(MAKE) target CFLAGS="-pg -g -O3 -ffast-math $(GCF) $(ADD_DEF)" LIBS="-lgprof-helper"
+ $(MAKE) target CFLAGS="-pg -g -O3 -ffast-math $(GCF) $(ADD_DEF)" LIBS="-lgprof-helper "
clean:
- rm -f $(OBJ) *.d *.d.* gmon.out
+ rm -f $(OBJ) *.d *.d.* gmon.out postfish
+distclean: clean
+ rm -f postfish-wisdomrc
+
%.d: %.c
- $(CC) -M $(GCF) $< > $@.$$$$; sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; rm -f $@.$$$$
+ $(CC) -M $(CFLAGS) $< > $@.$$$$; sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; rm -f $@.$$$$
-ifneq ($(MAKECMDGOALS),clean)
+postfish-wisdomrc:
+ fftwf-wisdom -v -o postfish-wisdomrc \
+ rif32 rof32 rib32 rob32 \
+ rif64 rof64 rib64 rob64 \
+ rif128 rof128 rib128 rob128 \
+ rif256 rof256 rib256 rob256 \
+ rif512 rof512 rib512 rob512 \
+ rif1024 rof1024 rib1024 rob1024 \
+ rif2048 rof2048 rib2048 rob2048 \
+ rif4096 rof4096 rib4096 rob4096 \
+ rif8192 rof8192 rib8192 rob8192 \
+ rif16384 rof16384 rib16384 rob16384
+
+ifeq ($(MAKECMDGOALS),target)
include $(SRC:.c=.d)
endif
-target: $(OBJ)
+target: $(OBJ) postfish-wisdomrc
./touch-version
- $(LD) $(OBJ) $(CFLAGS) -o postfish $(LIBS) `pkg-config --libs gtk+-2.0` -lpthread -lfftw3f -lm
+ $(LD) $(OBJ) $(CFLAGS) -o postfish $(LIBS) `pkg-config --libs gtk+-2.0` -lpthread -lfftw3f -lm
-install:
+install: target
$(INSTALL) -d -m 0755 $(BINDIR)
$(INSTALL) -m 0755 postfish $(BINDIR)
$(INSTALL) -d -m 0755 $(ETCDIR)
$(INSTALL) -m 0644 postfish-gtkrc $(ETCDIR)
+ $(INSTALL) -m 0644 postfish-wisdomrc $(ETCDIR)
# $(INSTALL) -d -m 0755 $(MANDIR)
# $(INSTALL) -d -m 0755 $(MANDIR)/man1
# $(INSTALL) -m 0644 postfish.1 $(MANDIR)/man1
Modified: trunk/postfish/bessel.c
===================================================================
--- trunk/postfish/bessel.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/bessel.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -302,6 +302,39 @@
}
+void compute_iir_decayonly2(float *x, int n, iir_state *is,
+ iir_filter *decay){
+ double d_c0=decay->c[0];
+ double d_c1=decay->c[1];
+ double d_g=decay->g;
+
+ double x0=is->x[0];
+ double x1=is->x[1];
+ double y0=is->y[0];
+ double y1=is->y[1];
+ int i=0;
+
+ while(i<n){
+ double yd;
+
+ if(y1<y0)y1=y0; // slope fixup
+
+ yd = (x[i]+x0*2.+x1)/d_g + y0*d_c0+y1*d_c1;
+
+ if(x[i]>yd)yd=x[i];
+
+ x1=x0;x0=x[i];
+ y1=y0;x[i]=y0=yd;
+ i++;
+ }
+
+ is->x[0]=x0;
+ is->x[1]=x1;
+ is->y[0]=y0;
+ is->y[1]=y1;
+
+}
+
void compute_iir_freefall3(float *x, int n, iir_state *is,
iir_filter *decay){
double d_c0=decay->c[0];
Modified: trunk/postfish/bessel.h
===================================================================
--- trunk/postfish/bessel.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/bessel.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -33,6 +33,7 @@
float alpha;
float Hz;
float ms;
+ int samples;
} iir_filter;
static inline long impulse_ahead2(float alpha){
@@ -84,6 +85,8 @@
iir_filter *decay);
extern void compute_iir_freefall2(float *x, int n, iir_state *is,
iir_filter *decay);
+extern void compute_iir_decayonly2(float *x, int n, iir_state *is,
+ iir_filter *decay);
extern void compute_iir_freefall3(float *x, int n, iir_state *is,
iir_filter *decay);
extern void compute_iir_freefall4(float *x, int n, iir_state *is,
Modified: trunk/postfish/clippanel.c
===================================================================
--- trunk/postfish/clippanel.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/clippanel.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -116,7 +116,7 @@
GtkWidget **windowbutton,
GtkWidget **activebutton){
int i;
- char *labels[2]={"10%","100%"};
+ char *labels[3]={"","10%","100%"};
float levels[3]={0.,10.,100.};
int block_choices=0;
@@ -151,13 +151,13 @@
for(i=64;i<=input_size*2;i*=2)block_choices++;
{
float levels[9]={0,1,2,3,4,5,6,7,8};
- char *labels[8]={"128","256","512","1024","2048","4096","8192","16384"};
+ char *labels[9]={"","128","256","512","1024","2048","4096","8192","16384"};
GtkWidget *table=gtk_table_new(4,2,0);
GtkWidget *sliderbox=gtk_hbox_new(0,0);
GtkWidget *fastlabel=gtk_label_new("fastest");
GtkWidget *qualitylabel=gtk_label_new("best");
- GtkWidget *slider=multibar_slider_new(block_choices-1,labels,levels,1);
+ GtkWidget *slider=multibar_slider_new(block_choices,labels,levels,1);
GtkWidget *samplelabel=gtk_label_new("window sample width");
GtkWidget *mslabel=gtk_label_new("window time width");
GtkWidget *hzlabel=gtk_label_new("approximate lowest response");
@@ -193,12 +193,12 @@
/* set up convergence config */
{
float levels[7]={20,40,60,80,100,120,140};
- char *labels[6]={"40","60","80","100","120","140"};
+ char *labels[7]={"","40","60","80","100","120","140"};
GtkWidget *table=gtk_table_new(2,2,0);
GtkWidget *sliderbox=gtk_hbox_new(0,0);
GtkWidget *fastlabel=gtk_label_new("fastest");
GtkWidget *qualitylabel=gtk_label_new("best");
- GtkWidget *slider=multibar_slider_new(6,labels,levels,1);
+ GtkWidget *slider=multibar_slider_new(7,labels,levels,1);
GtkWidget *label=gtk_label_new("solution depth");
depth_readout=readout_new("000dB");
@@ -223,12 +223,12 @@
/* set up limit config */
{
float levels[7]={1,5,10,20,40,60,100};
- char *labels[6]={"5","10","20","40","60","100"};
+ char *labels[7]={"","5","10","20","40","60","100"};
GtkWidget *table=gtk_table_new(2,2,0);
GtkWidget *sliderbox=gtk_hbox_new(0,0);
GtkWidget *fastlabel=gtk_label_new("fastest");
GtkWidget *qualitylabel=gtk_label_new("best");
- GtkWidget *slider=multibar_slider_new(6,labels,levels,1);
+ GtkWidget *slider=multibar_slider_new(7,labels,levels,1);
GtkWidget *label=gtk_label_new("hard iteration limit");
limit_readout=readout_new("000%");
@@ -250,7 +250,7 @@
}
for(i=0;i<input_ch;i++){
- char *slabels[8]={".05",".1",".2",".3",".4",
+ char *slabels[9]={"",".05",".1",".2",".3",".4",
".6",".8","1."};
float slevels[9]={.01,.05,.1,.2,.3,.4,.6,
.8,1.};
@@ -258,11 +258,11 @@
char buffer[80];
clipslider *cs=calloc(1,sizeof(*cs));
GtkWidget *label;
- GtkWidget *slider=multibar_new(8,slabels,slevels,1,
+ GtkWidget *slider=multibar_new(9,slabels,slevels,1,
HI_DECAY|ZERO_DAMP);
GtkWidget *readout=readout_new("0.00");
GtkWidget *readoutdB=readout_new("-40dB");
- GtkWidget *bar=multibar_new(2,labels,levels,0,
+ GtkWidget *bar=multibar_new(3,labels,levels,0,
HI_DECAY|ZERO_DAMP);
cs->slider=slider;
Modified: trunk/postfish/compandpanel.c
===================================================================
--- trunk/postfish/compandpanel.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/compandpanel.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -495,19 +495,19 @@
subpanel_generic *panel,
multicompand_settings *ms){
int i;
- char *labels[14]={"130","120","110","100","90","80","70",
+ char *labels[15]={"","130","120","110","100","90","80","70",
"60","50","40","30","20","10","0"};
float levels[15]={-140,-130,-120,-110,-100,-90,-80,-70,-60,-50,-40,
-30,-20,-10,0};
float compand_levels[9]={.1,.25,.5,.6667,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"};
+ char *compand_labels[89]={"","4:1","2:1","1:1.5","1:1","1:1.5","1:2","1:4","1:10"};
float timing_levels[6]={.5,1,10,100,1000,10000};
- char *timing_labels[5]={"1ms","10ms","100ms","1s","10s"};
+ char *timing_labels[6]={"","1ms","10ms","100ms","1s","10s"};
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%"};
+ char *per_labels[9]={"0%","","25%","","50%","","75%","","100%"};
multi_panel_state *ps=calloc(1,sizeof(multi_panel_state));
ps->inactive_updatep=1;
@@ -644,7 +644,7 @@
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);
+ GtkWidget *slider=multibar_slider_new(9,compand_labels,compand_levels,1);
ps->under_compand.r=READOUT(readout);
ps->under_compand.v=&ps->ms->under_ratio;
@@ -667,7 +667,7 @@
GtkWidget *label=gtk_label_new("attack/decay:");
GtkWidget *readout0=readout_new(" 100ms");
GtkWidget *readout1=readout_new(" 100ms");
- GtkWidget *slider=multibar_slider_new(5,timing_labels,timing_levels,2);
+ GtkWidget *slider=multibar_slider_new(6,timing_labels,timing_levels,2);
ps->under_timing.r0=READOUT(readout0);
ps->under_timing.r1=READOUT(readout1);
@@ -693,7 +693,7 @@
GtkWidget *label=gtk_label_new("lookahead:");
GtkWidget *readout=readout_new("100%");
- GtkWidget *slider=multibar_slider_new(8,per_labels,per_levels,1);
+ GtkWidget *slider=multibar_slider_new(9,per_labels,per_levels,1);
ps->under_lookahead.r=READOUT(readout);
ps->under_lookahead.v=&ps->ms->under_lookahead;
@@ -740,7 +740,7 @@
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);
+ GtkWidget *slider=multibar_slider_new(9,compand_labels,compand_levels,1);
ps->over_compand.r=READOUT(readout);
ps->over_compand.v=&ps->ms->over_ratio;
@@ -763,7 +763,7 @@
GtkWidget *label=gtk_label_new("attack/decay:");
GtkWidget *readout0=readout_new(" 100ms");
GtkWidget *readout1=readout_new(" 100ms");
- GtkWidget *slider=multibar_slider_new(5,timing_labels,timing_levels,2);
+ GtkWidget *slider=multibar_slider_new(6,timing_labels,timing_levels,2);
ps->over_timing.r0=READOUT(readout0);
ps->over_timing.r1=READOUT(readout1);
@@ -789,7 +789,7 @@
GtkWidget *label=gtk_label_new("lookahead:");
GtkWidget *readout=readout_new("100%");
- GtkWidget *slider=multibar_slider_new(8,per_labels,per_levels,1);
+ GtkWidget *slider=multibar_slider_new(9,per_labels,per_levels,1);
ps->over_lookahead.r=READOUT(readout);
ps->over_lookahead.v=&ps->ms->over_lookahead;
@@ -832,7 +832,7 @@
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);
+ GtkWidget *slider=multibar_slider_new(9,compand_labels,compand_levels,1);
ps->base_compand.r=READOUT(readout);
ps->base_compand.v=&ps->ms->base_ratio;
@@ -855,7 +855,7 @@
GtkWidget *label=gtk_label_new("attack/decay:");
GtkWidget *readout0=readout_new(" 100ms");
GtkWidget *readout1=readout_new(" 100ms");
- GtkWidget *slider=multibar_slider_new(5,timing_labels,timing_levels,2);
+ GtkWidget *slider=multibar_slider_new(6,timing_labels,timing_levels,2);
ps->base_timing.r0=READOUT(readout0);
ps->base_timing.r1=READOUT(readout1);
@@ -884,7 +884,7 @@
ps->bars[i].readoutu=readout_new(" +0");
ps->bars[i].readouto=readout_new(" +0");
- ps->bars[i].slider=multibar_new(14,labels,levels,2,HI_DECAY|LO_DECAY|LO_ATTACK);
+ ps->bars[i].slider=multibar_new(15,labels,levels,2,HI_DECAY|LO_DECAY|LO_ATTACK);
ps->bars[i].number=i;
ps->bars[i].mp=ps;
ps->bars[i].label=label;
@@ -911,7 +911,7 @@
{
GtkWidget *label=gtk_label_new("average");
- ps->bars[multicomp_freqs_max].slider=multibar_slider_new(14,labels,levels,2);
+ ps->bars[multicomp_freqs_max].slider=multibar_slider_new(15,labels,levels,2);
multibar_callback(MULTIBAR(ps->bars[multicomp_freqs_max].slider),average_change,ps);
@@ -982,15 +982,15 @@
rmsfeed=malloc(sizeof(*rmsfeed)*multicomp_freqs_max);
for(i=0;i<multicomp_freqs_max;i++){
- peakfeed[i]=malloc(sizeof(**peakfeed)*input_ch);
- rmsfeed[i]=malloc(sizeof(**rmsfeed)*input_ch);
+ peakfeed[i]=malloc(sizeof(**peakfeed)*max(input_ch,OUTPUT_CHANNELS));
+ rmsfeed[i]=malloc(sizeof(**rmsfeed)*max(input_ch,OUTPUT_CHANNELS));
}
}
if(pull_multicompand_feedback_master(peakfeed,rmsfeed,&bands)==1)
for(i=0;i<bands;i++)
multibar_set(MULTIBAR(master_panel->bars[i].slider),rmsfeed[i],peakfeed[i],
- input_ch,(displayit && multi_master_set.panel_visible));
+ OUTPUT_CHANNELS,(displayit && multi_master_set.panel_visible));
/* channel panels are a bit different; we want each in its native color */
if(pull_multicompand_feedback_channel(peakfeed,rmsfeed,&bands)==1){
Modified: trunk/postfish/declip.c
===================================================================
--- trunk/postfish/declip.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/declip.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -156,9 +156,7 @@
for(i=0;i<input_ch;i++)
chtrigger[i]=1.;
- out.size=input_size;
out.channels=input_ch;
- out.rate=input_rate;
out.data=malloc(input_ch*sizeof(*out.data));
for(i=0;i<input_ch;i++)
out.data[i]=malloc(input_size*sizeof(**out.data));
@@ -363,7 +361,7 @@
memcpy(lap[i],work+blocksize,sizeof(*work)*blocksize/2);
/* now iterate the pieces purely within in */
- for(j=0;j+blocksize<=in->size;j+=blocksize/2){
+ for(j=0;j+blocksize<=input_size;j+=blocksize/2){
memset(work,0,sizeof(*work)*blocksize);
memcpy(work+blocksize/2,in->data[i]+j,sizeof(*work)*blocksize);
memset(work+blocksize+blocksize/2,0,sizeof(*work)*blocksize/2);
@@ -394,10 +392,10 @@
cache_active=in->active;
fillstate=1;
out.samples=0;
- if(in->samples==in->size)break;
+ if(in->samples==input_size)break;
for(i=0;i<input_ch;i++)
- memset(in->data[i],0,sizeof(**in->data)*in->size);
+ memset(in->data[i],0,sizeof(**in->data)*input_size);
in->samples=0;
/* fall through */
@@ -589,7 +587,7 @@
/* declip */
if(declip_prev_active[i]){
- for(j=0;j+blocksize<=in->size;j+=blocksize/2){
+ for(j=0;j+blocksize<=input_size;j+=blocksize/2){
memset(work,0,sizeof(*work)*blocksize);
memcpy(work+blocksize/2,cache[i]+j,sizeof(*work)*blocksize);
memset(work+blocksize+blocksize/2,0,sizeof(*work)*blocksize/2);
@@ -607,7 +605,7 @@
}
}
}
- if(out.samples<out.size)fillstate=2;
+ if(out.samples<input_size)fillstate=2;
break;
case 2: /* we've pushed out EOF already */
out.samples=0;
@@ -622,7 +620,7 @@
comes in */
{
- int tozero=out.size-out.samples;
+ int tozero=input_size-out.samples;
if(tozero)
for(i=0;i<out.channels;i++)
memset(out.data[i]+out.samples,0,sizeof(**out.data)*tozero);
Modified: trunk/postfish/eq.c
===================================================================
--- trunk/postfish/eq.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/eq.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -32,6 +32,7 @@
typedef struct{
freq_state eq;
+ int ch;
} eq_state;
@@ -42,7 +43,6 @@
static eq_state master_state;
static eq_state channel_state;
-
/* accessed only in playback thread/setup */
int pull_eq_feedback_master(float **peak,float **rms){
return pull_freq_feedback(&master_state.eq,peak,rms);
@@ -53,15 +53,17 @@
}
/* called only by initial setup */
-int eq_load(void){
+int eq_load(int outch){
int i;
eq_channel_set=calloc(input_ch,sizeof(*eq_channel_set));
freq_class_load(&fc,eq_freq_list,eq_freqs);
- freq_load(&master_state.eq,&fc);
- freq_load(&channel_state.eq,&fc);
+ freq_load(&master_state.eq,&fc,outch);
+ master_state.ch=outch;
+ freq_load(&channel_state.eq,&fc,input_ch);
+ channel_state.ch=input_ch;
eq_master_set.curve_dirty=1;
@@ -118,11 +120,12 @@
/* called only by playback thread */
time_linkage *eq_read_master(time_linkage *in){
- int active[input_ch];
- int visible[input_ch];
+ eq_state *eq=&master_state;
+ int active[eq->ch];
+ int visible[eq->ch];
int i;
- for(i=0;i<input_ch;i++){
+ for(i=0;i<eq->ch;i++){
active[i]=eq_master_set.panel_active;
visible[i]=eq_master_set.panel_visible;
}
@@ -131,11 +134,12 @@
}
time_linkage *eq_read_channel(time_linkage *in){
- int active[input_ch];
- int visible[input_ch];
+ eq_state *eq=&channel_state;
+ int active[eq->ch];
+ int visible[eq->ch];
int i;
- for(i=0;i<input_ch;i++){
+ for(i=0;i<eq->ch;i++){
active[i]=eq_channel_set[i].panel_active;
visible[i]=eq_channel_set[i].panel_visible;
}
Modified: trunk/postfish/eq.h
===================================================================
--- trunk/postfish/eq.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/eq.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -51,7 +51,7 @@
extern int pull_eq_feedback_master(float **peak,float **rms);
extern int pull_eq_feedback_channel(float **peak,float **rms);
-extern int eq_load(void);
+extern int eq_load(int ch);
extern int eq_reset();
extern void eq_set(eq_settings *eq,int freq, float value);
extern time_linkage *eq_read_master(time_linkage *in);
Modified: trunk/postfish/eqpanel.c
===================================================================
--- trunk/postfish/eqpanel.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/eqpanel.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -66,7 +66,7 @@
eq_settings *es){
int i;
- char *labels[15]={"110","100","90","80","70","60","50","40",
+ char *labels[16]={"","110","100","90","80","70","60","50","40",
"30","20","10","0","+10","+20","+30"};
float levels[16]={-120,-110,-100,-90,-80,-70,-60,-50,-40,
-30,-20,-10,0,10,20,30};
@@ -81,7 +81,7 @@
gtk_widget_set_name(label,"smallmarker");
bars[i].readout=readout_new("+00dB");
- bars[i].slider=multibar_new(15,labels,levels,1,
+ bars[i].slider=multibar_new(16,labels,levels,1,
LO_DECAY|HI_DECAY|LO_ATTACK|HI_ATTACK);
bars[i].number=i;
bars[i].s=es;
@@ -125,7 +125,7 @@
GtkWidget **windowbutton,
GtkWidget **activebutton){
int i;
- c_bars=malloc(input_ch*sizeof(*m_bars));
+ c_bars=malloc(input_ch*sizeof(*c_bars));
/* a panel for each channel */
for(i=0;i<input_ch;i++){
@@ -154,15 +154,15 @@
rmsfeed=malloc(sizeof(*rmsfeed)*eq_freqs);
for(i=0;i<eq_freqs;i++){
- peakfeed[i]=malloc(sizeof(**peakfeed)*input_ch);
- rmsfeed[i]=malloc(sizeof(**rmsfeed)*input_ch);
+ peakfeed[i]=malloc(sizeof(**peakfeed)*max(input_ch,OUTPUT_CHANNELS));
+ rmsfeed[i]=malloc(sizeof(**rmsfeed)*max(input_ch,OUTPUT_CHANNELS));
}
}
if(pull_eq_feedback_master(peakfeed,rmsfeed)==1)
for(i=0;i<eq_freqs;i++)
multibar_set(MULTIBAR(m_bars[i].slider),rmsfeed[i],peakfeed[i],
- input_ch,(displayit && eq_master_set.panel_visible));
+ OUTPUT_CHANNELS,(displayit && eq_master_set.panel_visible));
if(pull_eq_feedback_channel(peakfeed,rmsfeed)==1){
Modified: trunk/postfish/freq.c
===================================================================
--- trunk/postfish/freq.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/freq.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -29,7 +29,6 @@
#include "lpc.h"
extern int input_rate;
-extern int input_ch;
extern int input_size;
/* feedback! */
@@ -49,7 +48,7 @@
int pull_freq_feedback(freq_state *ff,float **peak,float **rms){
freq_feedback *f=(freq_feedback *)feedback_pull(&ff->feedpool);
- int i;
+ int i,ch=ff->out.channels;
if(!f)return 0;
@@ -59,10 +58,10 @@
}else{
if(peak)
for(i=0;i<ff->fc->bands;i++)
- memcpy(peak[i],f->peak[i],sizeof(**peak)*input_ch);
+ memcpy(peak[i],f->peak[i],sizeof(**peak)*ch);
if(rms)
for(i=0;i<ff->fc->bands;i++)
- memcpy(rms[i],f->rms[i],sizeof(**rms)*input_ch);
+ memcpy(rms[i],f->rms[i],sizeof(**rms)*ch);
feedback_old(&ff->feedpool,(feedback_generic *)f);
return 1;
}
@@ -101,91 +100,101 @@
/* I'm too lazy to figure out the integral symbolically, use this
fancy CPU thingy for something */
+ f->ho_area=calloc(bands,sizeof(*f->ho_area));
f->ho_window=malloc(bands*sizeof(*f->ho_window));
- f->ho_area=calloc(bands,sizeof(*f->ho_area));
- {
- float working[f->qblocksize*4+2];
-
+ for(i=0;i<bands;i++)
+ f->ho_window[i]=calloc((f->qblocksize*2+1),sizeof(**f->ho_window));
+
+ /* first, build the first-pass desired, supersampled response */
+ for(j=0;j<(((f->qblocksize*2+1)/10)<<5);j++){
+ float localf= .5*j*input_rate/(f->qblocksize<<6);
+ int localbin= j>>5;
+
for(i=0;i<bands;i++){
float lastf=(i>0?frequencies[i-1]:0);
float thisf=frequencies[i];
float nextf=frequencies[i+1];
- memset(working,0,sizeof(working));
- for(j=0;j<((f->qblocksize*2+1)<<5);j++){
- float localf= .5*j*input_rate/(f->qblocksize<<6);
- int localbin= j>>5;
- float localwin;
+ if(localf>=lastf && localf<nextf){
+ float localwin=1.;
+ if(localf<thisf){
+ if(i!=0)localwin= sin((localf-lastf)/(thisf-lastf)*M_PIl*.5);
+ }else{
+ if(i+1!=bands)localwin= sin((nextf-localf)/(nextf-thisf)*M_PIl*.5);
+ }
- if(localf>=lastf && localf<thisf){
- if(i==0)
- localwin=1.;
- else
- localwin= sin((localf-lastf)/(thisf-lastf)*M_PIl*.5);
- localwin*=localwin;
- working[localbin]+=localwin*(1./32);
-
- }else if(localf>=thisf && localf<nextf){
- if(i+1==bands)
- localwin=1.;
- else
- localwin= sin((nextf-localf)/(nextf-thisf)*M_PIl*.5);
-
- localwin*=localwin;
- working[localbin]+=localwin*(1./32);
-
- }
+ localwin*=localwin;
+ f->ho_window[i][localbin]+=localwin*(1./32);
}
+ }
+ }
+ j>>=5;
+ for(;j<f->qblocksize*2+1;j++){
+ float localf= .5*j*input_rate/(f->qblocksize<<1);
- /* window this desired response in the time domain so that our
- convolution is properly padded against being circular */
- memset(f->fftwf_buffer,0,sizeof(*f->fftwf_buffer)*
- (f->qblocksize*4+2));
- for(j=0;j<f->qblocksize*2;j++)
- f->fftwf_buffer[j*2]=working[j];
-
- fftwf_execute(f->fftwf_backward);
+ for(i=0;i<bands;i++){
+ float lastf=(i>0?frequencies[i-1]:0);
+ float thisf=frequencies[i];
+ float nextf=frequencies[i+1];
- /* window response in time */
- for(j=0;j<f->qblocksize;j++){
- float val=cos(j*M_PI/(f->qblocksize*2));
- val=sin(val*val*M_PIl*.5);
- f->fftwf_buffer[j]*= sin(val*val*M_PIl*.5);
- }
+ if(localf>=lastf && localf<nextf){
+ float localwin=1.;
+ if(localf<thisf){
+ if(i!=0)localwin= sin((localf-lastf)/(thisf-lastf)*M_PIl*.5);
+ }else{
+ if(i+1!=bands)localwin= sin((nextf-localf)/(nextf-thisf)*M_PIl*.5);
+ }
- for(;j<f->qblocksize*3;j++)
- f->fftwf_buffer[j]=0.;
-
- for(;j<f->qblocksize*4;j++){
- float val=sin((j-f->qblocksize*3)*M_PI/(f->qblocksize*2));
- val=sin(val*val*M_PIl*.5);
- f->fftwf_buffer[j]*=sin(val*val*M_PIl*.5);
+ f->ho_window[i][j]+=localwin*localwin;
}
+ }
+ }
- /* back to frequency; this is all-real data still */
- fftwf_execute(f->fftwf_forward);
- for(j=0;j<f->qblocksize*4+2;j++)
- f->fftwf_buffer[j]/=f->qblocksize*4;
-
- /* now take what we learned and distill it a bit */
- f->ho_window[i]=calloc((f->qblocksize*2+1),sizeof(**f->ho_window));
- for(j=0;j<f->qblocksize*2+1;j++){
- f->ho_window[i][j]=f->fftwf_buffer[j*2];
- f->ho_area[i]+=fabs(f->ho_window[i][j]);
- }
- f->ho_area[i]=1./f->ho_area[i];
-
- lastf=thisf;
-
+ for(i=0;i<bands;i++){
+
+ /* window each desired response in the time domain so that our
+ convolution is properly padded against being circular */
+ memset(f->fftwf_buffer,0,sizeof(*f->fftwf_buffer)*
+ (f->qblocksize*4+2));
+ for(j=0;j<f->qblocksize*2;j++)
+ f->fftwf_buffer[j*2]=f->ho_window[i][j];
+
+ fftwf_execute(f->fftwf_backward);
+
+ /* window response in time */
+ for(j=0;j<f->qblocksize;j++){
+ float val=cos(j*M_PI/(f->qblocksize*2));
+ val=sin(val*val*M_PIl*.5);
+ f->fftwf_buffer[j]*= sin(val*val*M_PIl*.5);
}
+
+ for(;j<f->qblocksize*3;j++)
+ f->fftwf_buffer[j]=0.;
+
+ for(;j<f->qblocksize*4;j++){
+ float val=sin((j-f->qblocksize*3)*M_PI/(f->qblocksize*2));
+ val=sin(val*val*M_PIl*.5);
+ f->fftwf_buffer[j]*=sin(val*val*M_PIl*.5);
+ }
+
+ /* back to frequency; this is all-real data still */
+ fftwf_execute(f->fftwf_forward);
+ for(j=0;j<f->qblocksize*4+2;j++)
+ f->fftwf_buffer[j]/=f->qblocksize*4;
+
+ /* now take what we learned and distill it a bit */
+ for(j=0;j<f->qblocksize*2+1;j++){
+ f->ho_window[i][j]=f->fftwf_buffer[j*2];
+ f->ho_area[i]+=fabs(f->ho_window[i][j]);
+ }
+ f->ho_area[i]=1./f->ho_area[i];
}
-
+
return 0;
-
}
/* called only by initial setup */
-int freq_load(freq_state *f,freq_class_setup *fc){
+int freq_load(freq_state *f,freq_class_setup *fc,int ch){
int i;
memset(f,0,sizeof(*f));
@@ -193,22 +202,22 @@
f->fillstate=0;
f->cache_samples=0;
- f->cache1=malloc(input_ch*sizeof(*f->cache1));
- f->cache0=malloc(input_ch*sizeof(*f->cache0));
- for(i=0;i<input_ch;i++){
+ f->cache1=malloc(ch*sizeof(*f->cache1));
+ f->cache0=malloc(ch*sizeof(*f->cache0));
+ for(i=0;i<ch;i++){
f->cache1[i]=calloc(input_size,sizeof(**f->cache1));
f->cache0[i]=calloc(input_size,sizeof(**f->cache0));
}
- f->activeP=malloc(input_ch*sizeof(*f->activeP));
- f->active1=malloc(input_ch*sizeof(*f->active1));
- f->active0=malloc(input_ch*sizeof(*f->active0));
+ f->activeP=malloc(ch*sizeof(*f->activeP));
+ f->active1=malloc(ch*sizeof(*f->active1));
+ f->active0=malloc(ch*sizeof(*f->active0));
- f->lap1=malloc(input_ch*sizeof(*f->lap1));
- f->lap0=malloc(input_ch*sizeof(*f->lap0));
- f->lapC=malloc(input_ch*sizeof(*f->lapC));
- for(i=0;i<input_ch;i++){
+ f->lap1=malloc(ch*sizeof(*f->lap1));
+ f->lap0=malloc(ch*sizeof(*f->lap0));
+ f->lapC=malloc(ch*sizeof(*f->lapC));
+ for(i=0;i<ch;i++){
f->lap1[i]=calloc(fc->qblocksize,sizeof(**f->lap1));
f->lap0[i]=calloc(fc->qblocksize,sizeof(**f->lap0));
f->lapC[i]=calloc(fc->qblocksize,sizeof(**f->lapC));
@@ -217,15 +226,13 @@
f->peak=malloc(fc->bands*sizeof(*f->peak));
f->rms=malloc(fc->bands*sizeof(*f->rms));
for(i=0;i<fc->bands;i++){
- f->peak[i]=malloc(input_ch*sizeof(**f->peak));
- f->rms[i]=malloc(input_ch*sizeof(**f->rms));
+ f->peak[i]=malloc(ch*sizeof(**f->peak));
+ f->rms[i]=malloc(ch*sizeof(**f->rms));
}
- f->out.size=input_size;
- f->out.channels=input_ch;
- f->out.rate=input_rate;
- f->out.data=malloc(input_ch*sizeof(*f->out.data));
- for(i=0;i<input_ch;i++)
+ f->out.channels=ch;
+ f->out.data=malloc(ch*sizeof(*f->out.data));
+ for(i=0;i<ch;i++)
f->out.data[i]=malloc(input_size*sizeof(**f->out.data));
return(0);
@@ -298,12 +305,12 @@
int *active,
void (*func)(float *,int)){
- int i,j;
+ int i,j,ch=f->out.channels;
int have_feedback=0;
f->cache_samples+=in->samples;
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ch;i++){
int mutedC=mute_channel_muted(in->active,i);
int muted0=mute_channel_muted(f->mutemask0,i);
@@ -333,14 +340,14 @@
f->cache0[i],input_size);
}
- if(in->samples<in->size){
+ if(in->samples<input_size){
if(mutedC)memset(in->data[i],0,sizeof(**in->data)*input_size);
if(muted0)memset(f->cache0[i],0,sizeof(**f->cache0)*input_size);
postextrapolate_helper(f->cache0[i],input_size,
in->data[i],in->samples,
in->data[i]+in->samples,
- in->size-in->samples);
+ input_size-in->samples);
}
fill_freq_buffer_helper(fc->fftwf_buffer,
@@ -448,17 +455,17 @@
if(!ff->peak){
ff->peak=calloc(fc->bands,sizeof(*ff->peak));
for(i=0;i<fc->bands;i++)
- ff->peak[i]=malloc(input_ch*sizeof(**ff->peak));
+ ff->peak[i]=malloc(ch*sizeof(**ff->peak));
}
if(!ff->rms){
ff->rms=calloc(fc->bands,sizeof(*ff->rms));
for(i=0;i<fc->bands;i++)
- ff->rms[i]=malloc(input_ch*sizeof(**ff->rms));
+ ff->rms[i]=malloc(ch*sizeof(**ff->rms));
}
for(i=0;i<fc->bands;i++){
- memcpy(ff->peak[i],f->peak[i],input_ch*sizeof(**f->peak));
- memcpy(ff->rms[i],f->rms[i],input_ch*sizeof(**f->rms));
+ memcpy(ff->peak[i],f->peak[i],ch*sizeof(**f->peak));
+ memcpy(ff->rms[i],f->rms[i],ch*sizeof(**f->rms));
}
ff->bypass=0;
feedback_push(&f->feedpool,(feedback_generic *)ff);
@@ -485,7 +492,7 @@
time_linkage *freq_read(time_linkage *in, freq_state *f,
int *visible, int *active,
void (*func)(float *,int i)){
- int i;
+ int i,ch=f->out.channels;
freq_class_setup *fc=f->fc;
switch(f->fillstate){
@@ -496,7 +503,7 @@
}
/* zero out lapping and cache state */
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ch;i++){
memset(f->lap1[i],0,sizeof(**f->lap1)*fc->qblocksize);
memset(f->lap0[i],0,sizeof(**f->lap0)*fc->qblocksize);
memset(f->cache0[i],0,sizeof(**f->cache0)*input_size);
@@ -513,10 +520,10 @@
f->fillstate=1;
f->out.samples=0;
- if(in->samples==in->size)goto tidy_up;
+ if(in->samples==input_size)goto tidy_up;
- for(i=0;i<input_ch;i++)
- memset(in->data[i],0,sizeof(**in->data)*in->size);
+ for(i=0;i<ch;i++)
+ memset(in->data[i],0,sizeof(**in->data)*input_size);
in->samples=0;
/* fall through */
@@ -526,10 +533,10 @@
f->fillstate=2;
f->out.samples=0;
- if(in->samples==in->size)goto tidy_up;
+ if(in->samples==input_size)goto tidy_up;
- for(i=0;i<input_ch;i++)
- memset(in->data[i],0,sizeof(**in->data)*in->size);
+ for(i=0;i<ch;i++)
+ memset(in->data[i],0,sizeof(**in->data)*input_size);
in->samples=0;
/* fall through */
@@ -537,7 +544,7 @@
freq_work(fc,f,in,&f->out,visible,active,func);
- if(f->out.samples<f->out.size)f->fillstate=3;
+ if(f->out.samples<input_size)f->fillstate=3;
break;
case 3: /* we've pushed out EOF already */
f->out.samples=0;
@@ -545,7 +552,7 @@
tidy_up:
{
- int tozero=f->out.size-f->out.samples;
+ int tozero=input_size-f->out.samples;
if(tozero)
for(i=0;i<f->out.channels;i++)
memset(f->out.data[i]+f->out.samples,0,sizeof(**f->out.data)*tozero);
Modified: trunk/postfish/freq.h
===================================================================
--- trunk/postfish/freq.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/freq.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -71,7 +71,7 @@
extern int pull_freq_feedback(freq_state *ff,float **peak,float **rms);
extern int freq_class_load(freq_class_setup *f,const float *frequencies, int bands);
-extern int freq_load(freq_state *f,freq_class_setup *fc);
+extern int freq_load(freq_state *f,freq_class_setup *fc,int ch);
extern int freq_reset(freq_state *f);
extern time_linkage *freq_read(time_linkage *in,
Modified: trunk/postfish/input.c
===================================================================
--- trunk/postfish/input.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/input.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -327,23 +327,23 @@
4000: 256 */
if(rate<6000){
- input_size=out.size=256;
+ input_size=256;
}else if(rate<15000){
- input_size=out.size=512;
+ input_size=512;
}else if(rate<25000){
- input_size=out.size=1024;
+ input_size=1024;
}else if(rate<50000){
- input_size=out.size=2048;
+ input_size=2048;
}else if(rate<100000){
- input_size=out.size=4096;
+ input_size=4096;
}else
- input_size=out.size=8192;
+ input_size=8192;
input_ch=out.channels=ch;
- input_rate=out.rate=rate;
+ input_rate=rate;
out.data=malloc(sizeof(*out.data)*ch);
for(i=0;i<ch;i++)
- out.data[i]=malloc(sizeof(*out.data[0])*out.size);
+ out.data[i]=malloc(sizeof(*out.data[0])*input_size);
return 0;
}
@@ -423,7 +423,7 @@
time_linkage *input_read(void){
int read_b=0,i,j,k;
- int toread_b=out.size*out.channels*inbytes;
+ int toread_b=input_size*out.channels*inbytes;
unsigned char *readbuf;
float *rms=alloca(sizeof(*rms)*(out.channels+2));
float *peak=alloca(sizeof(*peak)*(out.channels+2));
@@ -551,7 +551,7 @@
tidy_up:
{
- int tozero=out.size-out.samples;
+ int tozero=input_size-out.samples;
if(tozero)
for(j=0;j<out.channels;j++)
memset(out.data[j]+out.samples,0,sizeof(**out.data)*tozero);
Modified: trunk/postfish/limit.c
===================================================================
--- trunk/postfish/limit.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/limit.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -28,7 +28,6 @@
extern int input_size;
extern int input_rate;
-extern int input_ch;
sig_atomic_t limit_active;
sig_atomic_t limit_visible;
@@ -67,24 +66,22 @@
if(!f)return 0;
if(peak)
- memcpy(peak,f->peak,sizeof(*peak)*input_ch);
+ memcpy(peak,f->peak,sizeof(*peak)*limitstate.out.channels);
if(att)
- memcpy(att,f->att,sizeof(*att)*input_ch);
+ memcpy(att,f->att,sizeof(*att)*limitstate.out.channels);
feedback_old(&limitstate.feedpool,(feedback_generic *)f);
return 1;
}
/* called only by initial setup */
-int limit_load(void){
+int limit_load(int ch){
int i;
memset(&limitstate,0,sizeof(limitstate));
- limitstate.iir=calloc(input_ch,sizeof(*limitstate.iir));
- limitstate.out.size=input_size;
- limitstate.out.channels=input_ch;
- limitstate.out.rate=input_rate;
- limitstate.out.data=malloc(input_ch*sizeof(*limitstate.out.data));
- for(i=0;i<input_ch;i++)
+ limitstate.iir=calloc(ch,sizeof(*limitstate.iir));
+ limitstate.out.channels=ch;
+ limitstate.out.data=malloc(ch*sizeof(*limitstate.out.data));
+ for(i=0;i<ch;i++)
limitstate.out.data[i]=malloc(input_size*sizeof(**limitstate.out.data));
window=malloc(input_size*sizeof(*window));
@@ -109,10 +106,10 @@
}
/* called only in playback thread */
-int limit_reset(void ){
+int limit_reset(void){
/* reset cached pipe state */
while(pull_limit_feedback(NULL,NULL));
- memset(limitstate.iir,0,input_ch*sizeof(&limitstate.iir));
+ memset(limitstate.iir,0,limitstate.out.channels*sizeof(&limitstate.iir));
limitstate.initted=0;
return 0;
}
@@ -123,8 +120,9 @@
time_linkage *limit_read(time_linkage *in){
- float peakfeed[input_ch];
- float attfeed[input_ch];
+ int ch=limitstate.out.channels;
+ float peakfeed[ch];
+ float attfeed[ch];
int activeC=limit_active;
int activeP=limitstate.prev_active;
@@ -154,7 +152,7 @@
depth=depth*.2;
depth*=depth;
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ch;i++){
localpeak=0.;
localatt=0.;
@@ -176,10 +174,9 @@
x[k]=att;
}
+ compute_iir_decayonly2(x,input_size,limitstate.iir+i,&limitstate.decay);
- compute_iir_freefall2(x,input_size,limitstate.iir+i,&limitstate.decay);
-
for(k=0;k<in->samples;k++)
x[k]=inx[k]*fromdB(-x[k]);
@@ -225,10 +222,10 @@
(limit_feedback *)feedback_new(&limitstate.feedpool,new_limit_feedback);
if(!ff->peak)
- ff->peak=malloc(input_ch*sizeof(*ff->peak));
+ ff->peak=malloc(ch*sizeof(*ff->peak));
if(!ff->att)
- ff->att=malloc(input_ch*sizeof(*ff->att));
+ ff->att=malloc(ch*sizeof(*ff->att));
memcpy(ff->peak,peakfeed,sizeof(peakfeed));
memcpy(ff->att,attfeed,sizeof(attfeed));
@@ -237,7 +234,7 @@
}
{
- int tozero=limitstate.out.size-limitstate.out.samples;
+ int tozero=input_size-limitstate.out.samples;
if(tozero)
for(i=0;i<limitstate.out.channels;i++)
memset(limitstate.out.data[i]+limitstate.out.samples,0,sizeof(**limitstate.out.data)*tozero);
Modified: trunk/postfish/limit.h
===================================================================
--- trunk/postfish/limit.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/limit.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -28,6 +28,6 @@
} limit_settings;
extern int pull_limit_feedback(float *peak,float *att);
-extern int limit_load(void);
+extern int limit_load(int ch);
extern int limit_reset(void);
extern time_linkage *limit_read(time_linkage *in);
Modified: trunk/postfish/limitpanel.c
===================================================================
--- trunk/postfish/limitpanel.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/limitpanel.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -34,7 +34,6 @@
extern sig_atomic_t limit_active;
extern sig_atomic_t limit_visible;
-extern int input_ch;
extern int input_size;
extern int input_rate;
@@ -93,17 +92,17 @@
GtkWidget *activebutton){
- char *labels[8]={"-80","-60","-40","-20","-10","-6","-3","+0"};
+ char *labels[9]={"","-80","-60","-40","-20","-10","-6","-3","+0"};
float levels[9]={-80,-60,-50,-40,-30,-10,-6,-3,0};
- char *labels2[4]={"-20","-10","-3","0"};
+ char *labels2[5]={"","-20","-10","-3","0"};
float levels2[5]={-30,-20,-10,-3,0};
- char *rlabels[3]={"6"," 20","40"};
+ char *rlabels[4]={"","6"," 20","40"};
float rlevels[4]={0,3,10,20};
float timing_levels[6]={.1,1,10,100,1000,10000};
- char *timing_labels[5]={"1ms","10ms","100ms","1s","10s"};
+ char *timing_labels[6]={"","1ms","10ms","100ms","1s","10s"};
char *shortcut[]={" l "};
@@ -124,11 +123,11 @@
GtkWidget *readout2=readout_new("+XXXXdB");
GtkWidget *readout3=readout_new("+XXXXms");
- GtkWidget *slider2=multibar_slider_new(4,labels2,levels2,1);
- GtkWidget *slider3=multibar_slider_new(5,timing_labels,timing_levels,1);
+ GtkWidget *slider2=multibar_slider_new(5,labels2,levels2,1);
+ GtkWidget *slider3=multibar_slider_new(6,timing_labels,timing_levels,1);
- t_slider=multibar_new(8,labels,levels,1,HI_DECAY);
- a_slider=multibar_new(3,rlabels,rlevels,0,0);
+ t_slider=multibar_new(9,labels,levels,1,HI_DECAY);
+ a_slider=multibar_new(4,rlabels,rlevels,0,0);
gtk_misc_set_alignment(GTK_MISC(label1),1,.5);
gtk_misc_set_alignment(GTK_MISC(label2),1,.5);
@@ -170,17 +169,17 @@
void limitpanel_feedback(int displayit){
if(!peakfeed){
int i;
- peakfeed=malloc(sizeof(*peakfeed)*input_ch);
- attfeed=malloc(sizeof(*attfeed)*input_ch);
- zerofeed=malloc(sizeof(*zerofeed)*input_ch);
- for(i=0;i<input_ch;i++)zerofeed[i]=-150.;
+ peakfeed=malloc(sizeof(*peakfeed)*OUTPUT_CHANNELS);
+ attfeed=malloc(sizeof(*attfeed)*OUTPUT_CHANNELS);
+ zerofeed=malloc(sizeof(*zerofeed)*OUTPUT_CHANNELS);
+ for(i=0;i<OUTPUT_CHANNELS;i++)zerofeed[i]=-150.;
}
if(pull_limit_feedback(peakfeed,attfeed)==1){
multibar_set(MULTIBAR(t_slider),zerofeed,peakfeed,
- input_ch,(displayit && limit_visible));
+ OUTPUT_CHANNELS,(displayit && limit_visible));
multibar_set(MULTIBAR(a_slider),zerofeed,attfeed,
- input_ch,(displayit && limit_visible));
+ OUTPUT_CHANNELS,(displayit && limit_visible));
}
}
Modified: trunk/postfish/main.c
===================================================================
--- trunk/postfish/main.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/main.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -28,6 +28,7 @@
/* sound playback code is OSS-specific for now */
#include "postfish.h"
+#include <fenv.h> // Thank you C99!
#include <fftw3.h>
#include "input.h"
#include "output.h"
@@ -38,25 +39,116 @@
#include "singlecomp.h"
#include "limit.h"
#include "mute.h"
+#include "mix.h"
pthread_mutex_t master_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
int outfileno=-1;
int eventpipe[2];
+int look_for_wisdom(char *filename){
+ int ret;
+ FILE *f=fopen(filename,"r");
+ if(!f)return 0;
+ ret=fftwf_import_wisdom_from_file(f);
+ fclose(f);
+
+ if(ret)
+ fprintf(stderr,"Found valid postfish-wisdomrc file at %s\n",filename);
+ else
+ fprintf(stderr,"WARNING: corrupt, invalid or obsolete postfish-wisdomrc file at %s\n",filename);
+ return(ret);
+}
+
int main(int argc, char **argv){
int configfd=-1;
+ int wisdom=0;
+ /* We do not care about FPEs; rather, underflow is nominal case, and
+ its better to ignore other traps in production than to crash the
+ app. Please inform the FPU of this. */
+ fedisableexcept(FE_INEXACT);
+ fedisableexcept(FE_UNDERFLOW);
+ fedisableexcept(FE_OVERFLOW);
+
+ /* Linux Altivec support has a very annoying problem; by default,
+ math on denormalized floats will simply crash the program. FFTW3
+ uses Altivec, so boom.
+
+ By the C99 spec, the above exception configuration is also
+ supposed to handle Altivec config, but doesn't. So we use the
+ below ugliness. */
+
+#ifdef __PPC
+#include <altivec.h>
+#if (defined __GNUC__) && (__GNUC__ == 3) && ! (defined __APPLE_CC__)
+ __vector unsigned short noTrap =
+ (__vector unsigned short){0,0,0,0,0,0,0x1,0};
+#else
+ vector unsigned short noTrap =
+ (vector unsigned short)(0,0,0,0,0,0,0x1,0);
+#endif
+
+ vec_mtvscr(noTrap);
+#endif
+
+ /* check for fftw wisdom file in order:
+ ./postfish-wisdomrc
+ $(POSTFISHDIR)/postfish-wisdomrc
+ ~/.postfish/postfish-wisdomrc
+ ETCDIR/postfish-wisdomrc
+ system wisdom */
+
+
+ wisdom=look_for_wisdom("./postfish-wisdomrc");
+ if(!wisdom){
+ char *rcdir=getenv("POSTFISH_RCDIR");
+ if(rcdir){
+ char *rcfile="/postfish-wisdomrc";
+ char *homerc=calloc(1,strlen(rcdir)+strlen(rcfile)+1);
+ strcat(homerc,rcdir);
+ strcat(homerc,rcfile);
+ wisdom=look_for_wisdom(homerc);
+ }
+ }
+ if(!wisdom){
+ char *rcdir=getenv("HOME");
+ if(rcdir){
+ char *rcfile="/.postfish/postfish-wisdomrc";
+ char *homerc=calloc(1,strlen(rcdir)+strlen(rcfile)+1);
+ strcat(homerc,rcdir);
+ strcat(homerc,rcfile);
+ wisdom=look_for_wisdom(homerc);
+ }
+ }
+ if(!wisdom)wisdom=look_for_wisdom(ETCDIR"/postfish-wisdomrc");
+ if(!wisdom){
+ fftwf_import_system_wisdom();
+
+ fprintf(stderr,"Postfish could not find the postfish-wisdom configuration file normally built\n"
+ "or installed with Postfish and located in one of the following places:\n"
+
+ "\t./postfish-wisdomrc\n"
+ "\t$(POSTFISHDIR)/postfish-wisdomrc\n"
+ "\t~/.postfish/postfish-wisdomrc\n\t"
+ ETCDIR"/postfish-wisdomrc\n"
+ "This configuration file is used to reduce the startup time Postfish uses to \n"
+ "pre-calculate Fourier transform tables for the FFTW3 library. Postfish will start\n"
+ "and operate normally, but it will take additional time before popping the main\n"
+ "window because this information must be regenerated each time Postfish runs.\n");
+ }
+
/* parse command line and open all the input files */
if(input_load(argc-1,argv+1))exit(1);
/* set up filter chains */
if(declip_load())exit(1);
- if(eq_load())exit(1);
+ if(eq_load(OUTPUT_CHANNELS))exit(1);
if(suppress_load())exit(1);
- if(multicompand_load())exit(1);
- if(singlecomp_load())exit(1);
- if(limit_load())exit(1);
+ if(multicompand_load(OUTPUT_CHANNELS))exit(1);
+ if(singlecomp_load(OUTPUT_CHANNELS))exit(1);
+ if(limit_load(OUTPUT_CHANNELS))exit(1);
if(mute_load())exit(1);
+ if(mix_load(OUTPUT_CHANNELS))exit(1);
/* look at stdout... do we have a file or device? */
if(!isatty(STDOUT_FILENO)){
Modified: trunk/postfish/mainpanel.c
===================================================================
--- trunk/postfish/mainpanel.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/mainpanel.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -57,6 +57,7 @@
compandpanel_reset();
singlepanel_reset();
limitpanel_reset();
+ mixpanel_reset();
meterhold_reset(p);
}
@@ -75,6 +76,7 @@
compandpanel_reset();
singlepanel_reset();
limitpanel_reset();
+ mixpanel_reset();
meterhold_reset(p);
}
@@ -452,14 +454,15 @@
GtkWidget *table,
char *label,
int i,
- int masterwinp,
- int channelwinp,
- void (*panel_create)
+ void (*single_create)
(postfish_mainpanel *,
+ GtkWidget **, GtkWidget **),
+ void (*multi_create)
+ (postfish_mainpanel *,
GtkWidget **, GtkWidget **)){
int j;
- GtkWidget *wm[input_ch];
+ GtkWidget *wm[input_ch+1];
GtkWidget *wa[input_ch];
for(j=0;j<input_ch;j++){
@@ -467,7 +470,7 @@
sprintf(buffer," %d ",j+1);
p->channel_wa[i][j]=wa[j]=gtk_toggle_button_new_with_label(buffer);
- if(channelwinp){
+ if(multi_create){
/* a panel button per channel, multiple accellerated labels */
GtkWidget *l=gtk_label_new_with_mnemonic(label);
GtkWidget *a=gtk_alignment_new(0,.5,0,0);
@@ -477,7 +480,7 @@
gtk_container_add(GTK_CONTAINER(a),wm[j]);
gtk_table_attach_defaults(GTK_TABLE(table),a,2+j*2,4+j*2,i+1,i+2);
gtk_table_attach(GTK_TABLE(table),l,1,2,i+1,i+2,GTK_FILL,0,0,0);
- if(j>0)gtk_widget_set_size_request(l,0,0);
+ if(j>0 || single_create)gtk_widget_set_size_request(l,0,0);
gtk_label_set_mnemonic_widget(GTK_LABEL(l),wm[j]);
{
@@ -494,28 +497,30 @@
}
}
- if(masterwinp){
+ if(single_create){
/* one master windowbutton, one label */
- wm[0]=windowbutton_new(label);
- gtk_table_attach_defaults(GTK_TABLE(table),wm[0],0,2,i+1,i+2);
+ wm[input_ch]=windowbutton_new(label);
+ gtk_table_attach_defaults(GTK_TABLE(table),wm[input_ch],0,2,i+1,i+2);
+
+ (*single_create)(p,wm+input_ch,wa);
}else{
- if (!channelwinp){
- GtkWidget *l=gtk_label_new(label);
+ GtkWidget *b=windowbutton_new(NULL);
- gtk_widget_set_name(l,"windowbuttonlike");
- gtk_misc_set_alignment(GTK_MISC(l),0,.5);
- gtk_table_attach_defaults(GTK_TABLE(table),l,1,2,i+1,i+2);
- }
- {
- GtkWidget *b=windowbutton_new(NULL);
-
- gtk_widget_set_sensitive(b,FALSE);
- gtk_table_attach_defaults(GTK_TABLE(table),b,0,1,i+1,i+2);
- }
+ gtk_widget_set_sensitive(b,FALSE);
+ gtk_table_attach_defaults(GTK_TABLE(table),b,0,1,i+1,i+2);
+ }
+ if(multi_create)
+ (*multi_create)(p,wm,wa);
+
+ if (!single_create && !multi_create){
+ GtkWidget *l=gtk_label_new(label);
+
+ gtk_widget_set_name(l,"windowbuttonlike");
+ gtk_misc_set_alignment(GTK_MISC(l),0,.5);
+ gtk_table_attach_defaults(GTK_TABLE(table),l,1,2,i+1,i+2);
}
- if(panel_create)(*panel_create)(p,wm,wa);
}
static void mainpanel_masterentry(postfish_mainpanel *p,
@@ -687,7 +692,7 @@
/* left side of main panel */
{
- char *labels[12]={"-96","-72","-60","-48","-36","-24",
+ char *labels[13]={"","-96","-72","-60","-48","-36","-24",
"-16","-8","-3","0","+3","+6"};
float levels[13]={-140.,-96.,-72.,-60.,-48.,-36.,-24.,
-16.,-8.,-3.,0.,+3.,+6.};
@@ -700,9 +705,9 @@
GtkWidget *inbox=gtk_hbox_new(0,0);
GtkWidget *outbox=gtk_hbox_new(0,0);
- panel->inbar=multibar_new(12,labels,levels, 0,
+ panel->inbar=multibar_new(13,labels,levels, 0,
LO_ATTACK|LO_DECAY|HI_DECAY|PEAK_FOLLOW );
- panel->outbar=multibar_new(12,labels,levels, 0,
+ panel->outbar=multibar_new(13,labels,levels, 0,
LO_ATTACK|LO_DECAY|HI_DECAY|PEAK_FOLLOW );
panel->inreadout=readout_new("------");
panel->outreadout=readout_new("------");
@@ -748,7 +753,7 @@
/* master dB slider */
{
- char *sliderlabels[10]={"-40","-30","-20","-10","0","+10","+20","+30","+40","+50"};
+ char *sliderlabels[11]={"","-40","-30","-20","-10","0","+10","+20","+30","+40","+50"};
float sliderlevels[11]={-50,-40,-30,-20,-10,0,10,20,30,40,50};
GtkWidget *box=gtk_hbox_new(0,0);
@@ -756,7 +761,7 @@
GtkWidget *masterlabel=gtk_label_new("master:");
panel->masterdB_a=gtk_toggle_button_new_with_label("a[t]ten");
panel->masterdB_r=readout_new(" 0.0dB");
- panel->masterdB_s=multibar_slider_new(10,sliderlabels,sliderlevels,1);
+ panel->masterdB_s=multibar_slider_new(11,sliderlabels,sliderlevels,1);
multibar_thumb_set(MULTIBAR(panel->masterdB_s),0.,0);
multibar_thumb_increment(MULTIBAR(panel->masterdB_s),.1,1.);
@@ -952,13 +957,14 @@
gtk_table_attach_defaults(GTK_TABLE(channeltable),temp,1,2+input_ch*2,0,1);
}
- mainpanel_chentry(panel,channeltable,"Mute ",0,0,0,mutedummy_create);
- mainpanel_chentry(panel,channeltable,"_Declip ",1,1,0,clippanel_create);
- mainpanel_chentry(panel,channeltable,"_Multicomp ",2,0,1,compandpanel_create_channel);
- mainpanel_chentry(panel,channeltable,"_Singlecomp ",3,0,1,singlepanel_create_channel);
- mainpanel_chentry(panel,channeltable,"De_verb ",4,1,0,suppresspanel_create_channel);
- mainpanel_chentry(panel,channeltable,"_Reverb ",5,1,0,0);
- mainpanel_chentry(panel,channeltable,"_EQ ",6,0,1,eqpanel_create_channel);
+ mainpanel_chentry(panel,channeltable,"_Declip ",0,clippanel_create,0);
+ mainpanel_chentry(panel,channeltable,"_Multicomp ",1,0,compandpanel_create_channel);
+ mainpanel_chentry(panel,channeltable,"_Singlecomp ",2,0,singlepanel_create_channel);
+ mainpanel_chentry(panel,channeltable,"De_verb ",3,suppresspanel_create_channel,0);
+ mainpanel_chentry(panel,channeltable,"_EQ ",4,0,eqpanel_create_channel);
+ mainpanel_chentry(panel,channeltable,"_Reverb ",5,0,0);
+ mainpanel_chentry(panel,channeltable,"Atten/Mi_x ",6,attenpanel_create,
+ mixpanel_create_channel);
/* master panel */
{
@@ -981,14 +987,47 @@
gtk_table_attach_defaults(GTK_TABLE(mastertable),temp,1,2,0,1);
}
- mainpanel_masterentry(panel,mastertable,"_Crossmix "," c ",GDK_c,0,0);
- mainpanel_masterentry(panel,mastertable,"_Multicomp "," m ",GDK_m,1,compandpanel_create_master);
- mainpanel_masterentry(panel,mastertable,"_Singlecomp "," s ",GDK_s,2,singlepanel_create_master);
- mainpanel_masterentry(panel,mastertable,"_Reverb "," r ",GDK_r,3,0);
- mainpanel_masterentry(panel,mastertable,"_EQ "," e ",GDK_e,4,eqpanel_create_master);
- mainpanel_masterentry(panel,mastertable,"_Limit "," l ",GDK_l,5,limitpanel_create);
- mainpanel_masterentry(panel,mastertable,"_Output ",NULL,GDK_l,6,0);
+ mainpanel_masterentry(panel,mastertable,"_Multicomp "," m ",GDK_m,0,compandpanel_create_master);
+ mainpanel_masterentry(panel,mastertable,"_Singlecomp "," s ",GDK_s,1,singlepanel_create_master);
+ mainpanel_masterentry(panel,mastertable,"_Reverb "," r ",GDK_r,2,0);
+ mainpanel_masterentry(panel,mastertable,"_EQ "," e ",GDK_e,3,eqpanel_create_master);
+ mainpanel_masterentry(panel,mastertable,"_Limit "," l ",GDK_l,4,limitpanel_create);
+ /* output has three activity buttons not in the main grid */
+ {
+ GtkWidget *ww=windowbutton_new("_Output ");
+
+ GtkWidget *std=gtk_toggle_button_new_with_label("o");
+ GtkWidget *ply=gtk_toggle_button_new_with_label("p");
+ GtkWidget *fil=gtk_toggle_button_new_with_label("f");
+ GtkWidget *box=gtk_hbox_new(0,0);
+ GtkWidget *box2=gtk_hbox_new(1,0);
+
+ GtkWidget *fw=windowbutton_new(NULL);
+ GtkWidget *fr=gtk_frame_new(NULL);
+
+ gtk_frame_set_shadow_type(GTK_FRAME(fr),GTK_SHADOW_ETCHED_IN);
+ gtk_widget_set_sensitive(fw,FALSE);
+
+ gtk_widget_add_accelerator (std, "activate", panel->group, GDK_o, 0, 0);
+ gtk_widget_add_accelerator (ply, "activate", panel->group, GDK_p, 0, 0);
+ gtk_widget_add_accelerator (fil, "activate", panel->group, GDK_f, 0, 0);
+
+ gtk_box_pack_start(GTK_BOX(box),ww,0,0,0);
+ gtk_box_pack_start(GTK_BOX(box),box2,1,1,2);
+ gtk_box_pack_start(GTK_BOX(box2),ply,1,1,0);
+ gtk_box_pack_start(GTK_BOX(box2),fil,1,1,0);
+
+
+ gtk_table_attach_defaults(GTK_TABLE(mastertable),fw,0,1,6,7);
+ gtk_table_attach_defaults(GTK_TABLE(mastertable),fr,1,2,6,7);
+
+ gtk_table_attach_defaults(GTK_TABLE(mastertable),box,0,1,7,8);
+ gtk_table_attach_defaults(GTK_TABLE(mastertable),std,1,2,7,8);
+
+ //if(panel_create)(*panel_create)(p,ww,(shortcut?wa:0));
+ }
+
g_signal_connect (G_OBJECT (panel->toplevel), "delete_event",
G_CALLBACK (shutdown), NULL);
@@ -1074,6 +1113,7 @@
compandpanel_feedback(current_p);
singlepanel_feedback(current_p);
limitpanel_feedback(current_p);
+ mixpanel_feedback(current_p);
}
}
@@ -1090,6 +1130,14 @@
return TRUE;
}
+static int look_for_gtkrc(char *filename){
+ FILE *f=fopen(filename,"r");
+ if(!f)return 0;
+ fprintf(stderr,"Loading postfish-gtkrc file found at %s\n",filename);
+ gtk_rc_add_default_file(filename);
+ return 1;
+}
+
#include <stdlib.h>
void mainpanel_go(int argc,char *argv[], int ch){
postfish_mainpanel p;
@@ -1097,9 +1145,48 @@
char *labels[11];
char buffer[20];
int i;
+ int found=0;
+ memset(&p,0,sizeof(p));
- memset(&p,0,sizeof(p));
- gtk_rc_add_default_file("/etc/postfish/postfish-gtkrc");
+ found|=look_for_gtkrc(ETCDIR"/postfish-gtkrc");
+ {
+ char *rcdir=getenv("HOME");
+ if(rcdir){
+ char *rcfile="/.postfish/postfish-gtkrc";
+ char *homerc=calloc(1,strlen(rcdir)+strlen(rcfile)+1);
+ strcat(homerc,homedir);
+ strcat(homerc,rcfile);
+ found|=look_for_gtkrc(homerc);
+ }
+ }
+ {
+ char *rcdir=getenv("POSTFISH_RCDIR");
+ if(rcdir){
+ char *rcfile="/postfish-gtkrc";
+ char *homerc=calloc(1,strlen(rcdir)+strlen(rcfile)+1);
+ strcat(homerc,homedir);
+ strcat(homerc,rcfile);
+ found|=look_for_gtkrc(homerc);
+ }
+ }
+ found|=look_for_gtkrc("./postfish-gtkrc");
+
+ if(!found){
+
+ fprintf(stderr,"Postfish could not find the postfish-gtkrc configuration file normally\n"
+ "installed with Postfish and located in one of the following places:\n"
+
+ "\t./postfish-gtkrc\n"
+ "\t$(POSTFISHDIR)/postfish-gtkrc\n"
+ "\t~/.postfish/postfish-gtkrc\n\t"
+ ETCDIR"/postfish-gtkrc\n"
+ "This configuration file is used to tune the color, font and other detail aspects\n"
+ "of the Postfish user interface. Although Postfish will work without it, the UI\n"
+ "appearence will likely make the application harder to use due to missing visual\n"
+ "cues.\n");
+ }
+
+ gtk_rc_add_default_file(ETCDIR"/postfish-gtkrc");
if(homedir){
char *rcfile="/.postfish-gtkrc";
char *homerc=calloc(1,strlen(homedir)+strlen(rcfile)+1);
@@ -1114,13 +1201,13 @@
memset(labels,0,sizeof(labels));
switch(ch){
case 1:
- labels[0]="_0 mono";
+ labels[0]="_1 mono";
break;
case 2:
- labels[0]="_0 left";
- labels[1]="_1 right";
- labels[2]="_2 mid";
- labels[3]="_3 side";
+ labels[0]="_1 left";
+ labels[1]="_2 right";
+ labels[2]="_y mid";
+ labels[3]="_z side";
break;
case 3:
case 4:
@@ -1136,14 +1223,17 @@
case 14:
case 15:
case 16:
- for(i=0;i<ch;i++){
- sprintf(buffer,"_%d",i);
+ for(i=0;i<ch && i<9;i++){
+ sprintf(buffer,"_%d",i+1);
labels[i]=strdup(buffer);
}
- sprintf(buffer,"_%d mid",i);
- labels[i++]=strdup(buffer);
- sprintf(buffer,"_%d div",i);
- labels[i++]=strdup(buffer);
+ for(;i<ch;i++){
+ sprintf(buffer,"%d_%d",(i+1)/10,(i+1)%10);
+ labels[i]=strdup(buffer);
+ }
+ labels[i++]=strdup("_y mid");
+ labels[i++]=strdup("_z div");
+
break;
default:
fprintf(stderr,"\nPostfish currently supports inputs of one to sixteen\n"
Modified: trunk/postfish/mainpanel.h
===================================================================
--- trunk/postfish/mainpanel.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/mainpanel.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -32,6 +32,7 @@
#include "singlepanel.h"
#include "suppresspanel.h"
#include "limitpanel.h"
+#include "mixpanel.h"
#include "mutedummy.h"
struct postfish_mainpanel{
Added: trunk/postfish/mix.c
===================================================================
--- trunk/postfish/mix.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/mix.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -0,0 +1,608 @@
+/*
+ *
+ * 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.
+ *
+ *
+ */
+
+#include "postfish.h"
+#include "feedback.h"
+#include "mix.h"
+
+extern int input_ch;
+extern int input_size;
+extern int input_rate;
+
+mix_settings *mix_set;
+
+sig_atomic_t atten_visible;
+sig_atomic_t *mixpanel_active;
+sig_atomic_t *mixpanel_visible;
+
+
+typedef struct{
+ time_linkage out;
+ feedback_generic_pool feedpool;
+
+ mix_settings *prev;
+ mix_settings *curr;
+
+ float **cacheP;
+ float **cachePP;
+
+ float **cachePA;
+ float **cachePPA;
+
+ float **cachePB;
+ float **cachePPB;
+
+ int fillstate;
+} mix_state;
+
+mix_state ms;
+
+/* this should be moved somewhere obvious/generic */
+float *frame_window;
+
+/* feedback! */
+typedef struct limit_feedback{
+ feedback_generic parent_class;
+ float **peak;
+ float **rms;
+ int bypass;
+} mix_feedback;
+
+static feedback_generic *new_mix_feedback(void){
+ mix_feedback *ret=calloc(1,sizeof(*ret));
+ return (feedback_generic *)ret;
+}
+
+/* peak, rms are pulled in array[mixblock][input_ch] order */
+int pull_mix_feedback(float **peak,float **rms){
+ mix_feedback *f=(mix_feedback *)feedback_pull(&ms.feedpool);
+ int i;
+
+ if(!f)return 0;
+
+ if(f->bypass){
+ feedback_old(&ms.feedpool,(feedback_generic *)f);
+ return 2;
+ }else{
+ if(peak)
+ for(i=0;i<MIX_BLOCKS+5;i++)
+ memcpy(peak[i],f->peak[i],sizeof(**peak)*input_ch);
+ if(rms)
+ for(i=0;i<MIX_BLOCKS+5;i++)
+ memcpy(rms[i],f->rms[i],sizeof(**rms)*input_ch);
+ feedback_old(&ms.feedpool,(feedback_generic *)f);
+ return 1;
+ }
+}
+
+/* called only by initial setup */
+int mix_load(int outch){
+ int i;
+
+ mix_set=calloc(input_ch,sizeof(*mix_set));
+ mixpanel_active=calloc(input_ch,sizeof(*mixpanel_active));
+ mixpanel_visible=calloc(input_ch,sizeof(*mixpanel_visible));
+
+ memset(&ms,0,sizeof(ms));
+ ms.prev=calloc(input_ch,sizeof(*ms.prev));
+ ms.curr=calloc(input_ch,sizeof(*ms.curr));
+
+ ms.cacheP=malloc(input_ch*sizeof(*ms.cacheP));
+ ms.cachePP=malloc(input_ch*sizeof(*ms.cachePP));
+ ms.cachePA=malloc(input_ch*sizeof(*ms.cachePA));
+ ms.cachePPA=malloc(input_ch*sizeof(*ms.cachePPA));
+ ms.cachePB=malloc(input_ch*sizeof(*ms.cachePB));
+ ms.cachePPB=malloc(input_ch*sizeof(*ms.cachePPB));
+ for(i=0;i<input_ch;i++)
+ ms.cacheP[i]=malloc(input_size*sizeof(**ms.cacheP));
+ for(i=0;i<input_ch;i++)
+ ms.cachePP[i]=malloc(input_size*sizeof(**ms.cachePP));
+ for(i=0;i<input_ch;i++)
+ ms.cachePA[i]=malloc(input_size*sizeof(**ms.cachePA));
+ for(i=0;i<input_ch;i++)
+ ms.cachePPA[i]=malloc(input_size*sizeof(**ms.cachePPA));
+ for(i=0;i<input_ch;i++)
+ ms.cachePB[i]=malloc(input_size*sizeof(**ms.cachePB));
+ for(i=0;i<input_ch;i++)
+ ms.cachePPB[i]=malloc(input_size*sizeof(**ms.cachePPB));
+
+ ms.out.channels=outch;
+ ms.out.data=malloc(outch*sizeof(*ms.out.data));
+ for(i=0;i<outch;i++)
+ ms.out.data[i]=malloc(input_size*sizeof(**ms.out.data));
+
+ frame_window=malloc(input_size*sizeof(*frame_window));
+ for(i=0;i<input_size;i++){
+ frame_window[i]= sin( (i+.5)/input_size*M_PI*.5 );
+ frame_window[i]*=frame_window[i];
+ }
+
+ return 0;
+}
+
+/* called only in playback thread */
+int mix_reset(){
+ while(pull_mix_feedback(NULL,NULL));
+ ms.fillstate=0;
+ return 0;
+}
+
+static void mixwork(float *data,float *cacheP,float *cachePP,
+ float *out,
+ float att,int del,int inv,
+ float attP,float delP,int invP){
+ int offset=0;
+ int i;
+
+ if(-del>input_size*2)del= -input_size*2;
+ if(-delP>input_size*2)delP= -input_size*2;
+
+ if(inv)att*=-1.;
+ if(invP)attP*=-1.;
+
+ if(att==attP && del==delP){
+
+ /* straight copy from cache with attenuation */
+ i=input_size*2+del;
+ while(i<input_size && offset<input_size)
+ out[offset++]+=cachePP[i++]*att;
+
+ i=input_size+del;
+ if(i<0)i=0;
+ while(i<input_size && offset<input_size)
+ out[offset++]+=cacheP[i++]*att;
+
+ i=0;
+ while(offset<input_size)
+ out[offset++]+=data[i++]*att;
+
+ }else{
+ /* lapped dual copy from cache */
+
+ /* current settings */
+ i=input_size*2+del;
+ while(i<input_size && offset<input_size){
+ out[offset]+=cachePP[i++]*att*frame_window[offset];
+ offset++;
+ }
+
+ i=input_size+del;
+ if(i<0)i=0;
+ while(i<input_size && offset<input_size){
+ out[offset]+=cacheP[i++]*att*frame_window[offset];
+ offset++;
+ }
+
+ i=0;
+ while(offset<input_size){
+ out[offset]+=data[i++]*att*frame_window[offset];
+ offset++;
+ }
+
+ /* ...lapped transition from old settings */
+ offset=0;
+ i=input_size*2+delP;
+ while(i<input_size && offset<input_size){
+ out[offset]+=cachePP[i++]*attP*frame_window[input_size-offset-1];
+ offset++;
+ }
+
+ i=input_size+delP;
+ if(i<0)i=0;
+ while(i<input_size && offset<input_size){
+ out[offset]+=cacheP[i++]*attP*frame_window[input_size-offset-1];
+ offset++;
+ }
+
+ i=0;
+ while(offset<input_size){
+ out[offset]+=data[i++]*attP*frame_window[input_size-offset-1];
+ offset++;
+ }
+ }
+}
+
+/* smooth active/inactive transitions while adding */
+static void mixadd(float *in,float *out,int active,int activeP){
+ int i;
+ if(!active && !activeP)return;
+ if(active && activeP){
+ for(i=0;i<input_size;i++)
+ out[i]+=in[i];
+ return;
+ }
+ if(active){
+ /* transitioning to active */
+ for(i=0;i<input_size;i++)
+ out[i]+=in[i]*frame_window[i];
+ return;
+ }
+ /* transitioning to inactive */
+ for(i=0;i<input_size;i++)
+ out[i]+=in[i]*frame_window[input_size-i-1];
+}
+
+/* called only by playback thread */
+time_linkage *mix_read(time_linkage *in,
+ time_linkage *inA, // reverb channel
+ time_linkage *inB){ // reverb channel
+
+ int i,j,k,outch=ms.out.channels;
+ int outactive[outch];
+
+ float peak[MIX_BLOCKS+5][input_ch];
+ float rms[MIX_BLOCKS+5][input_ch];
+ int bypass=1;
+
+ if(in->samples==0){
+ ms.out.samples=0;
+ return &ms.out;
+ }
+ memset(outactive,0,sizeof(outactive));
+ memset(peak,0,sizeof(peak));
+ memset(rms,0,sizeof(rms));
+
+ /* fillstate here is only used for lazy initialization/reset */
+ if(ms.fillstate==0){
+ /* zero the cache */
+ for(i=0;i<input_ch;i++){
+ memset(ms.cacheP[i],0,sizeof(**ms.cacheP)*input_size);
+ memset(ms.cachePP[i],0,sizeof(**ms.cachePP)*input_size);
+ }
+ ms.fillstate=1;
+ }
+
+ /* zero the output block; we'll me mixing into it input-by-input */
+ for(i=0;i<outch;i++)
+ memset(ms.out.data[i],0,sizeof(**ms.out.data)*input_size);
+
+ /* eliminate asynch change possibility */
+ memcpy(ms.curr,mix_set,sizeof(*mix_set)*input_ch);
+
+ /* a bit of laziness that may actually save time by avoiding
+ special-cases later */
+ for(i=0;i<input_ch;i++)
+ if(mute_channel_muted(in->active,i))
+ memset(in->data[i],0,sizeof(**in->data)*input_size);
+
+ /* input-by-input */
+ for(i=0;i<input_ch;i++){
+ int feedit=mixpanel_visible[i] && mixpanel_active[i];
+ int feeditM=atten_visible && mixpanel_active[i];
+
+ /* master feedback is a bit of a pain; the metrics we need aren't
+ produced by any of the mixdowns below. Do it by hand */
+ if(feeditM){
+ float mix[input_size];
+ float att=fromdB(ms.curr[i].master_att * .1);
+ int del=rint(ms.curr[i].master_delay*.00001*input_rate);
+ float acc=0.;
+
+ if(!mute_channel_muted(in->active,i)){
+ memset(mix,0,sizeof(mix));
+ mixwork(in->data[i],ms.cacheP[i],ms.cachePP[i],
+ mix,att,del,0,att,del,0);
+
+ bypass=0;
+ for(j=0;j<input_size;j++){
+ float val=mix[j]*mix[j];
+ if(val>peak[0][i])peak[0][i]=val;
+ acc+=val;
+ }
+
+ peak[0][i]=peak[0][i];
+ rms[0][i]=acc/input_size;
+ }
+
+ if(inA && !mute_channel_muted(inA->active,i)){
+ memset(mix,0,sizeof(mix));
+ mixwork(inA->data[i],ms.cacheP[i],ms.cachePP[i],
+ mix,att,del,0,att,del,0);
+
+ bypass=0;
+ for(j=0;j<input_size;j++){
+ float val=mix[j]*mix[j];
+ if(val>peak[0][i])peak[0][i]=val;
+ acc+=val;
+ }
+
+ peak[1][i]=peak[0][i];
+ rms[1][i]=acc/input_size;
+ }
+
+ if(inB && !mute_channel_muted(inB->active,i)){
+ memset(mix,0,sizeof(mix));
+ mixwork(inB->data[i],ms.cacheP[i],ms.cachePP[i],
+ mix,att,del,0,att,del,0);
+
+ bypass=0;
+ for(j=0;j<input_size;j++){
+ float val=mix[j]*mix[j];
+ if(val>peak[0][i])peak[0][i]=val;
+ acc+=val;
+ }
+
+ peak[2][i]=peak[0][i];
+ rms[2][i]=acc/input_size;
+ }
+ }
+
+ /* placer settings; translate to final numbers */
+ int placer=ms.curr[i].placer_place;
+ int placerP=ms.prev[i].placer_place;
+
+ float relA=(placer>100 ? placer*.01-1. : 0.);
+ float relB=(placer<100 ? 1.-placer*.01 : 0.);
+ float relAP=(placerP>100 ? placerP*.01-1. : 0.);
+ float relBP=(placerP<100 ? 1.-placerP*.01 : 0.);
+
+ float attA=
+ fromdB((ms.curr[i].master_att +
+ ms.curr[i].placer_att * relA)*.1);
+
+ float attB=
+ fromdB((ms.curr[i].master_att +
+ ms.curr[i].placer_att * relB)*.1);
+
+ int delA=
+ rint((ms.curr[i].master_delay +
+ ms.curr[i].placer_delay * relA)*.00001*input_rate);
+
+ int delB=
+ rint((ms.curr[i].master_delay +
+ ms.curr[i].placer_delay * relB)*.00001*input_rate);
+
+ float attAP=
+ fromdB((ms.prev[i].master_att +
+ ms.prev[i].placer_att * relAP)*.1);
+
+ float attBP=
+ fromdB((ms.prev[i].master_att +
+ ms.prev[i].placer_att * relBP)*.1);
+
+ int delAP=
+ rint((ms.prev[i].master_delay +
+ ms.prev[i].placer_delay * relAP)*.00001*input_rate);
+
+ int delBP=
+ rint((ms.prev[i].master_delay +
+ ms.prev[i].placer_delay * relBP)*.00001*input_rate);
+
+ /* place mix */
+ {
+ int mixedA=0,mixedB=0;
+ float mixA[input_size],mixB[input_size];
+
+ for(j=0;j<OUTPUT_CHANNELS;j++){
+ int destA=ms.curr[i].placer_destA[j];
+ int destAP=ms.prev[i].placer_destA[j];
+ int destB=ms.curr[i].placer_destB[j];
+ int destBP=ms.prev[i].placer_destB[j];
+
+ if(destA || destAP){
+ outactive[j]=1;
+
+ if(!mixedA){
+ memset(mixA,0,sizeof(mixA));
+ mixwork(in->data[i],ms.cacheP[i],ms.cachePP[i],
+ mixA,attA,delA,0,attAP,delAP,0);
+ mixedA=1;
+ }
+ mixadd(mixA,ms.out.data[j],destA,destAP);
+ }
+ if(destB || destBP){
+ outactive[j]=1;
+
+ if(!mixedB){
+ memset(mixB,0,sizeof(mixB));
+ mixwork(in->data[i],ms.cacheP[i],ms.cachePP[i],
+ mixB,attB,delB,0,attBP,delBP,0);
+ mixedB=1;
+ }
+ mixadd(mixB,ms.out.data[j],destB,destBP);
+ }
+ }
+
+ /* feedback for A */
+ if(feedit){
+ float acc=0.;
+ bypass=0;
+ if(mixedA){
+ for(j=0;j<input_size;j++){
+ float val=mixA[j]*mixA[j];
+ if(val>peak[3][i])peak[3][i]=val;
+ acc+=val;
+ }
+
+ peak[3][i]=peak[3][i];
+ rms[3][i]=acc/input_size;
+ }
+ }
+
+ /* feedback for B */
+ if(feedit){
+ float acc=0.;
+ bypass=0;
+ if(mixedB){
+ for(j=0;j<input_size;j++){
+ float val=mixB[j]*mixB[j];
+ if(val>peak[4][i])peak[4][i]=val;
+ acc+=val;
+ }
+
+ peak[4][i]=peak[4][i];
+ rms[4][i]=acc/input_size;
+ }
+ }
+ }
+
+ /* direct block mix */
+ for(k=0;k<MIX_BLOCKS;k++){
+ float mix[input_size];
+
+ int sourceM=ms.curr[i].insert_source[k][0];
+ int sourceMP=ms.prev[i].insert_source[k][0];
+ int sourceA=ms.curr[i].insert_source[k][1];
+ int sourceAP=ms.prev[i].insert_source[k][1];
+ int sourceB=ms.curr[i].insert_source[k][2];
+ int sourceBP=ms.prev[i].insert_source[k][2];
+
+ float att=
+ fromdB((ms.curr[i].master_att +
+ ms.curr[i].insert_att[k])*.1);
+
+ int del=
+ rint((ms.curr[i].master_delay +
+ ms.curr[i].insert_delay[k])*.00001*input_rate);
+
+ float attP=
+ fromdB((ms.prev[i].master_att +
+ ms.prev[i].insert_att[k])*.1);
+
+ int delP=
+ rint((ms.prev[i].master_delay +
+ ms.prev[i].insert_delay[k])*.00001*input_rate);
+
+ if(sourceM || sourceMP ||
+ sourceA || sourceAP ||
+ sourceB || sourceBP){
+ memset(mix,0,sizeof(mix));
+
+ /* master */
+ if(sourceM || sourceMP)
+ mixwork(in->data[i],ms.cacheP[i],ms.cachePP[i],
+ mix,
+ att,del,ms.curr[i].insert_invert[k],
+ attP,delP,ms.prev[i].insert_invert[k]);
+
+ /* reverbA */
+ if(sourceA || sourceAP)
+ if(inA)
+ mixwork(inA->data[i],ms.cachePA[i],ms.cachePPA[i],
+ mix,
+ att,del,ms.curr[i].insert_invert[k],
+ attP,delP,ms.prev[i].insert_invert[k]);
+
+ /* reverbB */
+ if(sourceB || sourceBP)
+ if(inB)
+ mixwork(inB->data[i],ms.cachePB[i],ms.cachePPB[i],
+ mix,
+ att,del,ms.curr[i].insert_invert[k],
+ attP,delP,ms.prev[i].insert_invert[k]);
+
+ /* mix into output */
+ for(j=0;j<OUTPUT_CHANNELS;j++){
+ int dest=ms.curr[i].insert_dest[k][j];
+ int destP=ms.prev[i].insert_dest[k][j];
+
+ if(dest || destP){
+ outactive[j]=1;
+ mixadd(mix,ms.out.data[j],dest,destP);
+ }
+ }
+
+ /* feedback */
+ if(feedit){
+ float acc=0.;
+ bypass=0;
+ for(j=0;j<input_size;j++){
+ float val=mix[j]*mix[j];
+ if(val>peak[5+k][i])peak[5+k][i]=val;
+ acc+=val;
+ }
+
+ peak[5+k][i]=peak[5+k][i];
+ rms[5+k][i]=acc/input_size;
+
+ }
+ }
+ }
+ /* rotate data cache */
+ {
+ float *temp=ms.cachePP[i];
+ ms.cachePP[i]=ms.cacheP[i];
+ ms.cacheP[i]=in->data[i];
+ in->data[i]=temp;
+
+ if(inA){
+ temp=ms.cachePPA[i];
+ ms.cachePPA[i]=ms.cachePA[i];
+ ms.cachePA[i]=inA->data[i];
+ inA->data[i]=temp;
+ }
+
+ if(inB){
+ temp=ms.cachePPB[i];
+ ms.cachePPB[i]=ms.cachePB[i];
+ ms.cachePB[i]=inB->data[i];
+ inB->data[i]=temp;
+ }
+ }
+ }
+
+ /* finish output data */
+ ms.out.samples=in->samples;
+ ms.out.active=0;
+ for(i=0;i<OUTPUT_CHANNELS;i++)
+ if(outactive[i])
+ ms.out.active|=(1<<i);
+
+ /* rotate settings cache */
+ {
+ mix_settings *temp=ms.curr;
+ ms.curr=ms.prev;
+ ms.prev=temp;
+ }
+
+ /* push feedback */
+ if(bypass){
+ mix_feedback *mf=
+ (mix_feedback *)feedback_new(&ms.feedpool,new_mix_feedback);
+ mf->bypass=1;
+ feedback_push(&ms.feedpool,(feedback_generic *)mf);
+ }else{
+ mix_feedback *mf=
+ (mix_feedback *)feedback_new(&ms.feedpool,new_mix_feedback);
+
+ if(!mf->peak){
+ mf->peak=malloc((MIX_BLOCKS+5)*sizeof(*mf->peak));
+ mf->rms=malloc((MIX_BLOCKS+5)*sizeof(*mf->rms));
+
+ for(i=0;i<MIX_BLOCKS+5;i++)
+ mf->rms[i]=malloc(input_ch*sizeof(**mf->rms));
+ for(i=0;i<MIX_BLOCKS+5;i++)
+ mf->peak[i]=malloc(input_ch*sizeof(**mf->peak));
+ }
+
+ for(i=0;i<MIX_BLOCKS+5;i++){
+ memcpy(mf->peak[i],peak[i],input_ch*sizeof(**peak));
+ memcpy(mf->rms[i],rms[i],input_ch*sizeof(**rms));
+ }
+ mf->bypass=0;
+ feedback_push(&ms.feedpool,(feedback_generic *)mf);
+ }
+
+ return &ms.out;
+}
+
Added: trunk/postfish/mix.h
===================================================================
--- trunk/postfish/mix.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/mix.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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.
+ *
+ *
+ */
+
+#include "postfish.h"
+
+#define MIX_BLOCKS 4
+
+typedef struct {
+ sig_atomic_t master_att;
+ sig_atomic_t master_delay;
+
+ sig_atomic_t placer_destA[OUTPUT_CHANNELS];
+ sig_atomic_t placer_destB[OUTPUT_CHANNELS];
+ sig_atomic_t placer_place;
+ sig_atomic_t placer_att;
+ sig_atomic_t placer_delay;
+
+ sig_atomic_t insert_source[MIX_BLOCKS][3];
+ sig_atomic_t insert_invert[MIX_BLOCKS];
+ sig_atomic_t insert_att[MIX_BLOCKS];
+ sig_atomic_t insert_delay[MIX_BLOCKS];
+ sig_atomic_t insert_dest[MIX_BLOCKS][OUTPUT_CHANNELS];
+} mix_settings;
+
+extern int mix_load(int outch);
+extern int mix_reset(void);
+extern time_linkage *mix_read(time_linkage *in,
+ time_linkage *inA, // reverb channel
+ time_linkage *inB); // reverb channel
+extern int pull_mix_feedback(float **peak,float **rms);
+
Added: trunk/postfish/mixpanel.c
===================================================================
--- trunk/postfish/mixpanel.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/mixpanel.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -0,0 +1,545 @@
+/*
+ *
+ * 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.
+ *
+ *
+ */
+
+#include "postfish.h"
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "readout.h"
+#include "multibar.h"
+#include "mainpanel.h"
+#include "subpanel.h"
+#include "feedback.h"
+#include "mix.h"
+
+extern int input_ch;
+extern int input_size;
+extern int input_rate;
+
+extern mix_settings *mix_set;
+extern sig_atomic_t atten_visible;
+extern sig_atomic_t *mixpanel_active;
+extern sig_atomic_t *mixpanel_visible;
+
+typedef struct {
+ GtkWidget *s;
+ GtkWidget *r;
+ sig_atomic_t *val;
+} slider_readout_pair;
+
+/* only the sliders we need to save for feedback */
+typedef struct {
+ GtkWidget **master;
+} atten_panelsave;
+
+typedef struct {
+ GtkWidget *place[2];
+ GtkWidget *sub[MIX_BLOCKS];
+} mix_panelsave;
+
+static atten_panelsave atten_panel;
+static mix_panelsave **mix_panels;
+
+static void dB_slider_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ slider_readout_pair *p=(slider_readout_pair *)in;
+ float val=multibar_get_value(MULTIBAR(p->s),0);
+
+ sprintf(buffer,"%+4.1fdB",val);
+ readout_set(READOUT(p->r),buffer);
+
+ *p->val=rint(val*10);
+}
+
+static void ms_slider_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ slider_readout_pair *p=(slider_readout_pair *)in;
+ float val=multibar_get_value(MULTIBAR(p->s),0);
+
+ if(val>-1. && val<1.){
+ sprintf(buffer,"%+4.2fms",val);
+ }else{
+ sprintf(buffer,"%+4.1fms",val);
+ }
+ readout_set(READOUT(p->r),buffer);
+ *p->val=rint(val*100);
+}
+
+static void AB_slider_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ slider_readout_pair *p=(slider_readout_pair *)in;
+ float val=multibar_get_value(MULTIBAR(p->s),0);
+
+ if(val==100){
+ sprintf(buffer,"center");
+ }else if(val<100){
+ sprintf(buffer,"A+%d%%",(int)(100-val));
+ }else{
+ sprintf(buffer,"B+%d%%",(int)(val-100));
+ }
+ readout_set(READOUT(p->r),buffer);
+
+ *p->val=rint(val);
+}
+
+static void toggle_callback(GtkWidget *w,gpointer in){
+ GtkToggleButton *b=GTK_TOGGLE_BUTTON(w);
+ sig_atomic_t *val=(sig_atomic_t *)in;
+
+ *val=gtk_toggle_button_get_active(b);
+}
+
+static char *labels_dB[11]={""," 60","40","20","10","0","10","20","40","60","80"};
+static float levels_dB[11]={-80,-60,-40,-20,-10,0,10,20,40,60,80};
+
+static char *labels_dBn[6]={"","-40","-20","-10","0","+10"};
+static float levels_dBn[6]={-80,-40,-20,-10,0,10};
+
+static char *labels_del[6]={"","-20","-10","-5","-1","-0"};
+static float levels_del[6]={-50,-20,-10,-5,-1,0};
+
+
+static mix_panelsave *mixpanel_create_helper(postfish_mainpanel *mp,
+ subpanel_generic *panel,
+ mix_settings *m){
+
+ int i,j;
+
+ char *labels_dBnn[6]={"","-40","-20","-10","-3","0"};
+ float levels_dBnn[6]={-80,-40,-20,-10,-3,0};
+
+ char *labels_AB[3]={"A","center","B"};
+ float levels_AB[3]={0,100,200};
+
+ GtkWidget *table=gtk_table_new(12+MIX_BLOCKS*3,6,0);
+ mix_panelsave *ps=calloc(1,sizeof(*ps));
+
+ /* crossplace marker */
+ {
+ GtkWidget *box=gtk_hbox_new(0,0);
+ GtkWidget *l=gtk_label_new("Crossplace ");
+ GtkWidget *h=gtk_hseparator_new();
+
+ gtk_widget_set_name(l,"framelabel");
+
+ gtk_box_pack_start(GTK_BOX(box),l,0,0,0);
+ gtk_box_pack_start(GTK_BOX(box),h,1,1,0);
+ gtk_table_attach(GTK_TABLE(table),box,0,6,2,3,
+ GTK_FILL,0,0,2);
+ gtk_table_set_row_spacing(GTK_TABLE(table),1,10);
+ }
+
+ /* crossplace controls */
+ {
+ slider_readout_pair *AB=calloc(1,sizeof(AB));
+ slider_readout_pair *att=calloc(1,sizeof(att));
+ slider_readout_pair *del=calloc(1,sizeof(del));
+ GtkWidget *boxA=gtk_hbox_new(1,0);
+ GtkWidget *boxB=gtk_hbox_new(1,0);
+
+ GtkWidget *lA=gtk_label_new("output A");
+ GtkWidget *lB=gtk_label_new("output B");
+
+ GtkWidget *latt=gtk_label_new("crossatten ");
+ GtkWidget *ldel=gtk_label_new("crossdelay ");
+ gtk_misc_set_alignment(GTK_MISC(latt),1,.5);
+ gtk_misc_set_alignment(GTK_MISC(ldel),1,.5);
+
+ AB->s=multibar_slider_new(3,labels_AB,levels_AB,1);
+ att->s=multibar_slider_new(6,labels_dBnn,levels_dBnn,1);
+ del->s=multibar_slider_new(6,labels_del,levels_del,1);
+ AB->r=readout_new("A+000");
+ att->r=readout_new("+00.0dB");
+ del->r=readout_new("+00.0ms");
+ AB->val=&m->placer_place;
+ att->val=&m->placer_att;
+ del->val=&m->placer_delay;
+
+ multibar_callback(MULTIBAR(AB->s),AB_slider_change,AB);
+ multibar_thumb_set(MULTIBAR(AB->s),100,0);
+ multibar_callback(MULTIBAR(att->s),dB_slider_change,att);
+ multibar_thumb_set(MULTIBAR(att->s),0,0);
+ multibar_callback(MULTIBAR(del->s),ms_slider_change,del);
+ multibar_thumb_set(MULTIBAR(del->s),0,0);
+
+ ps->place[0]=multibar_new(6,labels_dBn,levels_dBn,0,
+ LO_ATTACK|LO_DECAY|HI_DECAY);
+ ps->place[1]=multibar_new(6,labels_dBn,levels_dBn,0,
+ LO_ATTACK|LO_DECAY|HI_DECAY);
+
+ for(i=0;i<OUTPUT_CHANNELS;i++){
+ char buffer[80];
+ GtkWidget *bA,*bB;
+
+ sprintf(buffer," %d ",i+1);
+
+ bA=gtk_toggle_button_new_with_label(buffer);
+ bB=gtk_toggle_button_new_with_label(buffer);
+
+ gtk_box_pack_start(GTK_BOX(boxA),bA,1,1,0);
+ gtk_box_pack_start(GTK_BOX(boxB),bB,1,1,0);
+
+ g_signal_connect (G_OBJECT (bA), "clicked",
+ G_CALLBACK (toggle_callback),
+ (gpointer)&m->placer_destA[i]);
+ g_signal_connect (G_OBJECT (bB), "clicked",
+ G_CALLBACK (toggle_callback),
+ (gpointer)&m->placer_destB[i]);
+
+ }
+
+ gtk_table_attach(GTK_TABLE(table),lA,0,2,6,7,
+ 0,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),lB,5,6,6,7,
+ 0,0,0,0);
+
+ gtk_table_attach(GTK_TABLE(table),ps->place[0],0,2,4,5,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),ps->place[1],5,6,4,5,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+
+ gtk_table_attach(GTK_TABLE(table),boxA,0,2,5,6,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),boxB,5,6,5,6,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),AB->s,2,4,4,5,
+ GTK_FILL|GTK_EXPAND,0,2,0);
+ gtk_table_attach(GTK_TABLE(table),att->s,3,4,5,6,
+ GTK_FILL|GTK_EXPAND,0,2,0);
+ gtk_table_attach(GTK_TABLE(table),del->s,3,4,6,7,
+ GTK_FILL|GTK_EXPAND,0,2,0);
+ gtk_table_attach(GTK_TABLE(table),AB->r,4,5,4,5,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),att->r,4,5,5,6,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),del->r,4,5,6,7,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+
+ gtk_table_attach(GTK_TABLE(table),latt,2,3,5,6,
+ GTK_FILL,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),ldel,2,3,6,7,
+ GTK_FILL,0,0,0);
+
+
+ }
+
+ /* Direct Mix marker */
+ {
+ GtkWidget *box=gtk_hbox_new(0,0);
+ GtkWidget *l=gtk_label_new("Direct Mixdown Blocks ");
+ GtkWidget *h=gtk_hseparator_new();
+
+ GtkWidget *ls=gtk_label_new("source");
+ GtkWidget *lo=gtk_label_new("output");
+
+ gtk_widget_set_name(l,"framelabel");
+
+ gtk_box_pack_start(GTK_BOX(box),l,0,0,0);
+ gtk_box_pack_start(GTK_BOX(box),h,1,1,0);
+
+ gtk_table_attach(GTK_TABLE(table),box,0,6,7,8,
+ GTK_FILL,0,0,2);
+ gtk_table_attach(GTK_TABLE(table),ls,0,2,11+MIX_BLOCKS*3,12+MIX_BLOCKS*3,
+ GTK_FILL,0,0,2);
+ gtk_table_attach(GTK_TABLE(table),lo,5,6,11+MIX_BLOCKS*3,12+MIX_BLOCKS*3,
+ GTK_FILL,0,0,2);
+ gtk_table_set_row_spacing(GTK_TABLE(table),6,10);
+
+ }
+
+ for(i=0;i<MIX_BLOCKS;i++){
+ slider_readout_pair *att=calloc(1,sizeof(att));
+ slider_readout_pair *del=calloc(1,sizeof(del));
+
+ GtkWidget *boxA=gtk_hbox_new(0,0);
+ GtkWidget *boxB=gtk_hbox_new(1,0);
+
+ GtkWidget *bI=gtk_check_button_new_with_mnemonic("_invert source");
+
+ GtkWidget *bM=gtk_toggle_button_new_with_label("master");
+ GtkWidget *bA=gtk_toggle_button_new_with_label("revA");
+ GtkWidget *bB=gtk_toggle_button_new_with_label("revB");
+ GtkWidget *h=gtk_hseparator_new();
+
+ GtkWidget *latt=gtk_label_new(" attenuation ");
+ GtkWidget *ldel=gtk_label_new(" delay ");
+ gtk_misc_set_alignment(GTK_MISC(latt),1,.5);
+ gtk_misc_set_alignment(GTK_MISC(ldel),1,.5);
+
+ att->s=multibar_slider_new(11,labels_dB,levels_dB,1);
+ del->s=multibar_slider_new(6,labels_del,levels_del,1);
+ att->r=readout_new("+00.0dB");
+ del->r=readout_new("+00.0ms");
+ att->val=&m->insert_att[i];
+ del->val=&m->insert_delay[i];
+
+ ps->sub[i]=multibar_new(6,labels_dBn,levels_dBn,0,
+ LO_ATTACK|LO_DECAY|HI_DECAY);
+
+ multibar_callback(MULTIBAR(att->s),dB_slider_change,att);
+ multibar_callback(MULTIBAR(del->s),ms_slider_change,del);
+
+ gtk_box_pack_start(GTK_BOX(boxA),bM,1,1,0);
+ gtk_box_pack_start(GTK_BOX(boxA),bA,1,1,0);
+ gtk_box_pack_start(GTK_BOX(boxA),bB,1,1,0);
+
+ g_signal_connect (G_OBJECT (bI), "clicked",
+ G_CALLBACK (toggle_callback),
+ (gpointer)&m->insert_invert[i]);
+
+ g_signal_connect (G_OBJECT (bM), "clicked",
+ G_CALLBACK (toggle_callback),
+ (gpointer)&m->insert_source[i][0]);
+ g_signal_connect (G_OBJECT (bA), "clicked",
+ G_CALLBACK (toggle_callback),
+ (gpointer)&m->insert_source[i][1]);
+ g_signal_connect (G_OBJECT (bB), "clicked",
+ G_CALLBACK (toggle_callback),
+ (gpointer)&m->insert_source[i][2]);
+
+
+
+ for(j=0;j<OUTPUT_CHANNELS;j++){
+ char buffer[80];
+ GtkWidget *b;
+
+ sprintf(buffer," %d ",j+1);
+
+ b=gtk_toggle_button_new_with_label(buffer);
+ g_signal_connect (G_OBJECT (b), "clicked",
+ G_CALLBACK (toggle_callback),
+ (gpointer)&m->insert_dest[i][j]);
+
+ gtk_box_pack_start(GTK_BOX(boxB),b,1,1,0);
+ }
+
+ gtk_table_attach(GTK_TABLE(table),boxA,0,2,9+i*3,10+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),boxB,5,6,9+i*3,10+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),att->s,3,4,8+i*3,9+i*3,
+ GTK_FILL|GTK_EXPAND,0,2,0);
+ gtk_table_attach(GTK_TABLE(table),del->s,3,4,9+i*3,10+i*3,
+ GTK_FILL|GTK_EXPAND,0,2,0);
+ gtk_table_attach(GTK_TABLE(table),att->r,4,5,8+i*3,9+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),del->r,4,5,9+i*3,10+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+
+ gtk_table_attach(GTK_TABLE(table),bI,0,2,8+i*3,9+i*3,
+ 0,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),ps->sub[i],5,6,8+i*3,9+i*3,
+ GTK_FILL,0,0,0);
+
+ gtk_table_attach(GTK_TABLE(table),latt,2,3,8+i*3,9+i*3,
+ GTK_FILL,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),ldel,2,3,9+i*3,10+i*3,
+ GTK_FILL,0,0,0);
+
+ gtk_table_attach(GTK_TABLE(table),h,0,6,10+i*3,11+i*3,
+ GTK_FILL,0,0,2);
+
+
+ }
+
+ gtk_box_pack_start(GTK_BOX(panel->subpanel_box),table,1,1,4);
+ subpanel_show_all_but_toplevel(panel);
+
+ return ps;
+}
+
+void mixpanel_create_channel(postfish_mainpanel *mp,
+ GtkWidget **windowbutton,
+ GtkWidget **activebutton){
+ int i;
+ mix_panels=malloc(input_ch*sizeof(*mix_panels));
+
+ /* a panel for each channel */
+ for(i=0;i<input_ch;i++){
+ subpanel_generic *panel;
+ char buffer[80];
+
+ sprintf(buffer,"Mi_xdown block (channel %d)",i+1);
+
+ panel=subpanel_create(mp,windowbutton[i],activebutton+i,
+ &mixpanel_active[i],
+ &mixpanel_visible[i],
+ buffer,0,i,1);
+
+ mix_panels[i]=mixpanel_create_helper(mp,panel,mix_set+i);
+ }
+}
+
+void attenpanel_create(postfish_mainpanel *mp,
+ GtkWidget **windowbutton,
+ GtkWidget **activebutton){
+ int i;
+ subpanel_generic *panel=subpanel_create(mp,windowbutton[0],activebutton,
+ mixpanel_active,
+ &atten_visible,
+ "Mi_x Input Delay / Attenuation",
+ 0,0,input_ch);
+
+ GtkWidget *table=gtk_table_new(MIX_BLOCKS*3,5,0);
+ mix_panelsave *ps=calloc(1,sizeof(*ps));
+ atten_panel.master=calloc(input_ch,sizeof(*atten_panel.master));
+
+ for(i=0;i<input_ch;i++){
+ char buffer[80];
+ GtkWidget *l1=gtk_label_new("attenuation ");
+ GtkWidget *l2=gtk_label_new("delay ");
+ GtkWidget *h=gtk_hseparator_new();
+
+ sprintf(buffer," %d ",i+1);
+ GtkWidget *lN=gtk_label_new(buffer);
+ gtk_widget_set_name(lN,"framelabel");
+
+ sprintf(buffer,"channel/reverb %d VU",i+1);
+ GtkWidget *lV=gtk_label_new(buffer);
+
+ slider_readout_pair *att=calloc(1,sizeof(att));
+ slider_readout_pair *del=calloc(1,sizeof(del));
+
+ atten_panel.master[i]=multibar_new(6,labels_dBn,levels_dBn,0,
+ LO_ATTACK|LO_DECAY|HI_DECAY);
+
+ att->s=multibar_slider_new(11,labels_dB,levels_dB,1);
+ att->r=readout_new("+00.0dB");
+ att->val=&mix_set[i].master_att;
+
+ del->s=multibar_slider_new(6,labels_del,levels_del,1);
+ del->r=readout_new("+00.0ms");
+ del->val=&mix_set[i].master_delay;
+
+ multibar_callback(MULTIBAR(att->s),dB_slider_change,att);
+ multibar_callback(MULTIBAR(del->s),ms_slider_change,del);
+
+ multibar_thumb_set(MULTIBAR(att->s),0,0);
+ multibar_thumb_set(MULTIBAR(del->s),0,0);
+
+ gtk_misc_set_alignment(GTK_MISC(lN),1,.5);
+ gtk_misc_set_alignment(GTK_MISC(l1),1,.5);
+ gtk_misc_set_alignment(GTK_MISC(l2),1,.5);
+
+ gtk_table_attach(GTK_TABLE(table),lN,0,1,0+i*3,2+i*3,
+ 0,0,15,0);
+
+ gtk_table_attach(GTK_TABLE(table),h,0,5,2+i*3,3+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,2);
+
+ gtk_table_attach(GTK_TABLE(table),l1,1,2,0+i*3,1+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),att->s,2,3,0+i*3,1+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),att->r,3,4,0+i*3,1+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),atten_panel.master[i],4,5,0+i*3,1+i*3,
+ GTK_FILL,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),lV,4,5,1+i*3,2+i*3,
+ GTK_FILL,0,0,0);
+
+ gtk_table_attach(GTK_TABLE(table),l2,1,2,1+i*3,2+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),del->s,2,3,1+i*3,2+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ gtk_table_attach(GTK_TABLE(table),del->r,3,4,1+i*3,2+i*3,
+ GTK_FILL|GTK_EXPAND,0,0,0);
+ }
+
+ gtk_box_pack_start(GTK_BOX(panel->subpanel_box),table,1,1,4);
+ subpanel_show_all_but_toplevel(panel);
+}
+
+
+static float **peakfeed=0;
+static float **rmsfeed=0;
+
+void mixpanel_feedback(int displayit){
+ int i,j;
+ if(!peakfeed){
+ peakfeed=malloc(sizeof(*peakfeed)*(MIX_BLOCKS+5));
+ rmsfeed=malloc(sizeof(*rmsfeed)*(MIX_BLOCKS+5));
+
+ for(i=0;i<(MIX_BLOCKS+5);i++){
+ peakfeed[i]=malloc(sizeof(**peakfeed)*input_ch);
+ rmsfeed[i]=malloc(sizeof(**rmsfeed)*input_ch);
+ }
+ }
+
+ if(pull_mix_feedback(peakfeed,rmsfeed)==1){
+ for(j=0;j<input_ch;j++){
+ for(i=0;i<(MIX_BLOCKS+3);i++){
+ float rms[input_ch];
+ float peak[input_ch];
+
+ memset(rms,0,sizeof(rms));
+ memset(peak,0,sizeof(peak));
+
+ switch(i){
+ case 0:
+
+ /* master VU w/reverb display (3 channels) */
+ rms[1]=todB(rmsfeed[0][j])*.5;
+ peak[1]=todB(peakfeed[0][j])*.5;
+ rms[2]=todB(rmsfeed[1][j])*.5;
+ peak[2]=todB(peakfeed[1][j])*.5;
+ rms[3]=todB(rmsfeed[2][j])*.5;
+ peak[3]=todB(peakfeed[2][j])*.5;
+
+ multibar_set(MULTIBAR(atten_panel.master[j]),rms,peak,
+ 3,(displayit && atten_visible));
+ break;
+
+ case 2:
+ case 1:
+
+ rms[j]=todB(rmsfeed[i+2][j])*.5;
+ peak[j]=todB(peakfeed[i+2][j])*.5;
+ multibar_set(MULTIBAR(mix_panels[j]->place[i-1]),rms,peak,
+ input_ch,(displayit && mixpanel_visible[j]));
+ break;
+ default:
+ rms[j]=todB(rmsfeed[i+2][j])*.5;
+ peak[j]=todB(peakfeed[i+2][j])*.5;
+ multibar_set(MULTIBAR(mix_panels[j]->sub[i-3]),rms,peak,
+ input_ch,(displayit && mixpanel_visible[j]));
+ break;
+ }
+ }
+ }
+ }
+}
+
+void mixpanel_reset(void){
+ int i,j;
+
+ for(j=0;j<input_ch;j++){
+ multibar_reset(MULTIBAR(atten_panel.master[j]));
+ multibar_reset(MULTIBAR(mix_panels[j]->place[0]));
+ multibar_reset(MULTIBAR(mix_panels[j]->place[1]));
+
+ for(i=0;i<MIX_BLOCKS;i++)
+ multibar_reset(MULTIBAR(mix_panels[j]->sub[i]));
+
+ }
+}
+
Added: trunk/postfish/mixpanel.h
===================================================================
--- trunk/postfish/mixpanel.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/mixpanel.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -0,0 +1,33 @@
+/*
+ *
+ * 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.
+ *
+ *
+ */
+
+#include "postfish.h"
+
+extern void mixpanel_create_channel(postfish_mainpanel *mp,
+ GtkWidget **windowbutton,
+ GtkWidget **activebutton);
+extern void attenpanel_create(postfish_mainpanel *mp,
+ GtkWidget **windowbutton,
+ GtkWidget **activebutton);
+extern void mixpanel_feedback(int displayit);
+extern void mixpanel_reset(void);
Modified: trunk/postfish/multibar.c
===================================================================
--- trunk/postfish/multibar.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/multibar.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -350,7 +350,7 @@
}
- for(i=0;i<m->labels+1;i++){
+ for(i=0;i<=m->labels;i++){
int x=rint(((float)i)/m->labels*(widget->allocation.width-xpad*2-1))+xpad;
int y=widget->allocation.height-lpad-upad;
int px,py;
@@ -367,17 +367,22 @@
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);
+ pango_layout_get_pixel_size(m->layout[i],&px,&py);
+
+ if(i==0){
+ x+=2;
+ y-=py;
+ y/=2;
+ }else{
x-=px+2;
y-=py;
y/=2;
-
- gdk_draw_layout (m->backing,
- widget->style->text_gc[gc],
- x, y+upad,
- m->layout[i-1]);
}
+ gdk_draw_layout (m->backing,
+ widget->style->text_gc[gc],
+ x, y+upad,
+ m->layout[i]);
+
}
/* draw frame */
@@ -1079,18 +1084,18 @@
/* not the *proper* way to do it, but this is a one-shot */
m->levels=calloc((n+1),sizeof(*m->levels));
- m->labels=n;
- memcpy(m->levels,levels,(n+1)*sizeof(*levels));
+ m->labels=n-1;
+ memcpy(m->levels,levels,n*sizeof(*levels));
- m->layout=calloc(m->labels,sizeof(*m->layout));
- for(i=0;i<m->labels;i++)
+ m->layout=calloc(n,sizeof(*m->layout));
+ for(i=0;i<n;i++)
m->layout[i]=gtk_widget_create_pango_layout(ret,labels[i]);
m->dampen_flags=flags;
m->thumbfocus=-1;
m->thumbgrab=-1;
m->thumblo=levels[0];
- m->thumbhi=levels[n];
+ m->thumbhi=levels[n-1];
m->thumblo_x=val_to_pixel(m,m->thumblo);
m->thumbhi_x=val_to_pixel(m,m->thumbhi);
Modified: trunk/postfish/multicompand.c
===================================================================
--- trunk/postfish/multicompand.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/multicompand.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -69,7 +69,7 @@
float **peak;
float **rms;
-
+ int ch;
} multicompand_state;
multicompand_settings multi_master_set;
@@ -81,17 +81,7 @@
static subband_window sw[multicomp_banks];
static feedback_generic *new_multicompand_feedback(void){
- int i;
multicompand_feedback *ret=calloc(1,sizeof(*ret));
-
- ret->peak=malloc(multicomp_freqs_max*sizeof(*ret->peak));
- for(i=0;i<multicomp_freqs_max;i++)
- ret->peak[i]=malloc(input_ch*sizeof(**ret->peak));
-
- ret->rms=malloc(multicomp_freqs_max*sizeof(*ret->rms));
- for(i=0;i<multicomp_freqs_max;i++)
- ret->rms[i]=malloc(input_ch*sizeof(**ret->rms));
-
return (feedback_generic *)ret;
}
@@ -109,10 +99,10 @@
}else{
if(peak)
for(i=0;i<f->freq_bands;i++)
- memcpy(peak[i],f->peak[i],sizeof(**peak)*input_ch);
+ memcpy(peak[i],f->peak[i],sizeof(**peak)*ms->ch);
if(rms)
for(i=0;i<f->freq_bands;i++)
- memcpy(rms[i],f->rms[i],sizeof(**rms)*input_ch);
+ memcpy(rms[i],f->rms[i],sizeof(**rms)*ms->ch);
if(b)*b=f->freq_bands;
feedback_old(&ms->feedpool,(feedback_generic *)f);
return 1;
@@ -130,7 +120,7 @@
static void reset_filters(multicompand_state *ms){
int i,j;
for(i=0;i<multicomp_freqs_max;i++)
- for(j=0;j<input_ch;j++){
+ for(j=0;j<ms->ch;j++){
memset(&ms->over_peak[i][j],0,sizeof(peak_state));
memset(&ms->under_peak[i][j],0,sizeof(peak_state));
memset(&ms->base_peak[i][j],0,sizeof(peak_state));
@@ -151,44 +141,45 @@
}
-static int multicompand_load_helper(multicompand_state *ms){
+static int multicompand_load_helper(multicompand_state *ms,int ch){
int i;
int qblocksize=input_size/8;
memset(ms,0,sizeof(ms));
- subband_load(&ms->ss,multicomp_freqs_max,qblocksize);
+ ms->ch=ch;
+ subband_load(&ms->ss,multicomp_freqs_max,qblocksize,ch);
- ms->over_attack=calloc(input_ch,sizeof(*ms->over_attack));
- ms->over_decay=calloc(input_ch,sizeof(*ms->over_decay));
+ ms->over_attack=calloc(ms->ch,sizeof(*ms->over_attack));
+ ms->over_decay=calloc(ms->ch,sizeof(*ms->over_decay));
- ms->under_attack=calloc(input_ch,sizeof(*ms->under_attack));
- ms->under_decay=calloc(input_ch,sizeof(*ms->under_decay));
+ ms->under_attack=calloc(ms->ch,sizeof(*ms->under_attack));
+ ms->under_decay=calloc(ms->ch,sizeof(*ms->under_decay));
- ms->base_attack=calloc(input_ch,sizeof(*ms->base_attack));
- ms->base_decay=calloc(input_ch,sizeof(*ms->base_decay));
+ ms->base_attack=calloc(ms->ch,sizeof(*ms->base_attack));
+ ms->base_decay=calloc(ms->ch,sizeof(*ms->base_decay));
for(i=0;i<multicomp_freqs_max;i++){
- ms->over_peak[i]=calloc(input_ch,sizeof(peak_state));
- ms->under_peak[i]=calloc(input_ch,sizeof(peak_state));
- ms->base_peak[i]=calloc(input_ch,sizeof(peak_state));
- ms->over_iir[i]=calloc(input_ch,sizeof(iir_state));
- ms->under_iir[i]=calloc(input_ch,sizeof(iir_state));
- ms->base_iir[i]=calloc(input_ch,sizeof(iir_state));
+ ms->over_peak[i]=calloc(ms->ch,sizeof(peak_state));
+ ms->under_peak[i]=calloc(ms->ch,sizeof(peak_state));
+ ms->base_peak[i]=calloc(ms->ch,sizeof(peak_state));
+ ms->over_iir[i]=calloc(ms->ch,sizeof(iir_state));
+ ms->under_iir[i]=calloc(ms->ch,sizeof(iir_state));
+ ms->base_iir[i]=calloc(ms->ch,sizeof(iir_state));
}
ms->peak=calloc(multicomp_freqs_max,sizeof(*ms->peak));
ms->rms=calloc(multicomp_freqs_max,sizeof(*ms->rms));
- for(i=0;i<multicomp_freqs_max;i++)ms->peak[i]=malloc(input_ch*sizeof(**ms->peak));
- for(i=0;i<multicomp_freqs_max;i++)ms->rms[i]=malloc(input_ch*sizeof(**ms->rms));
+ for(i=0;i<multicomp_freqs_max;i++)ms->peak[i]=malloc(ms->ch*sizeof(**ms->peak));
+ for(i=0;i<multicomp_freqs_max;i++)ms->rms[i]=malloc(ms->ch*sizeof(**ms->rms));
return 0;
}
-int multicompand_load(void){
+int multicompand_load(int outch){
int i;
multi_channel_set=calloc(input_ch,sizeof(*multi_channel_set));
- multicompand_load_helper(&master_state);
- multicompand_load_helper(&channel_state);
+ multicompand_load_helper(&master_state,outch);
+ multicompand_load_helper(&channel_state,input_ch);
for(i=0;i<multicomp_banks;i++)
subband_load_freqs(&master_state.ss,&sw[i],multicomp_freq_list[i],
@@ -221,7 +212,7 @@
iir_filter *filter,
int attackp){
int i;
- for(i=0;i<input_ch;i++)
+ for(i=0;i<ms->ch;i++)
filter_set(ms,msec,filter+i,attackp);
}
@@ -513,10 +504,20 @@
multicompand_feedback *ff=
(multicompand_feedback *)
feedback_new(&ms->feedpool,new_multicompand_feedback);
+
+ if(!ff->peak){
+ ff->peak=malloc(multicomp_freqs_max*sizeof(*ff->peak));
+ ff->rms=malloc(multicomp_freqs_max*sizeof(*ff->rms));
+
+ for(i=0;i<multicomp_freqs_max;i++)
+ ff->rms[i]=malloc(ms->ch*sizeof(**ff->rms));
+ for(i=0;i<multicomp_freqs_max;i++)
+ ff->peak[i]=malloc(ms->ch*sizeof(**ff->peak));
+ }
for(i=0;i<maxmaxbands;i++){
- memcpy(ff->peak[i],ms->peak[i],input_ch*sizeof(**ms->peak));
- memcpy(ff->rms[i],ms->rms[i],input_ch*sizeof(**ms->rms));
+ memcpy(ff->peak[i],ms->peak[i],ms->ch*sizeof(**ms->peak));
+ memcpy(ff->rms[i],ms->rms[i],ms->ch*sizeof(**ms->rms));
}
ff->bypass=0;
ff->freq_bands=maxmaxbands;
@@ -530,13 +531,13 @@
int maxmaxbands=0;
for(i=0;i<multicomp_freqs_max;i++){
- for(j=0;j<input_ch;j++){
+ for(j=0;j<ms->ch;j++){
ms->peak[i][j]=-150.;
ms->rms[i][j]=-150;
}
}
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ms->ch;i++){
int maxbands=find_maxbands(&ms->ss,i);
if(maxbands>maxmaxbands)maxmaxbands=maxbands;
if(multicompand_work_perchannel(ms, ms->peak, ms->rms, maxbands, i, &multi_master_set))
@@ -552,13 +553,13 @@
int maxmaxbands=0;
for(i=0;i<multicomp_freqs_max;i++){
- for(j=0;j<input_ch;j++){
+ for(j=0;j<ms->ch;j++){
ms->peak[i][j]=-150.;
ms->rms[i][j]=-150;
}
}
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ms->ch;i++){
int maxbands=find_maxbands(&ms->ss,i);
if(maxbands>maxmaxbands)maxmaxbands=maxbands;
if(multicompand_work_perchannel(ms, ms->peak, ms->rms, maxbands, i, multi_channel_set+i))
@@ -569,12 +570,13 @@
}
time_linkage *multicompand_read_master(time_linkage *in){
- int visible[input_ch];
- int active[input_ch];
- subband_window *w[input_ch];
+ multicompand_state *ms=&master_state;
+ int visible[ms->ch];
+ int active[ms->ch];
+ subband_window *w[ms->ch];
int i,ab=multi_master_set.active_bank;
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ms->ch;i++){
visible[i]=multi_master_set.panel_visible;
active[i]=multi_master_set.panel_active;
w[i]=&sw[ab];
@@ -609,12 +611,13 @@
}
time_linkage *multicompand_read_channel(time_linkage *in){
- int visible[input_ch];
- int active[input_ch];
- subband_window *w[input_ch];
+ multicompand_state *ms=&channel_state;
+ int visible[ms->ch];
+ int active[ms->ch];
+ subband_window *w[ms->ch];
int i;
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ms->ch;i++){
/* do any filters need updated from UI changes? */
float o_attackms=multi_channel_set[i].over_attack*.1;
Modified: trunk/postfish/multicompand.h
===================================================================
--- trunk/postfish/multicompand.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/multicompand.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -82,7 +82,7 @@
} multicompand_settings;
extern void multicompand_reset();
-extern int multicompand_load(void);
+extern int multicompand_load(int outch);
extern time_linkage *multicompand_read_channel(time_linkage *in);
extern time_linkage *multicompand_read_master(time_linkage *in);
Modified: trunk/postfish/mute.c
===================================================================
--- trunk/postfish/mute.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/mute.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -23,14 +23,13 @@
#include <sys/types.h>
#include "postfish.h"
+#include "mix.h"
#include "mute.h"
-
-sig_atomic_t *mute_active;
extern int input_ch;
+extern sig_atomic_t *mixpanel_active;
int mute_load(void){
- mute_active=calloc(input_ch,sizeof(*mute_active));
return 0;
}
@@ -43,7 +42,7 @@
int i;
for(i=0;i<input_ch;i++)
- if(!mute_active[i])
+ if(mixpanel_active[i])
val|= (1<<i);
in->active=val;
Deleted: trunk/postfish/mutedummy.c
===================================================================
--- trunk/postfish/mutedummy.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/mutedummy.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -1,53 +0,0 @@
-/*
- *
- * 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.
- *
- *
- */
-
-#include "postfish.h"
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include "readout.h"
-#include "multibar.h"
-#include "mainpanel.h"
-#include "mutedummy.h"
-
-extern sig_atomic_t *mute_active;
-extern int input_ch;
-
-static int activebutton_action(GtkWidget *widget,gpointer in){
- int num=(int)in;
- int active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- mute_active[num]=active;
-
- return FALSE;
-}
-
-void mutedummy_create(postfish_mainpanel *mp,
- GtkWidget **windowbutton,
- GtkWidget **activebutton){
- int i;
-
- /* nothing to do here but slap an activation callback on each activebutton */
- for(i=0;i<input_ch;i++)
- g_signal_connect_after (G_OBJECT (activebutton[i]), "clicked",
- G_CALLBACK (activebutton_action), (gpointer)i);
-
-}
Modified: trunk/postfish/output.c
===================================================================
--- trunk/postfish/output.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/output.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -35,8 +35,10 @@
#include "suppress.h"
#include "limit.h"
#include "mute.h"
+#include "mix.h"
extern int input_size;
+extern int input_rate;
sig_atomic_t playback_active=0;
sig_atomic_t playback_exit=0;
sig_atomic_t playback_seeking=0;
@@ -64,6 +66,7 @@
suppress_reset(); /* clear any persistent lapping state */
limit_reset(); /* clear any persistent lapping state */
output_reset(); /* clear any persistent lapping state */
+ mix_reset();
}
typedef struct output_feedback{
@@ -247,6 +250,9 @@
link=eq_read_channel(link);
result|=link->samples;
+ link=mix_read(link,0,0);
+ result|=link->samples;
+
link=multicompand_read_master(link);
result|=link->samples;
link=singlecomp_read_master(link);
@@ -267,11 +273,6 @@
}
- /* the limiter is single-block zero additional latency */
- for(i=0;i<input_ch;i++)
- if(mute_channel_muted(link->active,i))
- memset(link->data[i],0,sizeof(**link->data)*input_size);
-
link=limit_read(link);
/************/
@@ -281,7 +282,10 @@
memset(rms,0,sizeof(*rms)*(input_ch+2));
memset(peak,0,sizeof(*peak)*(input_ch+2));
ch=link->channels;
- rate=link->rate;
+ rate=input_rate;
+
+ /* temporary! */
+ if(ch>2)ch=2;
/* lazy playbak setup; we couldn't do it until we had rate and
channel information from the pipeline */
@@ -295,8 +299,8 @@
setupp=1;
}
- if(audiobufsize<link->channels*link->samples*outbytes){
- audiobufsize=link->channels*link->samples*outbytes;
+ if(audiobufsize<ch*link->samples*outbytes){
+ audiobufsize=ch*link->samples*outbytes;
if(audiobuf)
audiobuf=realloc(audiobuf,sizeof(*audiobuf)*audiobufsize);
else
@@ -309,7 +313,7 @@
float mean=0.;
float divrms=0.;
- for(j=0;j<link->channels;j++){
+ for(j=0;j<ch;j++){
float dval=link->data[j][i];
switch(outbytes){
@@ -358,12 +362,12 @@
rms[input_ch]+= mean*mean;
/* div */
- for(j=0;j<link->channels;j++){
+ for(j=0;j<ch;j++){
float dval=mean-link->data[j][i];
if(fabs(dval)>peak[input_ch+1])peak[input_ch+1]=fabs(dval);
divrms+=dval*dval;
}
- rms[input_ch+1]+=divrms/link->channels;
+ rms[input_ch+1]+=divrms/ch;
}
@@ -372,7 +376,7 @@
rms[j]=sqrt(rms[j]);
}
- count+=fwrite(audiobuf,1,link->channels*link->samples*outbytes,playback_fd);
+ count+=fwrite(audiobuf,1,ch*link->samples*outbytes,playback_fd);
/* inform Lord Vader his shuttle is ready */
push_output_feedback(peak,rms);
Modified: trunk/postfish/postfish.h
===================================================================
--- trunk/postfish/postfish.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/postfish.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -50,6 +50,8 @@
#include <signal.h>
#include <fcntl.h>
+#define OUTPUT_CHANNELS 6
+
static inline float todB(float x){
return logf((x)*(x)+1e-30f)*4.34294480f;
}
@@ -65,7 +67,7 @@
}
static inline float fromdB_a(float x){
- int y=1.39331762961e+06f*(x+764.6161886f);
+ int y=1.39331762961e+06f*((x<-400?-400:x)+764.6161886f);
return *(float *)&y;
}
@@ -81,16 +83,19 @@
#endif
+#ifndef max
+#define max(x,y) ((x)>(y)?(x):(y))
+#endif
+
+
#define toOC(n) (log(n)*1.442695f-5.965784f)
#define fromOC(o) (exp(((o)+5.965784f)*.693147f))
#define toBark(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
#define fromBark(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f)
typedef struct time_linkage {
- int size;
int samples; /* normally same as size; exception is EOF */
int channels;
- int rate;
float **data;
u_int32_t active; /* active channel bitmask */
} time_linkage;
Added: trunk/postfish/reverb.c
===================================================================
--- trunk/postfish/reverb.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/reverb.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -0,0 +1,409 @@
+/*
+ *
+ * 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.
+ *
+ *
+ */
+
+/* The plate reverb implementation in this file is originally the work
+ of Steve Harris, released under the GPL2 as part of the SWH plugins
+ package. In the interests of proper attribution, the 'AUTHORS' file
+ from SWH is reproduced here:
+
+ "[Authors] In no particular order:
+
+ Steve Harris - general stuff
+ Frank Neumann - documentation, proofreading, DSP code
+ Juhana Sadeharju - DSP code
+ Joern Nettingsmeier - DSP code, bug reports and inspiration
+ Mark Knecht - testesting, docuementation
+ Pascal Haakmat - bugfixes, testing
+ Marcus Andersson - DSP code
+ Paul Winkler - documentation
+ Matthias Nagorni - testing, inspiration
+ Nathaniel Virgo - bugfixes
+ Patrick Shirkey - testing, inspiration
+
+ Project maintainted by Steve Harris, Southampton UK.
+ steve at plugin.org.uk or swh at ecs.soton.ac.uk
+
+ Plugin website at http://plugin.org.uk/" */
+
+#include "postfish.h"
+#include "reverb.h"
+
+typedef struct {
+ int size;
+ float *buffer[2];
+ int ptr;
+ int delay;
+ float fc;
+ float lp[2];
+ float a1a;
+ float a1b;
+ float zm1[2];
+} waveguide_nl;
+
+typedef struct {
+ float *outbuffer;
+ waveguide_nl w[8];
+} plate;
+
+typedef struct {
+ time_linkage out;
+ time_linkage outA;
+ time_linkage outB;
+
+ plate *plates;
+ int *prevactive;
+ int fillstate;
+} plate_state;
+
+extern int input_size;
+extern int input_ch;
+
+extern float *frame_window;
+plate_set *plate_channel_set;
+plate_set plate_master_set;
+
+static plate_state channel;
+static plate_state master;
+
+/* linear waveguide model */
+
+static void waveguide_init(waveguide_nl *wg,
+ int size, float fc, float da, float db){
+ wg->size = size;
+ wg->delay = size;
+ wg->buffer[0] = calloc(size, sizeof(float));
+ wg->buffer[1] = calloc(size, sizeof(float));
+ wg->ptr = 0;
+ wg->fc = fc;
+ wg->lp[0] = 0.0f;
+ wg->lp[1] = 0.0f;
+ wg->zm1[0] = 0.0f;
+ wg->zm1[1] = 0.0f;
+ wg->a1a = (1.0f - da) / (1.0f + da);
+ wg->a1b = (1.0f - db) / (1.0f + db);
+}
+
+static void waveguide_nl_reset(waveguide_nl *wg){
+ memset(wg->buffer[0], 0, wg->size * sizeof(float));
+ memset(wg->buffer[1], 0, wg->size * sizeof(float));
+ wg->lp[0] = 0.0f;
+ wg->lp[1] = 0.0f;
+ wg->zm1[0] = 0.0f;
+ wg->zm1[1] = 0.0f;
+}
+
+static void waveguide_nl_set_delay(waveguide_nl *wg, int delay){
+ if (delay > wg->size) {
+ wg->delay = wg->size;
+ } else if (delay < 1) {
+ wg->delay = 1;
+ } else {
+ wg->delay = delay;
+ }
+}
+
+static void waveguide_nl_set_fc(waveguide_nl *wg, float fc){
+ wg->fc = fc;
+}
+
+static void waveguide_nl_process_lin(waveguide_nl *wg, float in0, float in1,
+ float *out0, float *out1){
+ float tmp;
+
+ *out0 = wg->buffer[0][(wg->ptr + wg->delay) % wg->size];
+ *out0 = wg->lp[0] * (wg->fc - 1.0f) + wg->fc * *out0;
+ wg->lp[0] = *out0;
+ tmp = *out0 * -(wg->a1a) + wg->zm1[0];
+ wg->zm1[0] = tmp * wg->a1a + *out0;
+ *out0 = tmp;
+
+ *out1 = wg->buffer[1][(wg->ptr + wg->delay) % wg->size];
+ *out1 = wg->lp[1] * (wg->fc - 1.0f) + wg->fc * *out1;
+ wg->lp[1] = *out1;
+ tmp = *out1 * -(wg->a1a) + wg->zm1[1];
+ wg->zm1[1] = tmp * wg->a1a + *out1;
+ *out1 = tmp;
+
+ wg->buffer[0][wg->ptr] = in0;
+ wg->buffer[1][wg->ptr] = in1;
+ wg->ptr--;
+ if (wg->ptr < 0) wg->ptr += wg->size;
+}
+
+/* model the plate reverb as a set of eight linear waveguides */
+
+#define LP_INNER 0.96f
+#define LP_OUTER 0.983f
+
+#define RUN_WG(n, junct_a, junct_b) waveguide_nl_process_lin(&w[n], junct_a - out[n*2+1], junct_b - out[n*2], out+n*2, out+n*2+1)
+
+static void plate_reset_helper(plate_state *ps){
+ int i,j;
+
+ for(i=0;i<ps->out.channels;i++){
+ for (j = 0; j < 8; j++)
+ waveguide_nl_reset(&ps->plates[i].w[j]);
+ memset(ps->plates[i].outbuffer,0,
+ 32*sizeof(*ps->plates[i].outbuffer));
+ }
+ ps->fillstate=0;
+}
+
+void plate_reset(void){
+ plate_reset_helper(&master);
+ plate_reset_helper(&channel);
+}
+
+static void plate_init(plate *p){
+ memset(p,0,sizeof(*p));
+ p->outbuffer = calloc(32, sizeof(*p->outbuffer));
+
+ waveguide_init(&p->w[0], 2389, LP_INNER, 0.04f, 0.0f);
+ waveguide_init(&p->w[1], 4742, LP_INNER, 0.17f, 0.0f);
+ waveguide_init(&p->w[2], 4623, LP_INNER, 0.52f, 0.0f);
+ waveguide_init(&p->w[3], 2142, LP_INNER, 0.48f, 0.0f);
+ waveguide_init(&p->w[4], 5597, LP_OUTER, 0.32f, 0.0f);
+ waveguide_init(&p->w[5], 3692, LP_OUTER, 0.89f, 0.0f);
+ waveguide_init(&p->w[6], 5611, LP_OUTER, 0.28f, 0.0f);
+ waveguide_init(&p->w[7], 3703, LP_OUTER, 0.29f, 0.0f);
+
+}
+
+int plate_load(int outch){
+ int i;
+
+ /* setting storage */
+ memset(&plate_master_set,0,sizeof(plate_master_set));
+ plate_channel_set=calloc(input_ch,sizeof(*plate_channel_set));
+
+ /* output linkages for master and channels */
+
+ master.out.channels=outch;
+ master.out.data=malloc(outch*sizeof(*master.out.data));
+ for(i=0;i<outch;i++)
+ master.out.data[i]=malloc(input_size*sizeof(**master.out.data));
+
+ channel.out.channels=input_ch;
+ channel.outA.channels=input_ch;
+ channel.outB.channels=input_ch;
+ channel.out.data=malloc(input_ch*sizeof(*channel.out.data));
+ channel.outA.data=malloc(input_ch*sizeof(*channel.outA.data));
+ channel.outB.data=malloc(input_ch*sizeof(*channel.outB.data));
+ for(i=0;i<input_ch;i++){
+ channel.out.data[i]=malloc(input_size*sizeof(**master.out.data));
+ channel.outA.data[i]=malloc(input_size*sizeof(**master.outA.data));
+ channel.outB.data[i]=malloc(input_size*sizeof(**master.outB.data));
+ }
+
+ /* allocate/initialize plates */
+ channel.plates=calloc(input_ch,sizeof(*channel.plates));
+ for(i=0;i<input_ch;i++)
+ plate_init(&channel.plates[i]);
+
+ master.plates=calloc(outch,sizeof(*master.plates));
+ for(i=0;i<outch;i++)
+ plate_init(&master.plates[i]);
+
+ channel.prevactive=calloc(input_ch,sizeof(*channel.prevactive));
+ master.prevactive=calloc(1,sizeof(*master.prevactive));
+ return 0;
+}
+
+static void plate_compute(plate_set *p, plate *ps, float *in,
+ float *outA, float *outB, float *outC,
+ int count){
+
+ waveguide_nl *w = ps->w;
+ float *out=ps->outbuffer;
+
+ int pos;
+ const float scale = powf(p->time*.0009999f, 1.34f);
+ const float lpscale = 1.0f - p->damping*.001f * 0.93f;
+ const float wet = p->wet*.001f;
+
+ /* waveguide reconfig */
+ for (pos=0; pos<8; pos++)
+ waveguide_nl_set_delay(&w[pos], w[pos].size * scale);
+ for (pos=0; pos<4; pos++)
+ waveguide_nl_set_fc(&w[pos], LP_INNER * lpscale);
+ for (; pos<8; pos++)
+ waveguide_nl_set_fc(&w[pos], LP_OUTER * lpscale);
+
+ for (pos = 0; pos < count; pos++) {
+ const float alpha = (out[0] + out[2] + out[4] + out[6]) * 0.5f + in[pos];
+ const float beta = (out[1] + out[9] + out[14]) * 0.666666666f;
+ const float gamma = (out[3] + out[8] + out[11]) * 0.666666666f;
+ const float delta = (out[5] + out[10] + out[13]) * 0.666666666f;
+ const float epsilon = (out[7] + out[12] + out[15]) * 0.666666666f;
+
+ RUN_WG(0, beta, alpha);
+ RUN_WG(1, gamma, alpha);
+ RUN_WG(2, delta, alpha);
+ RUN_WG(3, epsilon, alpha);
+ RUN_WG(4, beta, gamma);
+ RUN_WG(5, gamma, delta);
+ RUN_WG(6, delta, epsilon);
+ RUN_WG(7, epsilon, beta);
+
+ if(!outB || !outC){
+ outA[pos]=in[pos] * (1.0f - wet) + beta * wet;
+ }else{
+ outA[pos]=in[pos] * (1.0f - wet);
+ outB[pos]= beta * wet;
+ outC[pos]= gamma * wet;
+ }
+ }
+}
+
+time_linkage *plate_read_channel(time_linkage *in,
+ time_linkage **revA,
+ time_linkage **revB){
+ int i,j,ch=in->channels;
+ plate_state *ps=&channel;
+
+ *revA=&ps->outA;
+ *revB=&ps->outB;
+
+ if(in->samples==0){
+ ps->out.samples=0;
+ ps->outA.samples=0;
+ ps->outB.samples=0;
+ }
+
+ ps->outA.active=0;
+ ps->outB.active=0;
+
+ if(ps->fillstate==0){
+ for(i=0;i<ch;i++)
+ ps->prevactive[i]=plate_channel_set[i].panel_active;
+ ps->fillstate=1;
+ }
+
+ for(i=0;i<ch;i++){
+ if(plate_channel_set[i].panel_active || ps->prevactive[i]){
+ float *x=in->data[i];
+ float *y=ps->out.data[i];
+ float *yA=ps->outA.data[i];
+ float *yB=ps->outB.data[i];
+
+ /* clear the waveguides of old state if they were inactive */
+ if (!ps->prevactive[i]){
+ for (j = 0; j < 8; j++)
+ waveguide_nl_reset(&ps->plates[i].w[j]);
+ memset(ps->plates[i].outbuffer,0,
+ 32*sizeof(*ps->plates[i].outbuffer));
+ }
+
+ /* process this plate */
+ plate_compute(&plate_channel_set[i], &ps->plates[i],
+ x,y,yA,yB,input_size);
+
+ if(!plate_channel_set[i].panel_active){
+ /* transition to inactive */
+ for(j=0;j<input_ch;j++){
+ y[j]= y[j]*(1.f - frame_window[j]) + x[j] * frame_window[j];
+ yA[j]= yA[j]*(1.f - frame_window[j]);
+ yB[j]= yB[j]*(1.f - frame_window[j]);
+ }
+
+ }else if (!ps->prevactive[i]){
+ /* transition to active */
+ for(j=0;j<input_ch;j++){
+ y[j]= y[j]* frame_window[j] + x[j] * (1. - frame_window[j]);
+ yA[j]= yA[j]* frame_window[j];
+ yB[j]= yB[j]* frame_window[j];
+ }
+ }
+ ps->outA.active |= 1<<i;
+ ps->outB.active |= 1<<i;
+
+ }else{
+ /* fully inactive */
+ float *temp=ps->out.data[i];
+ ps->out.data[i]=in->data[i];
+ in->data[i]=temp;
+ }
+ ps->prevactive[i]=plate_channel_set[i].panel_active;
+ }
+
+ ps->out.active=in->active;
+ ps->out.samples=in->samples;
+ ps->outA.samples=in->samples;
+ ps->outB.samples=in->samples;
+ return &ps->out;
+}
+
+time_linkage *plate_read_master(time_linkage *in){
+ int i,j,ch=in->channels;
+ plate_state *ps=&master;
+
+ if(in->samples==0){
+ ps->out.samples=0;
+ }
+
+ if(ps->fillstate==0){
+ ps->prevactive[0]=plate_master_set.panel_active;
+ ps->fillstate=1;
+ }
+
+ for(i=0;i<ch;i++){
+ if(plate_master_set.panel_active || ps->prevactive[0]){
+ float *x=in->data[i];
+ float *y=ps->out.data[i];
+
+ /* clear the waveguides of old state if they were inactive */
+ if (!ps->prevactive[0]){
+ for (j = 0; j < 8; j++)
+ waveguide_nl_reset(&ps->plates[i].w[j]);
+ memset(ps->plates[i].outbuffer,0,
+ 32*sizeof(*ps->plates[i].outbuffer));
+ }
+
+ /* process this plate */
+ plate_compute(&plate_master_set, &ps->plates[i],
+ x,y,0,0,input_size);
+
+ if(!plate_master_set.panel_active){
+ /* transition to inactive */
+ for(j=0;j<input_ch;j++)
+ y[j]= y[j]*(1.f - frame_window[j]) + x[j] * frame_window[j];
+
+ }else if (!ps->prevactive[0]){
+ /* transition to active */
+ for(j=0;j<input_ch;j++)
+ y[j]= y[j]* frame_window[j] + x[j] * (1. - frame_window[j]);
+
+ }
+ }else{
+ /* fully inactive */
+ float *temp=ps->out.data[i];
+ ps->out.data[i]=in->data[i];
+ in->data[i]=temp;
+ }
+ }
+ ps->prevactive[0]=plate_master_set.panel_active;
+
+ ps->out.active=in->active;
+ ps->out.samples=in->samples;
+ return &ps->out;
+}
Added: trunk/postfish/reverb.h
===================================================================
--- trunk/postfish/reverb.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/reverb.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -0,0 +1,38 @@
+/*
+ *
+ * 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.
+ *
+ *
+ */
+
+typedef struct {
+ sig_atomic_t panel_active;
+ sig_atomic_t panel_visible;
+
+ sig_atomic_t time; /* 1-1000 */
+ sig_atomic_t damping; /* 0.-1. * 1000 */
+ sig_atomic_t wet; /* 0.-1. * 1000 */
+} plate_set;
+
+extern void plate_reset(void);
+extern int plate_load(int outch);
+extern time_linkage *plate_read_channel(time_linkage *in,
+ time_linkage **revA,
+ time_linkage **revB);
+extern time_linkage *plate_read_master(time_linkage *in);
Modified: trunk/postfish/singlecomp.c
===================================================================
--- trunk/postfish/singlecomp.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/singlecomp.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -63,10 +63,10 @@
int mutemaskP;
int mutemask0;
-
+ int ch;
} singlecomp_state;
-float *window;
+static float *window;
singlecomp_settings singlecomp_master_set;
singlecomp_settings *singlecomp_channel_set;
@@ -95,9 +95,9 @@
if(!f)return 0;
if(peak)
- memcpy(peak,f->peak,sizeof(*peak)*input_ch);
+ memcpy(peak,f->peak,sizeof(*peak)*scs->ch);
if(rms)
- memcpy(rms,f->rms,sizeof(*rms)*input_ch);
+ memcpy(rms,f->rms,sizeof(*rms)*scs->ch);
feedback_old(&scs->feedpool,(feedback_generic *)f);
return 1;
}
@@ -110,47 +110,46 @@
return pull_singlecomp_feedback(&channel_state,peak,rms);
}
-static void singlecomp_load_helper(singlecomp_state *scs){
+static void singlecomp_load_helper(singlecomp_state *scs,int ch){
int i;
memset(scs,0,sizeof(scs));
- scs->activeP=calloc(input_ch,sizeof(*scs->activeP));
- scs->active0=calloc(input_ch,sizeof(*scs->active0));
+ scs->ch=ch;
+ scs->activeP=calloc(scs->ch,sizeof(*scs->activeP));
+ scs->active0=calloc(scs->ch,sizeof(*scs->active0));
- scs->o_attack=calloc(input_ch,sizeof(*scs->o_attack));
- scs->o_decay=calloc(input_ch,sizeof(*scs->o_decay));
- scs->u_attack=calloc(input_ch,sizeof(*scs->u_attack));
- scs->u_decay=calloc(input_ch,sizeof(*scs->u_decay));
- scs->b_attack=calloc(input_ch,sizeof(*scs->b_attack));
- scs->b_decay=calloc(input_ch,sizeof(*scs->b_decay));
+ scs->o_attack=calloc(scs->ch,sizeof(*scs->o_attack));
+ scs->o_decay=calloc(scs->ch,sizeof(*scs->o_decay));
+ scs->u_attack=calloc(scs->ch,sizeof(*scs->u_attack));
+ scs->u_decay=calloc(scs->ch,sizeof(*scs->u_decay));
+ scs->b_attack=calloc(scs->ch,sizeof(*scs->b_attack));
+ scs->b_decay=calloc(scs->ch,sizeof(*scs->b_decay));
- scs->o_iir=calloc(input_ch,sizeof(*scs->o_iir));
- scs->b_iir=calloc(input_ch,sizeof(*scs->b_iir));
- scs->u_iir=calloc(input_ch,sizeof(*scs->u_iir));
+ scs->o_iir=calloc(scs->ch,sizeof(*scs->o_iir));
+ scs->b_iir=calloc(scs->ch,sizeof(*scs->b_iir));
+ scs->u_iir=calloc(scs->ch,sizeof(*scs->u_iir));
- scs->o_peak=calloc(input_ch,sizeof(*scs->o_peak));
- scs->b_peak=calloc(input_ch,sizeof(*scs->b_peak));
- scs->u_peak=calloc(input_ch,sizeof(*scs->u_peak));
+ scs->o_peak=calloc(scs->ch,sizeof(*scs->o_peak));
+ scs->b_peak=calloc(scs->ch,sizeof(*scs->b_peak));
+ scs->u_peak=calloc(scs->ch,sizeof(*scs->u_peak));
- scs->out.size=input_size;
- scs->out.channels=input_ch;
- scs->out.rate=input_rate;
- scs->out.data=malloc(input_ch*sizeof(*scs->out.data));
- for(i=0;i<input_ch;i++)
+ scs->out.channels=scs->ch;
+ scs->out.data=malloc(scs->ch*sizeof(*scs->out.data));
+ for(i=0;i<scs->ch;i++)
scs->out.data[i]=malloc(input_size*sizeof(**scs->out.data));
scs->fillstate=0;
- scs->cache=malloc(input_ch*sizeof(*scs->cache));
- for(i=0;i<input_ch;i++)
+ scs->cache=malloc(scs->ch*sizeof(*scs->cache));
+ for(i=0;i<scs->ch;i++)
scs->cache[i]=malloc(input_size*sizeof(**scs->cache));
}
/* called only by initial setup */
-int singlecomp_load(void){
+int singlecomp_load(int outch){
int i;
- singlecomp_load_helper(&master_state);
- singlecomp_load_helper(&channel_state);
+ singlecomp_load_helper(&master_state,outch);
+ singlecomp_load_helper(&channel_state,input_ch);
window=malloc(input_size/2*sizeof(*window));
for(i=0;i<input_size/2;i++){
@@ -159,12 +158,12 @@
}
singlecomp_channel_set=calloc(input_ch,sizeof(*singlecomp_channel_set));
- master_set_bundle=malloc(input_ch*sizeof(*master_set_bundle));
+ master_set_bundle=malloc(outch*sizeof(*master_set_bundle));
channel_set_bundle=malloc(input_ch*sizeof(*channel_set_bundle));
- for(i=0;i<input_ch;i++){
- master_set_bundle[i]=&singlecomp_master_set;
+ for(i=0;i<input_ch;i++)
channel_set_bundle[i]=&singlecomp_channel_set[i];
- }
+ for(i=0;i<outch;i++)
+ master_set_bundle[i]=&singlecomp_master_set;
return 0;
}
@@ -188,12 +187,12 @@
}
static void reset_filter(singlecomp_state *scs){
- memset(scs->o_peak,0,input_ch*sizeof(&scs->o_peak));
- memset(scs->u_peak,0,input_ch*sizeof(&scs->u_peak));
- memset(scs->b_peak,0,input_ch*sizeof(&scs->b_peak));
- memset(scs->o_iir,0,input_ch*sizeof(&scs->o_iir));
- memset(scs->u_iir,0,input_ch*sizeof(&scs->u_iir));
- memset(scs->b_iir,0,input_ch*sizeof(&scs->b_iir));
+ memset(scs->o_peak,0,scs->ch*sizeof(&scs->o_peak));
+ memset(scs->u_peak,0,scs->ch*sizeof(&scs->u_peak));
+ memset(scs->b_peak,0,scs->ch*sizeof(&scs->b_peak));
+ memset(scs->o_iir,0,scs->ch*sizeof(&scs->o_iir));
+ memset(scs->u_iir,0,scs->ch*sizeof(&scs->u_iir));
+ memset(scs->b_iir,0,scs->ch*sizeof(&scs->b_iir));
}
/* called only in playback thread */
@@ -374,12 +373,12 @@
u_int32_t mutemask0=scs->mutemask0;
u_int32_t mutemaskP=scs->mutemaskP;
- float peakfeed[input_ch];
- float rmsfeed[input_ch];
+ float peakfeed[scs->ch];
+ float rmsfeed[scs->ch];
memset(peakfeed,0,sizeof(peakfeed));
memset(rmsfeed,0,sizeof(rmsfeed));
- for(i=0;i<input_ch;i++){
+ for(i=0;i<scs->ch;i++){
int activeC= active[i] && !mute_channel_muted(mutemaskC,i);
int active0= scs->active0[i];
@@ -551,10 +550,10 @@
(singlecomp_feedback *)feedback_new(&scs->feedpool,new_singlecomp_feedback);
if(!ff->peak)
- ff->peak=malloc(input_ch*sizeof(*ff->peak));
+ ff->peak=malloc(scs->ch*sizeof(*ff->peak));
if(!ff->rms)
- ff->rms=malloc(input_ch*sizeof(*ff->rms));
+ ff->rms=malloc(scs->ch*sizeof(*ff->rms));
memcpy(ff->peak,peakfeed,sizeof(peakfeed));
memcpy(ff->rms,rmsfeed,sizeof(rmsfeed));
@@ -583,7 +582,7 @@
return &scs->out;
}
- for(i=0;i<input_ch;i++){
+ for(i=0;i<scs->ch;i++){
memset(scs->o_iir+i,0,sizeof(*scs->o_iir));
memset(scs->u_iir+i,0,sizeof(*scs->u_iir));
memset(scs->b_iir+i,0,sizeof(*scs->b_iir));
@@ -599,17 +598,17 @@
scs->fillstate=1;
scs->out.samples=0;
- if(in->samples==in->size)goto tidy_up;
+ if(in->samples==input_size)goto tidy_up;
- for(i=0;i<input_ch;i++)
- memset(in->data[i],0,sizeof(**in->data)*in->size);
+ for(i=0;i<scs->ch;i++)
+ memset(in->data[i],0,sizeof(**in->data)*input_size);
in->samples=0;
/* fall through */
case 1: /* nominal processing */
work_and_lapping(scs,scset,in,&scs->out,active);
- if(scs->out.samples<scs->out.size)scs->fillstate=2;
+ if(scs->out.samples<input_size)scs->fillstate=2;
break;
case 2: /* we've pushed out EOF already */
scs->out.samples=0;
@@ -617,7 +616,7 @@
tidy_up:
{
- int tozero=scs->out.size-scs->out.samples;
+ int tozero=input_size-scs->out.samples;
if(tozero)
for(i=0;i<scs->out.channels;i++)
memset(scs->out.data[i]+scs->out.samples,0,sizeof(**scs->out.data)*tozero);
@@ -627,20 +626,20 @@
}
time_linkage *singlecomp_read_master(time_linkage *in){
- int active[input_ch],i;
+ int active[master_state.ch],i;
/* local copy required to avoid concurrency problems */
- for(i=0;i<input_ch;i++)
+ for(i=0;i<master_state.ch;i++)
active[i]=singlecomp_master_set.panel_active;
return singlecomp_read_helper(in, &master_state, master_set_bundle,active);
}
time_linkage *singlecomp_read_channel(time_linkage *in){
- int active[input_ch],i;
+ int active[channel_state.ch],i;
/* local copy required to avoid concurrency problems */
- for(i=0;i<input_ch;i++)
+ for(i=0;i<channel_state.ch;i++)
active[i]=singlecomp_channel_set[i].panel_active;
return singlecomp_read_helper(in, &channel_state, channel_set_bundle,active);
Modified: trunk/postfish/singlecomp.h
===================================================================
--- trunk/postfish/singlecomp.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/singlecomp.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -52,7 +52,7 @@
extern int pull_singlecomp_feedback_master(float *peak,float *rms);
extern int pull_singlecomp_feedback_channel(float *peak,float *rms);
-extern int singlecomp_load(void);
+extern int singlecomp_load(int ch);
extern int singlecomp_reset(void);
extern time_linkage *singlecomp_read_master(time_linkage *in);
extern time_linkage *singlecomp_read_channel(time_linkage *in);
Modified: trunk/postfish/singlepanel.c
===================================================================
--- trunk/postfish/singlepanel.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/singlepanel.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -186,19 +186,19 @@
subpanel_generic *panel,
singlecomp_settings *scset){
- char *labels[14]={"130","120","110","100","90","80","70",
+ char *labels[15]={"","130","120","110","100","90","80","70",
"60","50","40","30","20","10","0"};
float levels[15]={-140,-130,-120,-110,-100,-90,-80,-70,-60,-50,-40,
-30,-20,-10,0};
float compand_levels[9]={.1,.25,.5,.6667,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"};
+ char *compand_labels[9]={"","4:1","2:1","1:1.5","1:1","1:1.5","1:2","1:4","1:10"};
float timing_levels[6]={.5,1,10,100,1000,10000};
- char *timing_labels[5]={"1ms","10ms","100ms","1s","10s"};
+ char *timing_labels[6]={"","1ms","10ms","100ms","1s","10s"};
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%"};
+ char *per_labels[9]={"0%","","25%","","50%","","75%","","100%"};
singlecomp_panel_state *ps=calloc(1,sizeof(singlecomp_panel_state));
ps->ms=scset;
@@ -300,7 +300,7 @@
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);
+ GtkWidget *slider=multibar_slider_new(9,compand_labels,compand_levels,1);
ps->under_compand.r=READOUT(readout);
ps->under_compand.v=&ps->ms->u_ratio;
@@ -323,7 +323,7 @@
GtkWidget *label=gtk_label_new("attack/decay:");
GtkWidget *readout0=readout_new(" 100ms");
GtkWidget *readout1=readout_new(" 100ms");
- GtkWidget *slider=multibar_slider_new(5,timing_labels,timing_levels,2);
+ GtkWidget *slider=multibar_slider_new(6,timing_labels,timing_levels,2);
ps->under_timing.r0=READOUT(readout0);
ps->under_timing.r1=READOUT(readout1);
@@ -349,7 +349,7 @@
GtkWidget *label=gtk_label_new("lookahead:");
GtkWidget *readout=readout_new("100%");
- GtkWidget *slider=multibar_slider_new(8,per_labels,per_levels,1);
+ GtkWidget *slider=multibar_slider_new(9,per_labels,per_levels,1);
ps->under_lookahead.r=READOUT(readout);
ps->under_lookahead.v=&ps->ms->u_lookahead;
@@ -397,7 +397,7 @@
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);
+ GtkWidget *slider=multibar_slider_new(9,compand_labels,compand_levels,1);
ps->over_compand.r=READOUT(readout);
ps->over_compand.v=&ps->ms->o_ratio;
@@ -420,7 +420,7 @@
GtkWidget *label=gtk_label_new("attack/decay:");
GtkWidget *readout0=readout_new(" 100ms");
GtkWidget *readout1=readout_new(" 100ms");
- GtkWidget *slider=multibar_slider_new(5,timing_labels,timing_levels,2);
+ GtkWidget *slider=multibar_slider_new(6,timing_labels,timing_levels,2);
ps->over_timing.r0=READOUT(readout0);
ps->over_timing.r1=READOUT(readout1);
@@ -446,7 +446,7 @@
GtkWidget *label=gtk_label_new("lookahead:");
GtkWidget *readout=readout_new("100%");
- GtkWidget *slider=multibar_slider_new(8,per_labels,per_levels,1);
+ GtkWidget *slider=multibar_slider_new(9,per_labels,per_levels,1);
ps->over_lookahead.r=READOUT(readout);
ps->over_lookahead.v=&ps->ms->o_lookahead;
@@ -490,7 +490,7 @@
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);
+ GtkWidget *slider=multibar_slider_new(9,compand_labels,compand_levels,1);
ps->base_compand.r=READOUT(readout);
ps->base_compand.v=&ps->ms->b_ratio;
@@ -513,7 +513,7 @@
GtkWidget *label=gtk_label_new("attack/decay:");
GtkWidget *readout0=readout_new(" 100ms");
GtkWidget *readout1=readout_new(" 100ms");
- GtkWidget *slider=multibar_slider_new(5,timing_labels,timing_levels,2);
+ GtkWidget *slider=multibar_slider_new(6,timing_labels,timing_levels,2);
ps->base_timing.r0=READOUT(readout0);
ps->base_timing.r1=READOUT(readout1);
@@ -539,7 +539,7 @@
{
ps->bar.readoutu=readout_new(" +0");
ps->bar.readouto=readout_new(" +0");
- ps->bar.slider=multibar_new(14,labels,levels,2,HI_DECAY|LO_DECAY|LO_ATTACK);
+ ps->bar.slider=multibar_new(15,labels,levels,2,HI_DECAY|LO_DECAY|LO_ATTACK);
ps->bar.vu=&ps->ms->u_thresh;
ps->bar.vo=&ps->ms->o_thresh;
@@ -569,13 +569,13 @@
void singlepanel_feedback(int displayit){
int j;
if(!peakfeed){
- peakfeed=malloc(sizeof(*peakfeed)*input_ch);
- rmsfeed=malloc(sizeof(*rmsfeed)*input_ch);
+ peakfeed=malloc(sizeof(*peakfeed)*max(input_ch,OUTPUT_CHANNELS));
+ rmsfeed=malloc(sizeof(*rmsfeed)*max(input_ch,OUTPUT_CHANNELS));
}
if(pull_singlecomp_feedback_master(peakfeed,rmsfeed)==1)
multibar_set(MULTIBAR(master_panel->bar.slider),rmsfeed,peakfeed,
- input_ch,(displayit && singlecomp_master_set.panel_visible));
+ OUTPUT_CHANNELS,(displayit && singlecomp_master_set.panel_visible));
/* channel panels are a bit different; we want each in its native color */
if(pull_singlecomp_feedback_channel(peakfeed,rmsfeed)==1){
Modified: trunk/postfish/subband.c
===================================================================
--- trunk/postfish/subband.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/subband.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -28,10 +28,9 @@
extern int input_size;
extern int input_rate;
-extern int input_ch;
/* called only by initial setup */
-int subband_load(subband_state *f,int bands,int qblocksize){
+int subband_load(subband_state *f,int bands,int qblocksize,int ch){
int i,j;
memset(f,0,sizeof(*f));
@@ -40,44 +39,42 @@
f->fillstate=0;
f->lap_samples=0;
f->lap=malloc(bands*sizeof(*f->lap));
- f->cache0=malloc(input_ch*sizeof(*f->cache0));
- f->cache1=malloc(input_ch*sizeof(*f->cache1));
+ f->cache0=malloc(ch*sizeof(*f->cache0));
+ f->cache1=malloc(ch*sizeof(*f->cache1));
- f->lap_activeP=malloc(input_ch*sizeof(*f->lap_activeP));
- f->lap_active1=malloc(input_ch*sizeof(*f->lap_active1));
- f->lap_active0=malloc(input_ch*sizeof(*f->lap_active0));
- f->lap_activeC=malloc(input_ch*sizeof(*f->lap_activeC));
+ f->lap_activeP=malloc(ch*sizeof(*f->lap_activeP));
+ f->lap_active1=malloc(ch*sizeof(*f->lap_active1));
+ f->lap_active0=malloc(ch*sizeof(*f->lap_active0));
+ f->lap_activeC=malloc(ch*sizeof(*f->lap_activeC));
- f->visible1=malloc(input_ch*sizeof(*f->visible1));
- f->visible0=malloc(input_ch*sizeof(*f->visible0));
- f->visibleC=malloc(input_ch*sizeof(*f->visibleC));
+ f->visible1=malloc(ch*sizeof(*f->visible1));
+ f->visible0=malloc(ch*sizeof(*f->visible0));
+ f->visibleC=malloc(ch*sizeof(*f->visibleC));
- f->effect_activeP=malloc(input_ch*sizeof(*f->effect_activeP));
- f->effect_active1=malloc(input_ch*sizeof(*f->effect_active1));
- f->effect_active0=malloc(input_ch*sizeof(*f->effect_active0));
- f->effect_activeC=malloc(input_ch*sizeof(*f->effect_activeC));
+ f->effect_activeP=malloc(ch*sizeof(*f->effect_activeP));
+ f->effect_active1=malloc(ch*sizeof(*f->effect_active1));
+ f->effect_active0=malloc(ch*sizeof(*f->effect_active0));
+ f->effect_activeC=malloc(ch*sizeof(*f->effect_activeC));
- f->wP=calloc(input_ch,sizeof(*f->wP));
- f->w1=calloc(input_ch,sizeof(*f->w1));
- f->w0=calloc(input_ch,sizeof(*f->w0));
- f->wC=calloc(input_ch,sizeof(*f->wC));
+ f->wP=calloc(ch,sizeof(*f->wP));
+ f->w1=calloc(ch,sizeof(*f->w1));
+ f->w0=calloc(ch,sizeof(*f->w0));
+ f->wC=calloc(ch,sizeof(*f->wC));
- for(i=0;i<input_ch;i++)
+ for(i=0;i<ch;i++)
f->cache0[i]=malloc(input_size*sizeof(**f->cache0));
- for(i=0;i<input_ch;i++)
+ for(i=0;i<ch;i++)
f->cache1[i]=malloc(input_size*sizeof(**f->cache1));
for(i=0;i<bands;i++){
- f->lap[i]=malloc(input_ch*sizeof(**f->lap));
- for(j=0;j<input_ch;j++)
+ f->lap[i]=malloc(ch*sizeof(**f->lap));
+ for(j=0;j<ch;j++)
f->lap[i][j]=malloc(input_size*3*sizeof(***f->lap));
}
- f->out.size=input_size;
- f->out.channels=input_ch;
- f->out.rate=input_rate;
- f->out.data=malloc(input_ch*sizeof(*f->out.data));
- for(i=0;i<input_ch;i++)
+ f->out.channels=ch;
+ f->out.data=malloc(ch*sizeof(*f->out.data));
+ for(i=0;i<ch;i++)
f->out.data[i]=malloc(input_size*sizeof(**f->out.data));
/* fill in time window */
@@ -116,83 +113,98 @@
w->freq_bands=bands;
- /* supersample the spectrum */
+ /* unlike old postfish, we offer all frequencies via smoothly
+ supersampling the spectrum */
+ /* I'm too lazy to figure out the integral symbolically, use this
+ fancy CPU thingy for something */
+
w->ho_window=malloc(bands*sizeof(*w->ho_window));
- {
- float working[f->qblocksize*4+2];
-
+ for(i=0;i<bands;i++)
+ w->ho_window[i]=calloc((f->qblocksize*2+1),sizeof(**w->ho_window));
+
+ /* first, build the first-pass desired, supersampled response */
+ for(j=0;j<(((f->qblocksize*2+1)/10)<<5);j++){
+ float localf= .5*j*input_rate/(f->qblocksize<<6);
+ int localbin= j>>5;
+
for(i=0;i<bands;i++){
float lastf=(i>0?freq_list[i-1]:0);
float thisf=freq_list[i];
float nextf=freq_list[i+1];
- memset(working,0,sizeof(working));
-
- for(j=0;j<((f->qblocksize*2+1)<<5);j++){
- float localf= .5*j*input_rate/(f->qblocksize<<6);
- int localbin= j>>5;
- float localwin;
- if(localf>=lastf && localf<thisf){
- if(i==0)
- localwin=1.;
- else
- localwin= sin((localf-lastf)/(thisf-lastf)*M_PIl*.5);
- localwin*=localwin;
- working[localbin]+=localwin*(1./32);
+ if(localf>=lastf && localf<nextf){
+ float localwin=1.;
+ if(localf<thisf){
+ if(i!=0)localwin= sin((localf-lastf)/(thisf-lastf)*M_PIl*.5);
+ }else{
+ if(i+1!=bands)localwin= sin((nextf-localf)/(nextf-thisf)*M_PIl*.5);
+ }
- }else if(localf>=thisf && localf<nextf){
- if(i+1==bands)
- localwin=1.;
- else
- localwin= sin((nextf-localf)/(nextf-thisf)*M_PIl*.5);
-
- localwin*=localwin;
- working[localbin]+=localwin*(1./32);
-
- }
+ localwin*=localwin;
+ w->ho_window[i][localbin]+=localwin*(1./32);
}
+ }
+ }
+ j>>=5;
+ for(;j<f->qblocksize*2+1;j++){
+ float localf= .5*j*input_rate/(f->qblocksize<<1);
- /* window this desired response in the time domain so that our
- convolution is properly padded against being circular */
- memset(f->fftwf_backward_in,0,sizeof(*f->fftwf_backward_in)*
- (f->qblocksize*4+2));
- for(j=0;j<f->qblocksize*2+2;j++)
- f->fftwf_backward_in[j*2]=working[j];
+ for(i=0;i<bands;i++){
+ float lastf=(i>0?freq_list[i-1]:0);
+ float thisf=freq_list[i];
+ float nextf=freq_list[i+1];
- fftwf_execute(f->fftwf_backward);
+ if(localf>=lastf && localf<nextf){
+ float localwin=1.;
+ if(localf<thisf){
+ if(i!=0)localwin= sin((localf-lastf)/(thisf-lastf)*M_PIl*.5);
+ }else{
+ if(i+1!=bands)localwin= sin((nextf-localf)/(nextf-thisf)*M_PIl*.5);
+ }
- /* window response in time */
- memcpy(f->fftwf_forward_in,f->fftwf_backward_out,
- f->qblocksize*4*sizeof(*f->fftwf_forward_in));
- for(j=0;j<f->qblocksize;j++){
- float val=cos(j*M_PI/(f->qblocksize*2));
- val=sin(val*val*M_PIl*.5);
- f->fftwf_forward_in[j]*= sin(val*val*M_PIl*.5);
+ w->ho_window[i][j]+=localwin*localwin;
}
-
- for(;j<f->qblocksize*3;j++)
- f->fftwf_forward_in[j]=0.;
-
- for(;j<f->qblocksize*4;j++){
- float val=sin((j-f->qblocksize*3)*M_PI/(f->qblocksize*2));
- val=sin(val*val*M_PIl*.5);
- f->fftwf_forward_in[j]*=sin(val*val*M_PIl*.5);
- }
-
- /* back to frequency; this is all-real data still */
- fftwf_execute(f->fftwf_forward);
- for(j=0;j<f->qblocksize*4+2;j++)
- f->fftwf_forward_out[j]/=f->qblocksize*4;
-
- /* now take what we learned and distill it a bit */
- w->ho_window[i]=calloc((f->qblocksize*2+1),sizeof(**w->ho_window));
- for(j=0;j<f->qblocksize*2+1;j++)
- w->ho_window[i][j]=f->fftwf_forward_out[j*2];
-
- lastf=thisf;
-
}
}
+
+ for(i=0;i<bands;i++){
+ /* window each desired response in the time domain so that our
+ convolution is properly padded against being circular */
+ memset(f->fftwf_backward_in,0,sizeof(*f->fftwf_backward_in)*
+ (f->qblocksize*4+2));
+ for(j=0;j<f->qblocksize*2+1;j++)
+ f->fftwf_backward_in[j*2]=w->ho_window[i][j];
+
+ fftwf_execute(f->fftwf_backward);
+
+ /* window response in time */
+ memcpy(f->fftwf_forward_in,f->fftwf_backward_out,
+ f->qblocksize*4*sizeof(*f->fftwf_forward_in));
+ for(j=0;j<f->qblocksize;j++){
+ float val=cos(j*M_PI/(f->qblocksize*2));
+ val=sin(val*val*M_PIl*.5);
+ f->fftwf_forward_in[j]*= sin(val*val*M_PIl*.5);
+ }
+
+ for(;j<f->qblocksize*3;j++)
+ f->fftwf_forward_in[j]=0.;
+
+ for(;j<f->qblocksize*4;j++){
+ float val=sin((j-f->qblocksize*3)*M_PI/(f->qblocksize*2));
+ val=sin(val*val*M_PIl*.5);
+ f->fftwf_forward_in[j]*=sin(val*val*M_PIl*.5);
+ }
+
+ /* back to frequency; this is all-real data still */
+ fftwf_execute(f->fftwf_forward);
+ for(j=0;j<f->qblocksize*4+2;j++)
+ f->fftwf_forward_out[j]/=f->qblocksize*4;
+
+ /* now take what we learned and distill it a bit */
+ for(j=0;j<f->qblocksize*2+1;j++)
+ w->ho_window[i][j]=f->fftwf_forward_out[j*2];
+
+ }
return(0);
}
@@ -215,13 +227,13 @@
int *active){
- int i,j,k,l,off;
+ int i,j,k,l,off,ch=f->out.channels;
float *workoff=f->fftwf_forward_in+f->qblocksize;
u_int32_t mutemask=in->active;
f->mutemaskC=mutemask;
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ch;i++){
int content_p= f->lap_activeC[i]= (visible[i]||active[i]) && !mute_channel_muted(mutemask,i);
int content_p0= f->lap_active0[i];
@@ -320,10 +332,10 @@
}
static void unsubband_work(subband_state *f,time_linkage *in, time_linkage *out){
- int i,j,k;
+ int i,j,k,ch=f->out.channels;
f->lap_samples+=in->samples;
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ch;i++){
int content_pP= f->lap_activeP[i];
int content_p1= f->lap_active1[i];
@@ -466,20 +478,20 @@
/* rotate full-frame data for next frame */
- memcpy(f->effect_activeP,f->effect_active1,input_ch*sizeof(*f->effect_active1));
- memcpy(f->effect_active1,f->effect_active0,input_ch*sizeof(*f->effect_active0));
- memcpy(f->effect_active0,f->effect_activeC,input_ch*sizeof(*f->effect_activeC));
+ memcpy(f->effect_activeP,f->effect_active1,ch*sizeof(*f->effect_active1));
+ memcpy(f->effect_active1,f->effect_active0,ch*sizeof(*f->effect_active0));
+ memcpy(f->effect_active0,f->effect_activeC,ch*sizeof(*f->effect_activeC));
- memcpy(f->visible1,f->visible0,input_ch*sizeof(*f->visible0));
- memcpy(f->visible0,f->visibleC,input_ch*sizeof(*f->visibleC));
+ memcpy(f->visible1,f->visible0,ch*sizeof(*f->visible0));
+ memcpy(f->visible0,f->visibleC,ch*sizeof(*f->visibleC));
f->mutemaskP=f->mutemask1;
f->mutemask1=f->mutemask0;
f->mutemask0=f->mutemaskC;
- memcpy(f->wP,f->w1,input_ch*sizeof(*f->w1));
- memcpy(f->w1,f->w0,input_ch*sizeof(*f->w0));
- memcpy(f->w0,f->wC,input_ch*sizeof(*f->wC));
+ memcpy(f->wP,f->w1,ch*sizeof(*f->w1));
+ memcpy(f->w1,f->w0,ch*sizeof(*f->w0));
+ memcpy(f->w0,f->wC,ch*sizeof(*f->wC));
f->lap_samples-=(out?f->out.samples:0);
@@ -489,7 +501,7 @@
time_linkage *subband_read(time_linkage *in, subband_state *f,
subband_window **w,int *visible, int *active,
void (*workfunc)(void *),void *arg){
- int i,j;
+ int i,j,ch=f->out.channels;
switch(f->fillstate){
case 0: /* begin priming the lapping and cache */
@@ -499,7 +511,7 @@
}
/* initially zero the lapping and cache */
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ch;i++){
for(j=0;j<f->bands;j++)
memset(f->lap[j][i],0,sizeof(***f->lap)*input_size*2);
memset(f->cache1[i],0,sizeof(**f->cache1)*input_size);
@@ -511,12 +523,12 @@
/* set the vars to 'active' so that if the first frame is an
active frame, we don't transition window into it (the window
would have been in the previous frame */
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ch;i++){
int set=(visible[i]||active[i]) && !mute_channel_muted(in->active,i);
- memset(f->lap_activeP,set,sizeof(*f->lap_activeP)*input_ch);
- memset(f->lap_active1,set,sizeof(*f->lap_active1)*input_ch);
- memset(f->lap_active0,set,sizeof(*f->lap_active0)*input_ch);
- //memset(f->lap_activeC,1,sizeof(*f->lap_activeC)*input_ch);
+ memset(f->lap_activeP,set,sizeof(*f->lap_activeP)*ch);
+ memset(f->lap_active1,set,sizeof(*f->lap_active1)*ch);
+ memset(f->lap_active0,set,sizeof(*f->lap_active0)*ch);
+ //memset(f->lap_activeC,1,sizeof(*f->lap_activeC)*ch);
f->wP[i]=w[i];
f->w1[i]=w[i];
@@ -524,13 +536,13 @@
}
- memcpy(f->effect_activeP,active,sizeof(*f->effect_activeP)*input_ch);
- memcpy(f->effect_active1,active,sizeof(*f->effect_active1)*input_ch);
- memcpy(f->effect_active0,active,sizeof(*f->effect_active0)*input_ch);
- //memset(f->effect_activeC,1,sizeof(*f->effect_activeC)*input_ch);
+ memcpy(f->effect_activeP,active,sizeof(*f->effect_activeP)*ch);
+ memcpy(f->effect_active1,active,sizeof(*f->effect_active1)*ch);
+ memcpy(f->effect_active0,active,sizeof(*f->effect_active0)*ch);
+ //memset(f->effect_activeC,1,sizeof(*f->effect_activeC)*ch);
- memset(f->visible1,0,sizeof(*f->visible1)*input_ch);
- memset(f->visible0,0,sizeof(*f->visible0)*input_ch);
+ memset(f->visible1,0,sizeof(*f->visible1)*ch);
+ memset(f->visible0,0,sizeof(*f->visible0)*ch);
f->mutemaskP=in->active;
f->mutemask1=in->active;
@@ -540,17 +552,17 @@
memset(f->fftwf_forward_in,0,f->qblocksize*4*sizeof(*f->fftwf_forward_in));
/* extrapolation mechanism; avoid harsh transients at edges */
- for(i=0;i<input_ch;i++){
+ for(i=0;i<ch;i++){
if(f->lap_active0[i]){
preextrapolate_helper(in->data[i],input_size,
f->cache0[i],input_size);
- if(in->samples<in->size)
+ if(in->samples<input_size)
postextrapolate_helper(f->cache0[i],input_size,
in->data[i],in->samples,
in->data[i]+in->samples,
- in->size-in->samples);
+ input_size-in->samples);
}
}
@@ -560,10 +572,10 @@
f->fillstate=1;
f->out.samples=0;
- if(in->samples==in->size)goto tidy_up;
+ if(in->samples==input_size)goto tidy_up;
- for(i=0;i<input_ch;i++)
- memset(in->data[i],0,sizeof(**in->data)*in->size);
+ for(i=0;i<ch;i++)
+ memset(in->data[i],0,sizeof(**in->data)*input_size);
in->samples=0;
/* fall through */
@@ -571,13 +583,13 @@
/* extrapolation mechanism; avoid harsh transients at edges */
- if(in->samples<in->size)
- for(i=0;i<input_ch;i++){
+ if(in->samples<input_size)
+ for(i=0;i<ch;i++){
if((active[i] || visible[i]) && !mute_channel_muted(in->active,i))
postextrapolate_helper(f->cache0[i],input_size,
in->data[i],in->samples,
in->data[i]+in->samples,
- in->size-in->samples);
+ input_size-in->samples);
}
subband_work(f,in,w,visible,active);
@@ -586,29 +598,29 @@
f->fillstate=2;
f->out.samples=0;
- if(in->samples==in->size)goto tidy_up;
+ if(in->samples==input_size)goto tidy_up;
- for(i=0;i<input_ch;i++)
- memset(in->data[i],0,sizeof(**in->data)*in->size);
+ for(i=0;i<ch;i++)
+ memset(in->data[i],0,sizeof(**in->data)*input_size);
in->samples=0;
/* fall through */
case 2: /* nominal processing */
- if(in->samples<in->size)
- for(i=0;i<input_ch;i++){
+ if(in->samples<input_size)
+ for(i=0;i<ch;i++){
if((active[i] || visible[i]) && !mute_channel_muted(in->active,i))
postextrapolate_helper(f->cache0[i],input_size,
in->data[i],in->samples,
in->data[i]+in->samples,
- in->size-in->samples);
+ input_size-in->samples);
}
subband_work(f,in,w,visible,active);
workfunc(arg);
unsubband_work(f,in,&f->out);
- if(f->out.samples<f->out.size)f->fillstate=3;
+ if(f->out.samples<input_size)f->fillstate=3;
break;
case 3: /* we've pushed out EOF already */
@@ -618,7 +630,7 @@
tidy_up:
{
- int tozero=f->out.size-f->out.samples;
+ int tozero=input_size-f->out.samples;
if(tozero)
for(i=0;i<f->out.channels;i++)
memset(f->out.data[i]+f->out.samples,0,sizeof(**f->out.data)*tozero);
Modified: trunk/postfish/subband.h
===================================================================
--- trunk/postfish/subband.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/subband.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -80,7 +80,7 @@
-extern int subband_load(subband_state *f,int bands, int qb);
+extern int subband_load(subband_state *f,int bands, int qb,int ch);
extern int subband_load_freqs(subband_state *f,subband_window *w,
const float *freq_list,int bands);
Modified: trunk/postfish/suppress.c
===================================================================
--- trunk/postfish/suppress.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/suppress.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -104,7 +104,7 @@
suppress_channel_set.active=calloc(input_ch,sizeof(*suppress_channel_set.active));
- subband_load(&channel_state.ss,suppress_freqs,qblocksize);
+ subband_load(&channel_state.ss,suppress_freqs,qblocksize,input_ch);
subband_load_freqs(&channel_state.ss,&sw,suppress_freq_list,suppress_freqs);
for(i=0;i<suppress_freqs;i++){
Modified: trunk/postfish/suppresspanel.c
===================================================================
--- trunk/postfish/suppresspanel.c 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/suppresspanel.c 2004-05-17 08:16:56 UTC (rev 6712)
@@ -132,10 +132,10 @@
suppress_settings *sset){
int i;
float compand_levels[5]={1,1.5,2,3,5};
- char *compand_labels[4]={"1.5","2","3","5"};
+ char *compand_labels[5]={"","1.5","2","3","5"};
float timing_levels[5]={1, 10, 100, 1000, 10000};
- char *timing_labels[4]={"10ms"," 100ms","1s","10s"};
+ char *timing_labels[5]={"","10ms"," 100ms","1s","10s"};
GtkWidget *table=gtk_table_new(suppress_freqs+4,5,0);
GtkWidget *timinglabel=gtk_label_new("suppressor filter timing");
@@ -197,7 +197,7 @@
/* timing controls */
{
- GtkWidget *slider=multibar_slider_new(4,timing_labels,timing_levels,3);
+ GtkWidget *slider=multibar_slider_new(5,timing_labels,timing_levels,3);
ps->timing.r0=READOUT(readout_new("10.0ms"));
ps->timing.r1=READOUT(readout_new("10.0ms"));
@@ -230,7 +230,7 @@
gtk_widget_set_name(label,"scalemarker");
ps->bars[i].readoutc=READOUT(readout_new("1.55:1"));
- ps->bars[i].cslider=multibar_slider_new(4,compand_labels,compand_levels,1);
+ ps->bars[i].cslider=multibar_slider_new(5,compand_labels,compand_levels,1);
ps->bars[i].sp=ps;
ps->bars[i].v=sset->ratio+i;
ps->bars[i].number=i;
Modified: trunk/postfish/version.h
===================================================================
--- trunk/postfish/version.h 2004-05-17 04:33:46 UTC (rev 6711)
+++ trunk/postfish/version.h 2004-05-17 08:16:56 UTC (rev 6712)
@@ -1,2 +1,2 @@
#define VERSION "$Id$ "
-/* DO NOT EDIT: Automated versioning hack [Mon Apr 26 03:35:14 EDT 2004] */
+/* DO NOT EDIT: Automated versioning hack [Mon May 17 04:15:01 EDT 2004] */
--- >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