[xiph-cvs] cvs commit: postfish feedback.c feedback.h subpanel.c subpanel.h windowbutton.c windowbutton.h Makefile clippanel.c clippanel.h declip.c declip.h input.c input.h main.c mainpanel.c mainpanel.h multibar.c output.c output.h version.h
Monty
xiphmont at xiph.org
Wed Dec 24 01:49:18 PST 2003
xiphmont 03/12/24 04:49:17
Modified: . Makefile clippanel.c clippanel.h declip.c declip.h
input.c input.h main.c mainpanel.c mainpanel.h
multibar.c output.c output.h version.h
Added: . feedback.c feedback.h subpanel.c subpanel.h
windowbutton.c windowbutton.h
Log:
Changes leading up to hooking in declipping filter; it's not there
yet, but I don;t want to lose work.
Monty
Revision Changes Path
1.10 +2 -2 postfish/Makefile
Index: Makefile
===================================================================
RCS file: /usr/local/cvsroot/postfish/Makefile,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Makefile 20 Dec 2003 11:24:17 -0000 1.9
+++ Makefile 24 Dec 2003 09:49:16 -0000 1.10
@@ -6,9 +6,9 @@
LD=gcc
SRC = main.c mainpanel.c multibar.c readout.c input.c output.c clippanel.c declip.c \
- reconstruct.c smallft.c
+ reconstruct.c smallft.c windowbutton.c subpanel.c feedback.c
OBJ = main.o mainpanel.o multibar.o readout.o input.o output.o clippanel.o declip.o \
- reconstruct.o smallft.o
+ reconstruct.o smallft.o windowbutton.o subpanel.o feedback.o
GCF = `pkg-config --cflags gtk+-2.0` -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED
all:
<p><p>1.4 +267 -53 postfish/clippanel.c
Index: clippanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/clippanel.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- clippanel.c 18 Oct 2003 11:12:43 -0000 1.3
+++ clippanel.c 24 Dec 2003 09:49:16 -0000 1.4
@@ -1,73 +1,287 @@
+/*
+ *
+ * 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 "declip.h"
+
+extern sig_atomic_t declip_active;
+extern int input_ch;
+extern int input_size;
+extern int input_rate;
+extern sig_atomic_t declip_converge;
+
+GtkWidget **feedback_bars;
+
+GtkWidget *samplereadout;
+GtkWidget *msreadout;
+GtkWidget *hzreadout;
+GtkWidget *creadout;
+GtkWidget *ireadout;
+
+typedef struct {
+ GtkWidget *slider;
+ GtkWidget *readout;
+ GtkWidget *readoutdB;
+ int number;
+} clipslider;
+
+static void trigger_slider_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ clipslider *p=(clipslider *)in;
+ gdouble linear=gtk_range_get_value(GTK_RANGE(p->slider));
+
+ sprintf(buffer,"%1.2f",linear);
+ readout_set(READOUT(p->readout),buffer);
+
+ sprintf(buffer,"%3.0f dB",todB(linear));
+ readout_set(READOUT(p->readoutdB),buffer);
+
+ declip_settrigger(linear,p->number);
-void clippanel_show(postfish_clippanel *p){
- gtk_widget_show_all(p->toplevel);
-}
-void clippanel_hide(postfish_clippanel *p){
- gtk_widget_hide_all(p->toplevel);
}
-static gboolean forward_events(GtkWidget *widget,
- GdkEvent *event,
- gpointer in){
- postfish_clippanel *p=in;
- GdkEvent copy=*(GdkEvent *)event;
- copy.any.window=p->mainpanel->toplevel->window;
- gtk_main_do_event((GdkEvent *)(©));
- return TRUE;
-}
-
-void clippanel_create(postfish_clippanel *panel,postfish_mainpanel *mp){
- GdkWindow *root=gdk_get_default_root_window();
- GtkWidget *topframe=gtk_frame_new (NULL);
- GtkWidget *toplabel=gtk_label_new (NULL);
- GtkWidget *topvbox=gtk_vbox_new (0,0);
-
- GtkWidget *indframe=gtk_frame_new (NULL);
- GtkWidget *allframe=gtk_frame_new (NULL);
- GtkWidget *indcheck=
- gtk_radio_button_new_with_label (NULL,
- "individual channels ");
- GtkWidget *allcheck=
- gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON(indcheck),
- "all channels ");
-
- gtk_label_set_markup(GTK_LABEL(toplabel),
- "<span weight=\"bold\" "
- "style=\"italic\">"
- " declipping filter </span>");
+static void blocksize_slider_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ int choice=rint(gtk_range_get_value(GTK_RANGE(w)));
+ int blocksize=64<<choice;
- gtk_frame_set_label_widget(GTK_FRAME(indframe),indcheck);
- gtk_frame_set_label_widget(GTK_FRAME(allframe),allcheck);
+ sprintf(buffer,"%5d ",blocksize*3/4);
+ readout_set(READOUT(samplereadout),buffer);
- gtk_box_pack_end(GTK_BOX(topvbox),allframe,0,1,4);
- gtk_box_pack_end(GTK_BOX(topvbox),indframe,0,1,4);
+ sprintf(buffer,"%3.1f ms",blocksize*3000./4/input_rate);
+ readout_set(READOUT(msreadout),buffer);
- panel->toplevel=gtk_window_new (GTK_WINDOW_TOPLEVEL);
- panel->mainpanel=mp;
-
- gtk_container_add (GTK_CONTAINER (panel->toplevel), topframe);
- gtk_container_add (GTK_CONTAINER (topframe), topvbox);
- gtk_container_set_border_width (GTK_CONTAINER (topframe), 3);
- gtk_container_set_border_width (GTK_CONTAINER (topvbox), 5);
- gtk_frame_set_shadow_type(GTK_FRAME(topframe),GTK_SHADOW_ETCHED_IN);
- gtk_frame_set_label_widget(GTK_FRAME(topframe),toplabel);
+ sprintf(buffer,"%5d Hz",(int)rint(input_rate*2./blocksize));
+ readout_set(READOUT(hzreadout),buffer);
+
+ declip_setblock(blocksize);
+}
-
+static void converge_slider_change(GtkWidget *w,gpointer in){
+ char buffer[80];
+ double percent=gtk_range_get_value(GTK_RANGE(w));
+ double sigfigs=percent*.05+2.8;
+ double epsilon=pow(1.,-sigfigs);
+ sprintf(buffer,"%3.1f",sigfigs);
+ readout_set(READOUT(creadout),buffer);
+ sprintf(buffer,"%3.0f%%",percent);
+ readout_set(READOUT(ireadout),buffer);
- /* forward unhandled events to the main window */
- g_signal_connect_after (G_OBJECT (panel->toplevel), "key-press-event",
- G_CALLBACK (forward_events),
- panel);
+ declip_setconvergence(epsilon);
+ declip_setiterations(percent);
+}
+void clippanel_create(postfish_mainpanel *mp,
+ GtkWidget *windowbutton,
+ GtkWidget *activebutton){
+ int i;
+ char *labels[3]={"1%","10%","100%"};
+ double levels[4]={0.,1.,10.,100.};
+ int block_choices=0;
+
+ subpanel_generic *panel=subpanel_create(mp,windowbutton,activebutton,
+ &declip_active,
+ "_Declipping filter setup"," [d] ");
+
+ GtkWidget *framebox=gtk_hbox_new(1,0);
+ GtkWidget *blocksize_box=gtk_vbox_new(0,0);
+ GtkWidget *blocksize_frame=gtk_frame_new (" filter width / approx. lowest response ");
+ GtkWidget *converge_frame=gtk_frame_new (" filter convergence ");
+ GtkWidget *converge_box=gtk_vbox_new(0,0);
+ GtkWidget *channel_table=gtk_table_new(input_ch,4,0);
+
+ gtk_widget_set_name(blocksize_box,"choiceframe");
+ gtk_widget_set_name(converge_box,"choiceframe");
+ gtk_container_set_border_width(GTK_CONTAINER(blocksize_box),2);
+ gtk_container_set_border_width(GTK_CONTAINER(converge_box),2);
+
+ feedback_bars=calloc(input_ch,sizeof(*feedback_bars));
+
+ /* set up blocksize config */
+ for(i=64;i<=input_size*2;i*=2)block_choices++;
+ {
+ 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=gtk_hscale_new_with_range(0,block_choices-1,1);
+ GtkWidget *samplelabel=gtk_label_new("window sample width");
+ GtkWidget *mslabel=gtk_label_new("window time width");
+ GtkWidget *hzlabel=gtk_label_new("approx. lowest response");
+ samplereadout=readout_new("00000 ");
+ msreadout=readout_new("00000 ms");
+ hzreadout=readout_new("00000 Hz");
+
+ gtk_scale_set_draw_value(GTK_SCALE(slider),FALSE);
+ gtk_misc_set_alignment(GTK_MISC(samplelabel),1,.5);
+ gtk_misc_set_alignment(GTK_MISC(mslabel),1,.5);
+ gtk_misc_set_alignment(GTK_MISC(hzlabel),1,.5);
+
+ gtk_box_pack_start(GTK_BOX(sliderbox),fastlabel,0,0,4);
+ gtk_box_pack_start(GTK_BOX(sliderbox),slider,1,1,0);
+ gtk_box_pack_start(GTK_BOX(sliderbox),qualitylabel,0,0,4);
+ gtk_table_attach(GTK_TABLE(table),sliderbox,0,2,0,1,GTK_FILL|GTK_EXPAND,0,0,8);
+ gtk_table_attach(GTK_TABLE(table),samplelabel,0,1,1,2,GTK_FILL|GTK_EXPAND,GTK_FILL,0,0);
+ gtk_table_attach(GTK_TABLE(table),mslabel,0,1,2,3,GTK_FILL|GTK_EXPAND,GTK_FILL,0,0);
+ gtk_table_attach(GTK_TABLE(table),hzlabel,0,1,3,4,GTK_FILL|GTK_EXPAND,GTK_FILL,0,0);
+
+ gtk_table_attach(GTK_TABLE(table),samplereadout,1,2,1,2,GTK_FILL,0,5,0);
+ gtk_table_attach(GTK_TABLE(table),msreadout,1,2,2,3,GTK_FILL,0,5,0);
+ gtk_table_attach(GTK_TABLE(table),hzreadout,1,2,3,4,GTK_FILL,0,5,0);
+ gtk_container_add(GTK_CONTAINER(blocksize_box),table);
+
+
+ g_signal_connect (G_OBJECT (slider), "key-press-event",
+ G_CALLBACK (slider_keymodify), NULL);
+ g_signal_connect_after (G_OBJECT(slider), "value-changed",
+ G_CALLBACK(blocksize_slider_change), 0);
+ gtk_range_set_value(GTK_RANGE(slider),3.);
+
+ }
+ gtk_container_add(GTK_CONTAINER(blocksize_frame),blocksize_box);
- gtk_window_set_resizable(GTK_WINDOW(panel->toplevel),0);
+ /* set up convergence config */
+ {
+ GtkWidget *table=gtk_table_new(3,2,0);
+ GtkWidget *sliderbox=gtk_hbox_new(0,0);
+ GtkWidget *fastlabel=gtk_label_new("fastest");
+ GtkWidget *qualitylabel=gtk_label_new("best");
+ GtkWidget *slider=gtk_hscale_new_with_range(10,200,1);
+ GtkWidget *clabel=gtk_label_new("significant figure target");
+ GtkWidget *ilabel=gtk_label_new("iteration bound");
+ creadout=readout_new("000 ");
+ ireadout=readout_new("000%");
+
+ gtk_scale_set_draw_value(GTK_SCALE(slider),FALSE);
+ gtk_misc_set_alignment(GTK_MISC(clabel),1,.5);
+ gtk_misc_set_alignment(GTK_MISC(ilabel),1,.5);
+
+ gtk_box_pack_start(GTK_BOX(sliderbox),fastlabel,0,0,4);
+ gtk_box_pack_start(GTK_BOX(sliderbox),slider,1,1,0);
+ gtk_box_pack_start(GTK_BOX(sliderbox),qualitylabel,0,0,4);
+ gtk_table_attach(GTK_TABLE(table),sliderbox,0,2,0,1,GTK_FILL|GTK_EXPAND,0,0,8);
+ gtk_table_attach(GTK_TABLE(table),clabel,0,1,1,2,GTK_FILL|GTK_EXPAND,GTK_FILL,0,0);
+ gtk_table_attach(GTK_TABLE(table),ilabel,0,1,2,3,GTK_FILL|GTK_EXPAND,GTK_FILL,0,0);
+
+ gtk_table_attach(GTK_TABLE(table),creadout,1,2,1,2,GTK_FILL,0,5,0);
+ gtk_table_attach(GTK_TABLE(table),ireadout,1,2,2,3,GTK_FILL,0,5,0);
+ gtk_container_add(GTK_CONTAINER(converge_box),table);
+
+ g_signal_connect (G_OBJECT (slider), "key-press-event",
+ G_CALLBACK (slider_keymodify), NULL);
+ g_signal_connect_after (G_OBJECT(slider), "value-changed",
+ G_CALLBACK(converge_slider_change), 0);
+ gtk_range_set_value(GTK_RANGE(slider),25.);
+ }
+ gtk_container_add(GTK_CONTAINER(converge_frame),converge_box);
+
+ gtk_box_pack_start(GTK_BOX(framebox),blocksize_frame,0,1,4);
+ gtk_box_pack_start(GTK_BOX(framebox),converge_frame,0,1,4);
+
+ gtk_box_pack_start(GTK_BOX(panel->subpanel_box),framebox,0,1,4);
+ gtk_box_pack_start(GTK_BOX(panel->subpanel_box),channel_table,0,1,4);
+
+ for(i=0;i<input_ch;i++){
+ char buffer[80];
+ clipslider *cs=calloc(1,sizeof(*cs));
+ GtkWidget *label;
+ GtkWidget *slider=gtk_hscale_new_with_range(.01,1.,.01);
+ GtkWidget *readout=readout_new("0.00");
+ GtkWidget *readoutdB=readout_new("-40 dB");
+ GtkWidget *barframe=gtk_frame_new(NULL);
+ GtkWidget *bar=multibar_new(3,labels,levels,0);
+
+ cs->slider=slider;
+ cs->readout=readout;
+ cs->readoutdB=readoutdB;
+ cs->number=i;
+ feedback_bars[i]=bar;
+
+ gtk_widget_set_size_request (slider,200,-1);
+ gtk_widget_set_name(bar,"clipbar");
+ gtk_scale_set_draw_value(GTK_SCALE(slider),FALSE);
+ gtk_range_set_value(GTK_RANGE(slider),1.);
+ gtk_frame_set_shadow_type(GTK_FRAME(barframe),GTK_SHADOW_ETCHED_IN);
+
+ switch(input_ch){
+ case 1:
+ sprintf(buffer,"trigger level:");
+ break;
+ case 2:
+ switch(i){
+ case 0:
+ sprintf(buffer,"left trigger level:");
+ break;
+ case 1:
+ sprintf(buffer,"right trigger level:");
+ break;
+ }
+ break;
+ default:
+ sprintf(buffer,"%d trigger level:",i+1);
+ }
+ label=gtk_label_new(buffer);
+ gtk_misc_set_alignment(GTK_MISC(label),1,.5);
+
+ gtk_table_attach(GTK_TABLE(channel_table),label,0,1,i,i+1,GTK_FILL,GTK_FILL,2,0);
+ gtk_table_attach(GTK_TABLE(channel_table),readout,1,2,i,i+1,GTK_FILL,GTK_FILL,0,0);
+ gtk_table_attach(GTK_TABLE(channel_table),readoutdB,2,3,i,i+1,GTK_FILL,GTK_FILL,0,0);
+ gtk_table_attach_defaults(GTK_TABLE(channel_table),slider,3,4,i,i+1);
+ gtk_table_attach(GTK_TABLE(channel_table),barframe,4,5,i,i+1,GTK_FILL,GTK_FILL,0,0);
+ gtk_container_add(GTK_CONTAINER(barframe),bar);
+
+
+ g_signal_connect_after (G_OBJECT(slider), "value-changed",
+ G_CALLBACK(trigger_slider_change), (gpointer)cs);
+ g_signal_connect (G_OBJECT (slider), "key-press-event",
+ G_CALLBACK (slider_keymodify), NULL);
+
+ trigger_slider_change(NULL,cs);
+ }
}
+
+void clippanel_feedback(void){
+ int clip[input_ch],count;
+ if(pull_declip_feedback(clip,&count)){
+ int i;
+ for(i=0;i<input_ch;i++){
+ double val=clip[i]*100./count,zero=0;
+ multibar_set(MULTIBAR(feedback_bars[i]),&zero,&val,1);
+ }
+ }
+}
+
+void clippanel_reset(void){
+ int i;
+ for(i=0;i<input_ch;i++)
+ multibar_reset(MULTIBAR(feedback_bars[i]));
+}
<p><p>1.2 +5 -11 postfish/clippanel.h
Index: clippanel.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/clippanel.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- clippanel.h 18 Oct 2003 09:53:22 -0000 1.1
+++ clippanel.h 24 Dec 2003 09:49:16 -0000 1.2
@@ -1,13 +1,7 @@
#include "postfish.h"
-typedef struct postfish_clippanel {
- GtkWidget *toplevel;
-
- postfish_mainpanel *mainpanel;
-} postfish_clippanel;
-
-
-extern void clippanel_create(postfish_clippanel *panel,
- postfish_mainpanel *mp);
-extern void clippanel_show(postfish_clippanel *p);
-extern void clippanel_hide(postfish_clippanel *p);
+extern void clippanel_create(postfish_mainpanel *mp,
+ GtkWidget *windowbutton,
+ GtkWidget *activebutton);
+extern void clippanel_feedback(void);
+extern void clippanel_reset(void);
<p><p>1.2 +139 -75 postfish/declip.c
Index: declip.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/declip.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- declip.c 20 Dec 2003 11:24:17 -0000 1.1
+++ declip.c 24 Dec 2003 09:49:16 -0000 1.2
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include "smallft.h"
#include "reconstruct.h"
+#include "feedback.h"
#include <stdio.h>
extern int input_rate;
@@ -76,25 +77,61 @@
static int fillstate=0; /* 0: uninitialized
1: normal
2: eof processed */
-
static time_linkage out;
/* accessed across threads */
-static sig_atomic_t declip_active=0;
-static sig_atomic_t declip_converge=2; /* 0=over, 1=full, 2=half, 3=partial, 4=approx */
-static sig_atomic_t *chtrigger=0;
-static sig_atomic_t *chactive=0;
+sig_atomic_t declip_active=0;
+sig_atomic_t declip_converge=2; /* 0=over, 1=full, 2=half, 3=partial, 4=approx */
+
+static double *chtrigger=0;
static sig_atomic_t pending_blocksize=0;
+static double convergence=0.;
+static double iterations=0.;
+
+
+/* feedback! */
+typedef struct declip_feedback{
+ feedback_generic parent_class;
+ int *clipcount;
+ int total;
+} declip_feedback;
+
+static feedback_generic_pool feedpool;
+
+static feedback_generic *new_declip_feedback(void){
+ declip_feedback *ret=malloc(sizeof(*ret));
+ ret->clipcount=malloc((input_ch)*sizeof(*ret->clipcount));
+ return (feedback_generic *)ret;
+}
+
+static void push_declip_feedback(int *clip,int total){
+ int i,n=input_ch;
+ declip_feedback *f=(declip_feedback *)
+ feedback_new(&feedpool,new_declip_feedback);
+ memcpy(f->clipcount,clip,n*sizeof(*clip));
+ f->total=total;
+ feedback_push(&feedpool,(feedback_generic *)f);
+}
+
+int pull_declip_feedback(int *clip,int *total){
+ declip_feedback *f=(declip_feedback *)feedback_pull(&feedpool);
+ int i,j;
+
+ if(!f)return 0;
+
+ if(clip)memcpy(clip,f->clipcount,sizeof(*clip)*input_ch);
+ if(total)*total=f->total;
+
+ feedback_old(&feedpool,(feedback_generic *)f);
+ return 1;
+}
/* called only by initial setup */
int declip_load(void){
int i;
chtrigger=malloc(input_ch*sizeof(*chtrigger));
- chactive=malloc(input_ch*sizeof(*chactive));
- for(i=0;i<input_ch;i++){
- chtrigger[i]=0x80000000UL;
- chactive[i]=1;
- }
+ for(i=0;i<input_ch;i++)
+ chtrigger[i]=1.;
out.size=input_size;
out.channels=input_ch;
@@ -121,22 +158,31 @@
return 0;
}
-int declip_setactive(int activep,int ch){
+int declip_settrigger(double trigger,int ch){
if(ch<0 || ch>=input_ch)return -1;
- chactive[ch]=activep;
+ pthread_mutex_lock(&master_mutex);
+ chtrigger[ch]=trigger;
+ pthread_mutex_unlock(&master_mutex);
return 0;
}
-int declip_settrigger(double trigger,int ch){
- if(ch<0 || ch>=input_ch)return -1;
- chtrigger[ch]=rint(trigger*(1.*0x80000000UL));
- return 0;
+int declip_setiterations(double it){
+ pthread_mutex_lock(&master_mutex);
+ iterations=it;
+ pthread_mutex_unlock(&master_mutex);
+}
+
+int declip_setconvergence(double c){
+ pthread_mutex_lock(&master_mutex);
+ convergence=c;
+ pthread_mutex_unlock(&master_mutex);
}
/* called only in playback thread */
int declip_reset(void){
/* reset cached pipe state */
fillstate=0;
+ while(pull_declip_feedback(NULL,NULL));
return 0;
}
@@ -199,12 +245,12 @@
}
static void declip(double *data,double *lap,double *out,
- int blocksize,unsigned long trigger){
+ int blocksize,double trigger,
+ double epsilon, double iteration,
+ int *runningtotal, int *runningcount){
double freq[blocksize];
int flag[blocksize];
- double triggerlevel=trigger*(1./0x80000000UL);
- double epsilon=1e-12;
- int iterbound=blocksize,i,j,count=0;
+ int iterbound,i,j,count=0;
for(i=0;i<blocksize/8;i++)flag[i]=0;
for(;i<blocksize*7/8;i++){
@@ -212,52 +258,67 @@
if(data[i]>=trigger || data[i]<=-trigger){
flag[i]=1;
count++;
+ *runningcount++;
}
}
- for(;i<blocksize;i++)flag[i]=0;
- for(i=0;i<blocksize;i++)data[i]*=window[i];
- memcpy(freq,data,sizeof(freq));
- drft_forward(&fft,freq);
- sliding_bark_average(freq,freq,blocksize,width);
- switch(declip_converge){
- case 0:
- epsilon=1e-12;
- iterbound=blocksize*2;
- break;
- case 1:
- epsilon=1e-8;
- iterbound=count;
- break;
- case 2:
- epsilon=1e-6;
- iterbound=count/2;
- break;
- case 3:
- epsilon=1e-5;
- iterbound=count/4;
- break;
- case 4:
- epsilon=1e-3;
- iterbound=count/8;
- break;
- }
- if(iterbound<20)iterbound=20;
+ *runningtotal+=blocksize*3/4;
+
+ if(declip_active){
+
+ for(;i<blocksize;i++)flag[i]=0;
+ for(i=0;i<blocksize;i++)data[i]*=window[i];
+ memcpy(freq,data,sizeof(freq));
+ drft_forward(&fft,freq);
+ sliding_bark_average(freq,freq,blocksize,width);
+
+ if(iteration<1.){
+ iterbound=count*iteration;
+ }else{
+ iterbound=count+blocksize*(iteration-1.);
+ }
+ if(iterbound<20)iterbound=20;
+
+ reconstruct(&fft,data,freq,flag,epsilon*count,iterbound,blocksize);
+
+ if(out)
+ for(i=0;i<blocksize/2;i++)
+ out[i]=lap[i]+data[i]*window[i];
+
+ for(i=blocksize/2,j=0;i<blocksize;i++)
+ lap[j]=data[i]*window[i];
- reconstruct(&fft,data,freq,flag,epsilon*count,iterbound,blocksize);
+ }else{
- if(out)
- for(i=0;i<blocksize/2;i++)
- out[i]=lap[i]+data[i]*window[i];
+ if(out)
+ for(i=0;i<blocksize/2;i++)
+ out[i]=data[i];
+
+ for(i=blocksize/2,j=0;i<blocksize;i++)
+ lap[j]=data[i]*window[i]*window[i];
- for(i=blocksize/2,j=0;i<blocksize;i++)
- lap[j]=data[i]*window[i];
+ }
}
/* called only by playback thread */
time_linkage *declip_read(time_linkage *in){
int i;
double work[blocksize];
+ double local_trigger[input_ch];
+ int total=0;
+ int count[input_ch];
+ time_linkage dummy;
+
+ double local_convergence;
+ double local_iterations;
+
+ pthread_mutex_lock(&master_mutex);
+ local_convergence=convergence;
+ local_iterations=iterations;
+ memcpy(local_trigger,chtrigger,sizeof(local_trigger));
+ pthread_mutex_unlock(&master_mutex);
+
+ memset(count,0,sizeof(count));
if(pending_blocksize!=blocksize){
if(blocksize){
@@ -292,19 +353,19 @@
}
+
switch(fillstate){
case 0: /* prime the lapping and cache */
for(i=0;i<input_ch;i++){
int j;
double *temp=in->data[i];
- if(chactive[i] && declip_active){
- memset(work,0,sizeof(*work)*blocksize/2);
- memcpy(work+blocksize/2,temp,sizeof(*work)*blocksize/2);
- declip(work,lap[i],0,blocksize,chtrigger[i]);
- }else{
- for(j=0;j<blocksize/2;j++)
- lap[i][j]=window[j+blocksize/2]*temp[j];
- }
+ total=0;
+ memset(work,0,sizeof(*work)*blocksize/2);
+ memcpy(work+blocksize/2,temp,sizeof(*work)*blocksize/2);
+ declip(work,lap[i],0,blocksize,
+ local_trigger[i],local_convergence,local_iterations,
+ &total,count+i);
+
memset(cache[i],0,sizeof(**cache)*input_size);
in->data[i]=cache[i];
cache[i]=temp;
@@ -317,20 +378,19 @@
case 1: /* nominal processing */
for(i=0;i<input_ch;i++){
double *temp=cache[i];
- int j;
- if(chactive[i] && declip_active){
- for(j=0;j+blocksize<out.size;j+=blocksize/2){
- memcpy(work,temp+j,sizeof(*work)*blocksize);
- declip(work,lap[i],out.data[i]+j,blocksize,chtrigger[i]);
- }
- memcpy(work,temp+j,sizeof(*work)*blocksize/2);
- memcpy(work+blocksize/2,in->data[i],sizeof(*work)*blocksize/2);
- declip(work,lap[i],out.data[i]+j,blocksize,chtrigger[i]);
- }else{
- memcpy(out.data[i],temp,out.size*sizeof(*temp));
- for(j=0;j<blocksize/2;j++)
- lap[i][j]=window[j+blocksize/2]*temp[j];
+ int j;
+ total=0;
+ for(j=0;j+blocksize<out.size;j+=blocksize/2){
+ memcpy(work,temp+j,sizeof(*work)*blocksize);
+ declip(work,lap[i],out.data[i]+j,blocksize,
+ local_trigger[i],local_convergence,local_iterations,
+ &total,count+i);
}
+ memcpy(work,temp+j,sizeof(*work)*blocksize/2);
+ memcpy(work+blocksize/2,in->data[i],sizeof(*work)*blocksize/2);
+ declip(work,lap[i],out.data[i]+j,blocksize,
+ local_trigger[i],local_convergence,local_iterations,
+ &total,count+i);
in->data[i]=cache[i];
cache[i]=temp;
@@ -342,5 +402,9 @@
case 2: /* we've pushed out EOF already */
return 0;
}
+
+ /* we're returning data, push feedback */
+ push_declip_feedback(count,total);
+
return &out;
}
<p><p>1.2 +2 -1 postfish/declip.h
Index: declip.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/declip.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- declip.h 20 Dec 2003 11:24:17 -0000 1.1
+++ declip.h 24 Dec 2003 09:49:16 -0000 1.2
@@ -23,7 +23,8 @@
extern int declip_load(void);
extern int declip_setblock(int n);
-extern int declip_setactive(int activep,int ch);
extern int declip_settrigger(double trigger,int ch);
+extern int declip_setiterations(double x);
+extern int declip_setconvergence(double x);
extern int declip_reset(void);
extern time_linkage *declip_read(time_linkage *in);
<p><p>1.12 +51 -64 postfish/input.c
Index: input.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/input.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- input.c 20 Dec 2003 11:24:17 -0000 1.11
+++ input.c 24 Dec 2003 09:49:16 -0000 1.12
@@ -2,7 +2,7 @@
*
* postfish
*
- * Copyright (C) 2002-2003 Monty
+ * 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
@@ -22,6 +22,7 @@
*/
#include "postfish.h"
+#include "feedback.h"
#include "input.h"
static off_t Acursor=0;
@@ -47,16 +48,13 @@
} file_entry;
typedef struct input_feedback{
+ feedback_generic parent_class;
off_t cursor;
double *rms;
double *peak;
-
- struct input_feedback *next;
} input_feedback;
-static input_feedback *feedback_list_head;
-static input_feedback *feedback_list_tail;
-static input_feedback *feedback_pool;
+static feedback_generic_pool feedpool;
static file_entry *file_list=NULL;
static int file_entries=0;
@@ -163,7 +161,7 @@
int input_load(int n,char *list[]){
char *fname="stdin";
- int stdinp=0,i,j,ch,rate;
+ int stdinp=0,i,j,ch=0,rate=0;
off_t total=0;
if(n==0){
@@ -309,7 +307,38 @@
}
}
- input_size=out.size=2048;
+
+ /* 192000: 8192
+
+ 96000: 4096
+ 88200: 4096
+ 64000: 4096
+
+ 48000: 2048
+ 44100: 2048
+ 32000: 1024
+
+ 22050: 1024
+ 16000: 1024
+
+ 11025: 512
+ 8000: 512
+
+ 4000: 256 */
+
+ if(rate<6000){
+ input_size=out.size=256;
+ }else if(rate<15000){
+ input_size=out.size=512;
+ }else if(rate<25000){
+ input_size=out.size=1024;
+ }else if(rate<50000){
+ input_size=out.size=2048;
+ }else if(rate<100000){
+ input_size=out.size=4096;
+ }else
+ input_size=out.size=8192;
+
input_ch=out.channels=ch;
input_rate=out.rate=rate;
out.data=malloc(sizeof(*out.data)*ch);
@@ -364,73 +393,31 @@
return ret;
}
-static input_feedback *new_input_feedback(void){
- input_feedback *ret;
-
- pthread_mutex_lock(&master_mutex);
- if(feedback_pool){
- ret=feedback_pool;
- feedback_pool=feedback_pool->next;
- pthread_mutex_unlock(&master_mutex);
- return ret;
- }
- pthread_mutex_unlock(&master_mutex);
- ret=malloc(sizeof(*ret));
+static feedback_generic *new_input_feedback(void){
+ input_feedback *ret=malloc(sizeof(*ret));
ret->rms=malloc((input_ch+2)*sizeof(*ret->rms));
ret->peak=malloc((input_ch+2)*sizeof(*ret->peak));
-
- return ret;
+ return (feedback_generic *)ret;
}
static void push_input_feedback(double *peak,double *rms, off_t cursor){
int i,n=input_ch+2;
- input_feedback *f=new_input_feedback();
-
+ input_feedback *f=(input_feedback *)
+ feedback_new(&feedpool,new_input_feedback);
f->cursor=cursor;
memcpy(f->rms,rms,n*sizeof(*rms));
memcpy(f->peak,peak,n*sizeof(*peak));
- f->next=NULL;
-
- pthread_mutex_lock(&master_mutex);
- if(!feedback_list_tail){
- feedback_list_tail=f;
- feedback_list_head=f;
- }else{
- feedback_list_head->next=f;
- feedback_list_head=f;
- }
- pthread_mutex_unlock(&master_mutex);
+ feedback_push(&feedpool,(feedback_generic *)f);
}
-int pull_input_feedback(double *peak,double *rms,off_t *cursor,int *nn){
- input_feedback *f;
+int pull_input_feedback(double *peak,double *rms,off_t *cursor){
+ input_feedback *f=(input_feedback *)feedback_pull(&feedpool);
int i,j,n=input_ch+2;
- if(nn)*nn=n;
-
- pthread_mutex_lock(&master_mutex);
- if(feedback_list_tail){
-
- f=feedback_list_tail;
- feedback_list_tail=feedback_list_tail->next;
- if(!feedback_list_tail)feedback_list_head=0;
-
- }else{
- pthread_mutex_unlock(&master_mutex);
- return 0;
- }
- pthread_mutex_unlock(&master_mutex);
-
- if(rms)
- memcpy(rms,f->rms,sizeof(*rms)*n);
- if(peak)
- memcpy(peak,f->peak,sizeof(*peak)*n);
- if(cursor)
- *cursor=f->cursor;
-
- pthread_mutex_lock(&master_mutex);
- f->next=feedback_pool;
- feedback_pool=f;
- pthread_mutex_unlock(&master_mutex);
+ if(!f)return 0;
+ if(rms)memcpy(rms,f->rms,sizeof(*rms)*n);
+ if(peak)memcpy(peak,f->peak,sizeof(*peak)*n);
+ if(cursor)*cursor=f->cursor;
+ feedback_old(&feedpool,(feedback_generic *)f);
return 1;
}
@@ -567,7 +554,7 @@
}
void input_reset(void){
- while(pull_input_feedback(NULL,NULL,NULL,NULL));
+ while(pull_input_feedback(NULL,NULL,NULL));
return;
}
<p><p>1.7 +1 -1 postfish/input.h
Index: input.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/input.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- input.h 17 Oct 2003 08:40:18 -0000 1.6
+++ input.h 24 Dec 2003 09:49:16 -0000 1.7
@@ -6,6 +6,6 @@
extern off_t input_seek(off_t pos);
extern time_linkage *input_read(void);
extern int input_load(int n,char *list[]);
-extern int pull_input_feedback(double *peak,double *rms,off_t *cursor,int *n);
+extern int pull_input_feedback(double *peak,double *rms,off_t *cursor);
extern void input_reset(void);
extern off_t input_time_seek_rel(double s);
<p><p>1.8 +2 -0 postfish/main.c
Index: main.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/main.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- main.c 18 Oct 2003 11:10:09 -0000 1.7
+++ main.c 24 Dec 2003 09:49:16 -0000 1.8
@@ -41,6 +41,8 @@
/* 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);
/* look at stdout... do we have a file or device? */
if(!isatty(STDOUT_FILENO)){
<p><p>1.24 +65 -40 postfish/mainpanel.c
Index: mainpanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/mainpanel.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- mainpanel.c 20 Dec 2003 11:24:17 -0000 1.23
+++ mainpanel.c 24 Dec 2003 09:49:16 -0000 1.24
@@ -10,14 +10,45 @@
#include "input.h"
#include "output.h"
#include "mainpanel.h"
+#include "windowbutton.h"
-static void action_clippanel_window(GtkWidget *widget,postfish_mainpanel *p){
- if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))){
- clippanel_show(&p->clippanel);
- }else{
- clippanel_hide(&p->clippanel);
+gboolean slider_keymodify(GtkWidget *w,GdkEventKey *event,gpointer in){
+ GtkWidget *toplevel=gtk_widget_get_toplevel(w);
+ GtkAdjustment *adj=gtk_range_get_adjustment(GTK_RANGE(w));
+ if(event->state&GDK_MOD1_MASK) return FALSE;
+ if(event->state&GDK_CONTROL_MASK) return FALSE;
+
+ switch(event->keyval){
+ case GDK_minus:
+ gtk_range_set_value(GTK_RANGE(w),adj->value-adj->step_increment);
+ break;
+ case GDK_underscore:
+ gtk_range_set_value(GTK_RANGE(w),adj->value-adj->page_increment);
+ break;
+ case GDK_equal:
+ gtk_range_set_value(GTK_RANGE(w),adj->value+adj->step_increment);
+ break;
+ case GDK_plus:
+ gtk_range_set_value(GTK_RANGE(w),adj->value+adj->page_increment);
+ break;
+
+ case GDK_Left:
+ gtk_widget_child_focus(toplevel,GTK_DIR_LEFT);
+ break;
+ case GDK_Up:
+ gtk_widget_child_focus(toplevel,GTK_DIR_UP);
+ break;
+ case GDK_Right:
+ gtk_widget_child_focus(toplevel,GTK_DIR_RIGHT);
+ break;
+ case GDK_Down:
+ gtk_widget_child_focus(toplevel,GTK_DIR_DOWN);
+ break;
+ default:
+ return FALSE;
}
+ return TRUE;
}
static void action_zero(GtkWidget *widget,postfish_mainpanel *p){
@@ -29,6 +60,7 @@
readout_set(READOUT(p->cue),(char *)time);
multibar_reset(MULTIBAR(p->inbar));
multibar_reset(MULTIBAR(p->outbar));
+ clippanel_reset();
}
static void action_end(GtkWidget *widget,postfish_mainpanel *p){
@@ -41,6 +73,7 @@
readout_set(READOUT(p->cue),(char *)buf);
multibar_reset(MULTIBAR(p->inbar));
multibar_reset(MULTIBAR(p->outbar));
+ clippanel_reset();
}
static void action_bb(GtkWidget *widget,postfish_mainpanel *p){
@@ -131,6 +164,7 @@
char time[14];
input_cursor_to_time(0,time);
gtk_entry_set_text(GTK_ENTRY(p->entry_a),time);
+ input_Acursor_set(0);
}
static void action_resetb(GtkWidget *widget,postfish_mainpanel *p){
@@ -263,7 +297,7 @@
case GDK_Left:
if(pos==0){
/* back up focus */
- gtk_widget_child_focus(toplevel,GTK_DIR_TAB_BACKWARD);
+ gtk_widget_child_focus(toplevel,GTK_DIR_LEFT);
return TRUE;
}
@@ -275,7 +309,7 @@
case GDK_Right:
if(pos>=12){
/* advance focus */
- gtk_widget_child_focus(toplevel,GTK_DIR_TAB_FORWARD);
+ gtk_widget_child_focus(toplevel,GTK_DIR_RIGHT);
return TRUE;
}
@@ -401,10 +435,6 @@
gtk_widget_activate(p->deckactive[3]);
break;
case GDK_period:
-
-
-
-
gtk_widget_activate(p->deckactive[4]);
break;
case GDK_greater:
@@ -424,23 +454,18 @@
char *label,
char *shortcut,
int i,
- GCallback cw,
- GCallback ca){
- GtkWidget *ww=gtk_check_button_new_with_mnemonic(label);
+ void (*panel_create)
+ (postfish_mainpanel *,
+ GtkWidget *, GtkWidget *)){
+
+ GtkWidget *ww=windowbutton_new(label);
GtkWidget *wa=gtk_toggle_button_new_with_label(shortcut);
-
- p->buttonwindow[i]=ww;
- p->buttonactive[i]=wa;
gtk_table_attach_defaults(GTK_TABLE(p->wintable),ww,0,1,i+1,i+2);
gtk_table_attach_defaults(GTK_TABLE(p->wintable),wa,1,2,i+1,i+2);
- if(cw)
- g_signal_connect (G_OBJECT (ww), "clicked",
- G_CALLBACK (cw), p);
- if(ca)
- g_signal_connect (G_OBJECT (wa), "clicked",
- G_CALLBACK (ca), p);
+ p->buttonactive[i]=wa;
+ if(panel_create)(*panel_create)(p,ww,wa);
}
void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
@@ -494,8 +519,6 @@
gtk_container_add (GTK_CONTAINER (panel->toplevel), topplace);
gtk_container_set_border_width (GTK_CONTAINER (panel->quitbutton), 3);
-
-
g_signal_connect (G_OBJECT (panel->quitbutton), "clicked",
G_CALLBACK (shutdown), NULL);
@@ -578,14 +601,13 @@
gtk_table_attach_defaults(GTK_TABLE(panel->wintable),temp,1,2,0,1);
}
- mainpanel_panelentry(panel,"_Declip ","[d]",0,
- (GCallback)action_clippanel_window,0);
- mainpanel_panelentry(panel,"Cross_Talk ","[t]",1,0,0);
- mainpanel_panelentry(panel,"_Noise Filter ","[n]",2,0,0);
- mainpanel_panelentry(panel,"_Equalizer ","[e]",3,0,0);
- mainpanel_panelentry(panel,"_Compander ","[c]",4,0,0);
- mainpanel_panelentry(panel,"_Limiter ","[l]",5,0,0);
- mainpanel_panelentry(panel,"_Output Cal. ","[o]",6,0,0);
+ mainpanel_panelentry(panel,"_Declip ","[d]",0,clippanel_create);
+ mainpanel_panelentry(panel,"Cross_Talk ","[t]",1,0);
+ mainpanel_panelentry(panel,"_Noise Filter ","[n]",2,0);
+ mainpanel_panelentry(panel,"_Equalizer ","[e]",3,0);
+ mainpanel_panelentry(panel,"_Compander ","[c]",4,0);
+ mainpanel_panelentry(panel,"_Limiter ","[l]",5,0);
+ mainpanel_panelentry(panel,"_Output Cal. ","[o]",6,0);
g_signal_connect (G_OBJECT (panel->toplevel), "delete_event",
@@ -666,6 +688,9 @@
gtk_table_attach_defaults(GTK_TABLE(ttable),box,1,3,3,4);
+ g_signal_connect (G_OBJECT (panel->masterdB_s), "key-press-event",
+ G_CALLBACK (slider_keymodify), NULL);
+
g_signal_connect_after (G_OBJECT(panel->masterdB_s), "value-changed",
G_CALLBACK(masterdB_change), (gpointer)panel);
@@ -734,7 +759,7 @@
GtkWidget *framea=gtk_vseparator_new();
GtkWidget *frameb=gtk_vseparator_new();
- GtkWidget *panelb=gtk_check_button_new_with_mnemonic("c_ue list");
+ GtkWidget *panelb=windowbutton_new("c_ue list");
panel->entry_a=gtk_entry_new();
panel->entry_b=gtk_entry_new();
@@ -803,7 +828,7 @@
GtkWidget *confbox=gtk_hbox_new(0,0);
GtkWidget *conflabel=gtk_label_new("setting:");
GtkWidget *conf=readout_new("");
- GtkWidget *panel=gtk_check_button_new_with_mnemonic("_setting list");
+ GtkWidget *panel=windowbutton_new("_setting list");
gtk_misc_set_alignment(GTK_MISC(conflabel),1,.5);
gtk_table_attach_defaults(GTK_TABLE(ttable),conflabel,0,1,6,7);
@@ -822,8 +847,6 @@
gtk_widget_show_all(panel->toplevel);
gtk_window_set_resizable(GTK_WINDOW(panel->toplevel),0);
- clippanel_create(&panel->clippanel,panel);
-
}
static gboolean feedback_process(postfish_mainpanel *panel){
@@ -839,10 +862,10 @@
available and not dirtied by a seek */
if(!playback_seeking){
off_t time_cursor;
- int n;
+ int n=input_ch+2;
double *rms=alloca(sizeof(*rms)*(input_ch+2));
double *peak=alloca(sizeof(*peak)*(input_ch+2));
- if(pull_input_feedback(peak,rms,&time_cursor,&n)){
+ if(pull_input_feedback(peak,rms,&time_cursor)){
char buffer[14];
int i;
for(i=0;i<n;i++){
@@ -859,7 +882,9 @@
input_cursor_to_time(time_cursor,buffer);
readout_set(READOUT(panel->cue),buffer);
- if(pull_output_feedback(peak,rms,&n)){
+ clippanel_feedback();
+
+ if(pull_output_feedback(peak,rms)){
for(i=0;i<n;i++){
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->channelshow[i]))){
peak[i]=todB(peak[i]);
<p><p>1.5 +1 -2 postfish/mainpanel.h
Index: mainpanel.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/mainpanel.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- mainpanel.h 18 Oct 2003 11:10:09 -0000 1.4
+++ mainpanel.h 24 Dec 2003 09:49:16 -0000 1.5
@@ -33,7 +33,6 @@
GtkWidget *masterdB_s;
GtkWidget *masterdB_a;
- GtkWidget *buttonwindow[7];
GtkWidget *buttonactive[7];
GtkWidget *cue_set[2];
@@ -50,7 +49,6 @@
GtkWidget *entry_a;
GtkWidget *entry_b;
- postfish_clippanel clippanel;
/* ui state */
int fishframe;
@@ -59,3 +57,4 @@
};
+extern gboolean slider_keymodify(GtkWidget *w,GdkEventKey *event,gpointer in);
<p><p>1.13 +1 -1 postfish/multibar.c
Index: multibar.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/multibar.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- multibar.c 20 Dec 2003 11:24:17 -0000 1.12
+++ multibar.c 24 Dec 2003 09:49:16 -0000 1.13
@@ -343,7 +343,7 @@
if(y>maxy)maxy=y;
}
- requisition->width = (maxx*2)*m->labels;
+ requisition->width = (maxx*1.5+2)*m->labels;
requisition->height = maxy;
}
<p><p>1.10 +21 -59 postfish/output.c
Index: output.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/output.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- output.c 17 Oct 2003 06:28:15 -0000 1.9
+++ output.c 24 Dec 2003 09:49:16 -0000 1.10
@@ -25,7 +25,10 @@
#include <linux/soundcard.h>
#include <sys/ioctl.h>
#include "postfish.h"
+#include "feedback.h"
#include "input.h"
+#include "output.h"
+#include "declip.h"
sig_atomic_t playback_active=0;
sig_atomic_t playback_exit=0;
@@ -33,7 +36,7 @@
void output_reset(void){
/* empty feedback queues */
- while(pull_output_feedback(NULL,NULL,NULL));
+ while(pull_output_feedback(NULL,NULL));
return;
}
@@ -47,84 +50,42 @@
fcntl(eventpipe[0],F_SETFL,flags);
input_reset(); /* clear any persistent lapping state */
+ declip_reset(); /* clear any persistent lapping state */
output_reset(); /* clear any persistent lapping state */
}
typedef struct output_feedback{
+ feedback_generic parent_class;
double *rms;
double *peak;
-
- struct output_feedback *next;
} output_feedback;
-static output_feedback *feedback_list_head;
-static output_feedback *feedback_list_tail;
-static output_feedback *feedback_pool;
+static feedback_generic_pool feedpool;
-static output_feedback *new_output_feedback(void){
- output_feedback *ret;
-
- pthread_mutex_lock(&master_mutex);
- if(feedback_pool){
- ret=feedback_pool;
- feedback_pool=feedback_pool->next;
- pthread_mutex_unlock(&master_mutex);
- return ret;
- }
- pthread_mutex_unlock(&master_mutex);
- ret=malloc(sizeof(*ret));
+static feedback_generic *new_output_feedback(void){
+ output_feedback *ret=malloc(sizeof(*ret));
ret->rms=malloc((input_ch+2)*sizeof(*ret->rms));
ret->peak=malloc((input_ch+2)*sizeof(*ret->peak));
-
- return ret;
+ return (feedback_generic *)ret;
}
static void push_output_feedback(double *peak,double *rms){
int i,n=input_ch+2;
- output_feedback *f=new_output_feedback();
-
+ output_feedback *f=(output_feedback *)
+ feedback_new(&feedpool,new_output_feedback);
+
memcpy(f->rms,rms,n*sizeof(*rms));
memcpy(f->peak,peak,n*sizeof(*peak));
- f->next=NULL;
-
- pthread_mutex_lock(&master_mutex);
- if(!feedback_list_tail){
- feedback_list_tail=f;
- feedback_list_head=f;
- }else{
- feedback_list_head->next=f;
- feedback_list_head=f;
- }
- pthread_mutex_unlock(&master_mutex);
+ feedback_push(&feedpool,(feedback_generic *)f);
}
-int pull_output_feedback(double *peak,double *rms,int *nn){
- output_feedback *f;
+int pull_output_feedback(double *peak,double *rms){
+ output_feedback *f=(output_feedback *)feedback_pull(&feedpool);
int i,j,n=input_ch+2;
- if(nn)*nn=n;
-
- pthread_mutex_lock(&master_mutex);
- if(feedback_list_tail){
-
- f=feedback_list_tail;
- feedback_list_tail=feedback_list_tail->next;
- if(!feedback_list_tail)feedback_list_head=0;
-
- }else{
- pthread_mutex_unlock(&master_mutex);
- return 0;
- }
- pthread_mutex_unlock(&master_mutex);
-
- if(rms)
- memcpy(rms,f->rms,sizeof(*rms)*n);
- if(peak)
- memcpy(peak,f->peak,sizeof(*peak)*n);
-
- pthread_mutex_lock(&master_mutex);
- f->next=feedback_pool;
- feedback_pool=f;
- pthread_mutex_unlock(&master_mutex);
+ if(!f)return 0;
+ if(rms)memcpy(rms,f->rms,sizeof(*rms)*n);
+ if(peak)memcpy(peak,f->peak,sizeof(*peak)*n);
+ feedback_old(&feedpool,(feedback_generic *)f);
return 1;
}
@@ -240,6 +201,7 @@
/* get data */
if(!(ret=input_read()))break;
+ //!(ret=declip_read()))break;
/************/
<p><p>1.4 +1 -1 postfish/output.h
Index: output.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/output.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- output.h 17 Oct 2003 06:28:15 -0000 1.3
+++ output.h 24 Dec 2003 09:49:16 -0000 1.4
@@ -1,4 +1,4 @@
-extern int pull_output_feedback(double *peak,double *rms,int *n);
+extern int pull_output_feedback(double *peak,double *rms);
extern void *playback_thread(void *dummy);
extern void output_halt_playback(void);
extern void output_reset(void);
<p><p>1.22 +2 -2 postfish/version.h
Index: version.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/version.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- version.h 20 Dec 2003 11:24:17 -0000 1.21
+++ version.h 24 Dec 2003 09:49:16 -0000 1.22
@@ -1,2 +1,2 @@
-#define VERSION "$Id: version.h,v 1.21 2003/12/20 11:24:17 xiphmont Exp $ "
-/* DO NOT EDIT: Automated versioning hack [Sat Dec 20 05:44:23 EST 2003] */
+#define VERSION "$Id: version.h,v 1.22 2003/12/24 09:49:16 xiphmont Exp $ "
+/* DO NOT EDIT: Automated versioning hack [Wed Dec 24 04:43:27 EST 2003] */
<p><p>1.1 postfish/feedback.c
Index: feedback.c
===================================================================
/*
*
* postfish
*
* Copyright (C) 2002-2004 Monty and Xiph.Org
*
* 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"
feedback_generic *feedback_new(feedback_generic_pool *pool,
feedback_generic *(*constructor)(void)){
feedback_generic *ret;
pthread_mutex_lock(&master_mutex);
if(pool->feedback_pool){
ret=pool->feedback_pool;
pool->feedback_pool=pool->feedback_pool->next;
pthread_mutex_unlock(&master_mutex);
return ret;
}
pthread_mutex_unlock(&master_mutex);
ret=constructor();
return ret;
}
void feedback_push(feedback_generic_pool *pool,
feedback_generic *f){
f->next=NULL;
pthread_mutex_lock(&master_mutex);
if(!pool->feedback_list_tail){
pool->feedback_list_tail=f;
pool->feedback_list_head=f;
}else{
pool->feedback_list_head->next=f;
pool->feedback_list_head=f;
}
pthread_mutex_unlock(&master_mutex);
}
feedback_generic *feedback_pull(feedback_generic_pool *pool){
feedback_generic *f;
pthread_mutex_lock(&master_mutex);
if(pool->feedback_list_tail){
f=pool->feedback_list_tail;
pool->feedback_list_tail=pool->feedback_list_tail->next;
if(!pool->feedback_list_tail)pool->feedback_list_head=0;
}else{
pthread_mutex_unlock(&master_mutex);
return 0;
}
pthread_mutex_unlock(&master_mutex);
return(f);
}
void feedback_old(feedback_generic_pool *pool,
feedback_generic *f){
pthread_mutex_lock(&master_mutex);
f->next=pool->feedback_pool;
pool->feedback_pool=f;
pthread_mutex_unlock(&master_mutex);
}
<p><p><p>1.1 postfish/feedback.h
Index: feedback.h
===================================================================
/*
*
* postfish
*
* Copyright (C) 2002-2004 Monty and Xiph.Org
*
* 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 feedback_generic{
struct feedback_generic *next;
} feedback_generic;
typedef struct feedback_generic_pool{
feedback_generic *feedback_list_head;
feedback_generic *feedback_list_tail;
feedback_generic *feedback_pool;
} feedback_generic_pool;
extern feedback_generic *feedback_new(feedback_generic_pool *pool,
feedback_generic *(*constructor)(void));
extern void feedback_push(feedback_generic_pool *pool,
feedback_generic *f);
extern feedback_generic *feedback_pull(feedback_generic_pool *pool);
extern void feedback_old(feedback_generic_pool *pool,
feedback_generic *f);
<p><p><p>1.1 postfish/subpanel.c
Index: subpanel.c
===================================================================
/*
*
* postfish
*
* Copyright (C) 2002-2004 Monty
*
* Postfish is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* Postfish is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#include "postfish.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "mainpanel.h"
#include "windowbutton.h"
#include "subpanel.h"
tatic int clippanel_hide(GtkWidget *widget,
GdkEvent *event,
gpointer in){
subpanel_generic *p=in;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->subpanel_windowbutton),0);
return FALSE;
}
static int windowbutton_action(GtkWidget *widget,
gpointer in){
int active;
subpanel_generic *p=in;
if(widget==p->subpanel_windowbutton){
active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p->subpanel_windowbutton));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->mainpanel_windowbutton),active);
}else{
active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p->mainpanel_windowbutton));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->subpanel_windowbutton),active);
}
if(active)
gtk_widget_show_all(p->subpanel_toplevel);
else
gtk_widget_hide_all(p->subpanel_toplevel);
return FALSE;
}
tatic int activebutton_action(GtkWidget *widget,
gpointer in){
subpanel_generic *p=in;
int active;
if(widget==p->subpanel_activebutton){
active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p->subpanel_activebutton));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->mainpanel_activebutton),active);
}else{
active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p->mainpanel_activebutton));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->subpanel_activebutton),active);
}
*p->activevar=active;
return FALSE;
}
tatic gboolean forward_events(GtkWidget *widget,
GdkEvent *event,
gpointer in){
subpanel_generic *p=in;
GdkEvent copy=*(GdkEvent *)event;
copy.any.window=p->mainpanel->toplevel->window;
gtk_main_do_event((GdkEvent *)(©));
return TRUE;
}
ubpanel_generic *subpanel_create(postfish_mainpanel *mp,
GtkWidget *windowbutton,
GtkWidget *activebutton,
sig_atomic_t *activevar,
char *prompt,char *shortcut){
subpanel_generic *panel=calloc(1,sizeof(*panel));
GdkWindow *root=gdk_get_default_root_window();
GtkWidget *topframe=gtk_frame_new (NULL);
GtkWidget *toplabelbox=gtk_event_box_new();
GtkWidget *toplabelframe=gtk_frame_new(NULL);
GtkWidget *toplabel=gtk_hbox_new(0,0);
GtkWidget *toplabelwb=windowbutton_new(prompt);
GtkWidget *toplabelab=0;
if(activebutton && activevar)
toplabelab=gtk_toggle_button_new_with_label(shortcut);
panel->subpanel_windowbutton=toplabelwb;
panel->subpanel_activebutton=toplabelab;
panel->mainpanel_windowbutton=windowbutton;
panel->mainpanel_activebutton=activebutton;
panel->activevar=activevar;
gtk_box_pack_start(GTK_BOX(toplabel),toplabelwb,0,0,5);
gtk_box_pack_end(GTK_BOX(toplabel),toplabelab,0,0,5);
gtk_widget_set_name(toplabelwb,"panelbutton");
gtk_widget_set_name(toplabelbox,"panelbox");
gtk_frame_set_shadow_type(GTK_FRAME(toplabelframe),GTK_SHADOW_ETCHED_IN);
gtk_container_add(GTK_CONTAINER (toplabelbox), toplabelframe);
gtk_container_add(GTK_CONTAINER (toplabelframe), toplabel);
panel->subpanel_box=gtk_vbox_new (0,0);
panel->subpanel_toplevel=gtk_window_new (GTK_WINDOW_TOPLEVEL);
panel->mainpanel=mp;
gtk_container_add (GTK_CONTAINER (panel->subpanel_toplevel), topframe);
gtk_container_add (GTK_CONTAINER (topframe), panel->subpanel_box);
gtk_container_set_border_width (GTK_CONTAINER (topframe), 3);
gtk_container_set_border_width (GTK_CONTAINER (panel->subpanel_box), 5);
gtk_frame_set_shadow_type(GTK_FRAME(topframe),GTK_SHADOW_NONE);
gtk_frame_set_label_widget(GTK_FRAME(topframe),toplabelbox);
/* forward unhandled events to the main window */
g_signal_connect_after (G_OBJECT (panel->subpanel_toplevel), "key-press-event",
G_CALLBACK (forward_events),
panel);
/* delete should == hide */
g_signal_connect (G_OBJECT (panel->mainpanel->toplevel), "delete-event",
G_CALLBACK (clippanel_hide),
panel);
/* link the mainpanel and subpanel buttons */
g_signal_connect_after (G_OBJECT (panel->mainpanel_windowbutton), "clicked",
G_CALLBACK (windowbutton_action), panel);
g_signal_connect_after (G_OBJECT (panel->subpanel_windowbutton), "clicked",
G_CALLBACK (windowbutton_action), panel);
if(activebutton && activevar){
g_signal_connect_after (G_OBJECT (panel->mainpanel_activebutton), "clicked",
G_CALLBACK (activebutton_action), panel);
g_signal_connect_after (G_OBJECT (panel->subpanel_activebutton), "clicked",
G_CALLBACK (activebutton_action), panel);
}
gtk_window_set_resizable(GTK_WINDOW(panel->subpanel_toplevel),0);
return panel;
}
<p><p><p>1.1 postfish/subpanel.h
Index: subpanel.h
===================================================================
/*
*
* postfish
*
* Copyright (C) 2002-2004 Monty
*
* Postfish is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* Postfish is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
typedef struct{
GtkWidget *mainpanel_windowbutton;
GtkWidget *mainpanel_activebutton;
GtkWidget *subpanel_windowbutton;
GtkWidget *subpanel_activebutton;
GtkWidget *subpanel_toplevel;
GtkWidget *subpanel_box;
sig_atomic_t *activevar;
postfish_mainpanel *mainpanel;
} subpanel_generic;
extern subpanel_generic *subpanel_create(postfish_mainpanel *mp,
GtkWidget *windowbutton,
GtkWidget *activebutton,
sig_atomic_t *activevar,
char *prompt,char *shortcut);
<p><p>1.1 postfish/windowbutton.c
Index: windowbutton.c
===================================================================
#include "windowbutton.h"
tatic GtkCheckButtonClass *parent_class = NULL;
tatic void draw_triangle (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
GtkShadowType shadow_type,
gint x,
gint y,
gint size){
GdkGC *gc=style->bg_gc[state_type];
GdkGC *light_gc=style->light_gc[state_type];
GdkGC *dark_gc=style->dark_gc[state_type];
GdkGC *black_gc=style->black_gc;
int i;
/* fill the main triangle */
for(i=0;i<size;i++)
gdk_draw_line(window,gc,x+i,y+((i)>>1),x+i,y+size-1-((i)>>1));
<p> /* draw border */
switch(shadow_type){
case GTK_SHADOW_ETCHED_IN:
for(i=0;i<size;i++){
if(y+size-1-(i>>1) > y+(i>>1)+1){
gdk_draw_point(window,dark_gc,x+i,y+size-1-(i>>1)-1);
gdk_draw_point(window,light_gc,x+i,y+(i>>1)+1);
}
gdk_draw_point(window,light_gc,x+i,y+size-1-(i>>1));
gdk_draw_point(window,dark_gc,x+i,y+(i>>1));
}
gdk_draw_line(window,dark_gc,x,y,x,y+size-1);
gdk_draw_line(window,light_gc,x+1,y+1,x+1,y+size-2);
break;
case GTK_SHADOW_IN:
for(i=0;i<size;i++){
if(y+size-1-(i>>1) > y+(i>>1)+1)
gdk_draw_point(window,black_gc,x+i,y+(i>>1)+1);
gdk_draw_point(window,light_gc,x+i,y+size-1-(i>>1));
gdk_draw_point(window,dark_gc,x+i,y+(i>>1));
}
gdk_draw_line(window,dark_gc,x,y,x,y+size-1);
gdk_draw_line(window,black_gc,x+1,y+1,x+1,y+size-2);
break;
<p> case GTK_SHADOW_OUT:
for(i=0;i<size;i++){
if(y+size-1-(i>>1)-1 > y+(i>>1))
gdk_draw_point(window,dark_gc,x+i,y+size-1-(i>>1)-1);
gdk_draw_point(window,light_gc,x+i,y+(i>>1));
gdk_draw_point(window,black_gc,x+i,y+size-1-(i>>1));
}
gdk_draw_line(window,light_gc,x,y,x,y+size-2);
break;
}
}
tatic void windowbutton_draw_indicator (GtkCheckButton *check_button,
GdkRectangle *area){
GtkWidget *widget;
GtkWidget *child;
GtkButton *button;
GtkToggleButton *toggle_button;
GtkStateType state_type;
GtkShadowType shadow_type;
gint x, y;
gint indicator_size;
gint indicator_spacing;
gint focus_width;
gint focus_pad;
gboolean interior_focus;
if (GTK_WIDGET_DRAWABLE (check_button)){
widget = GTK_WIDGET (check_button);
button = GTK_BUTTON (check_button);
toggle_button = GTK_TOGGLE_BUTTON (check_button);
gtk_widget_style_get (widget, "interior_focus", &interior_focus,
"focus-line-width", &focus_width,
"focus-padding", &focus_pad, NULL);
_gtk_check_button_get_props (check_button, &indicator_size,
&indicator_spacing);
x = widget->allocation.x +
indicator_spacing + GTK_CONTAINER (widget)->border_width;
y = widget->allocation.y +
(widget->allocation.height - indicator_size) / 2;
child = GTK_BIN (check_button)->child;
if (!interior_focus || !(child && GTK_WIDGET_VISIBLE (child)))
x += focus_width + focus_pad;
if (toggle_button->inconsistent)
shadow_type = GTK_SHADOW_ETCHED_IN;
else if (toggle_button->active)
shadow_type = GTK_SHADOW_IN;
else
shadow_type = GTK_SHADOW_OUT;
if (button->activate_timeout || (toggle_button->active))
state_type = GTK_STATE_ACTIVE;
else if (button->in_button)
state_type = GTK_STATE_PRELIGHT;
else if (!GTK_WIDGET_IS_SENSITIVE (widget))
state_type = GTK_STATE_INSENSITIVE;
else
state_type = GTK_STATE_NORMAL;
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
x = widget->allocation.x + widget->allocation.width -
(indicator_size + x - widget->allocation.x);
draw_triangle (widget->style, widget->window,
state_type, shadow_type,
x, y, indicator_size);
}
}
<p>static void windowbutton_class_init (WindowbuttonClass *class){
GtkCheckButtonClass *cb_class = (GtkCheckButtonClass*) class;
parent_class = g_type_class_peek_parent (class);
cb_class->draw_indicator = windowbutton_draw_indicator;
}
tatic void windowbutton_init (Windowbutton *r){
}
GType windowbutton_get_type (void){
static GType m_type = 0;
if (!m_type){
static const GTypeInfo m_info={
sizeof (WindowbuttonClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) windowbutton_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (Windowbutton),
0,
(GInstanceInitFunc) windowbutton_init,
0
};
m_type = g_type_register_static (GTK_TYPE_CHECK_BUTTON, "Windowbutton", &m_info, 0);
}
return m_type;
}
GtkWidget* windowbutton_new (char *markup){
return g_object_new (windowbutton_get_type (),
"label", markup,
"use_underline", TRUE, NULL);
}
<p><p><p><p>1.1 postfish/windowbutton.h
Index: windowbutton.h
===================================================================
#ifndef __WINDOWBUTTON_H__
#define __WINDOWBUTTON_H__
#include <sys/time.h>
#include <time.h>
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtkcheckbutton.h>
G_BEGIN_DECLS
#define WINDOWBUTTON_TYPE (windowbutton_get_type ())
#define WINDOWBUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WINDOWBUTTON_TYPE, Windowbutton))
#define WINDOWBUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WINDOWBUTTON_TYPE, WindowbuttonClass))
#define IS_WINDOWBUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WINDOWBUTTON_TYPE))
#define IS_WINDOWBUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WINDOWBUTTON_TYPE))
typedef struct _Windowbutton Windowbutton;
typedef struct _WindowbuttonClass WindowbuttonClass;
truct _Windowbutton{
GtkCheckButton frame;
};
truct _WindowbuttonClass{
GtkCheckButtonClass parent_class;
void (* windowbutton) (Windowbutton *m);
};
GType windowbutton_get_type (void);
GtkWidget* windowbutton_new (char *markup);
G_END_DECLS
#endif
<p><p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list