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

Monty xiphmont at xiph.org
Tue Feb 17 03:52:20 PST 2004



xiphmont    04/02/17 06:52:19

  Modified:    .        Makefile clippanel.h main.c mainpanel.c mainpanel.h
                        multibar.c multibar.h postfish-gtkrc postfish.h
                        readout.c readout.h version.h
  Added:       .        eq.c eq.h eqpanel.c eqpanel.h freq.c freq.h
  Log:
  add bounded trough to multibar

Revision  Changes    Path
1.12      +6 -4      postfish/Makefile

Index: Makefile
===================================================================
RCS file: /usr/local/cvsroot/postfish/Makefile,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Makefile	26 Dec 2003 09:55:56 -0000	1.11
+++ Makefile	17 Feb 2004 11:52:17 -0000	1.12
@@ -10,10 +10,12 @@
 ETCDIR=/etc
 MANDIR=$PREFIX/man
 
-SRC = main.c mainpanel.c multibar.c readout.c input.c output.c clippanel.c declip.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 windowbutton.o subpanel.o feedback.o
+SRC = main.c mainpanel.c multibar.c readout.c input.c output.c clippanel.c \
+	declip.c reconstruct.c smallft.c windowbutton.c subpanel.c \
+	feedback.c freq.c eq.c eqpanel.c
+OBJ = main.o mainpanel.o multibar.o readout.o input.o output.o clippanel.o \
+	declip.o reconstruct.o smallft.o windowbutton.o subpanel.o \
+	feedback.o freq.o eq.o eqpanel.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.3       +23 -0     postfish/clippanel.h

Index: clippanel.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/clippanel.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- clippanel.h	24 Dec 2003 09:49:16 -0000	1.2
+++ clippanel.h	17 Feb 2004 11:52:17 -0000	1.3
@@ -1,3 +1,26 @@
+/*
+ *
+ *  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 clippanel_create(postfish_mainpanel *mp,

<p><p>1.9       +1 -0      postfish/main.c

Index: main.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/main.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- main.c	24 Dec 2003 09:49:16 -0000	1.8
+++ main.c	17 Feb 2004 11:52:17 -0000	1.9
@@ -43,6 +43,7 @@
   if(input_load(argc-1,argv+1))exit(1);
   /* set up filter chains */
   if(declip_load())exit(1);
+  if(eq_load())exit(1);
 
   /* look at stdout... do we have a file or device? */
   if(!isatty(STDOUT_FILENO)){

<p><p>1.29      +32 -3     postfish/mainpanel.c

Index: mainpanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/mainpanel.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- mainpanel.c	16 Feb 2004 05:00:54 -0000	1.28
+++ mainpanel.c	17 Feb 2004 11:52:17 -0000	1.29
@@ -1,3 +1,25 @@
+/*
+ *
+ *  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>
@@ -61,6 +83,7 @@
   multibar_reset(MULTIBAR(p->inbar));
   multibar_reset(MULTIBAR(p->outbar));
   clippanel_reset();
+  eqpanel_reset();
 }
 
 static void action_end(GtkWidget *widget,postfish_mainpanel *p){
@@ -74,6 +97,7 @@
   multibar_reset(MULTIBAR(p->inbar));
   multibar_reset(MULTIBAR(p->outbar));
   clippanel_reset();
+  eqpanel_reset();
 }
 
 static void action_bb(GtkWidget *widget,postfish_mainpanel *p){
@@ -631,16 +655,20 @@
     {
       GtkWidget *box=gtk_hbox_new(0,0);
 
-      panel->masterdB_a=gtk_toggle_button_new_with_label("[m]aster");
+      GtkWidget *masterlabel=gtk_label_new("master:");
+      panel->masterdB_a=gtk_toggle_button_new_with_label("[m] active");
       panel->masterdB_r=readout_new("  0.0 dB");
       panel->masterdB_s=gtk_hscale_new_with_range(-50,50,.1);
 
+      gtk_misc_set_alignment(GTK_MISC(masterlabel),1,.5);
+
       gtk_range_set_value(GTK_RANGE(panel->masterdB_s),0);
       gtk_scale_set_draw_value(GTK_SCALE(panel->masterdB_s),FALSE);
     
-      gtk_table_attach(GTK_TABLE(ttable),panel->masterdB_a,0,1,3,4,
+      gtk_table_attach(GTK_TABLE(ttable),masterlabel,0,1,3,4,
                        GTK_FILL,GTK_FILL,0,0);
       
+      gtk_box_pack_start(GTK_BOX(box),panel->masterdB_a,0,0,2);
       gtk_box_pack_start(GTK_BOX(box),panel->masterdB_r,0,0,0);
       gtk_box_pack_start(GTK_BOX(box),panel->masterdB_s,1,1,0);
       
@@ -826,7 +854,7 @@
   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,"_Equalizer ","[e]",3,eqpanel_create);
   mainpanel_panelentry(panel,"_Compander ","[c]",4,0);
   mainpanel_panelentry(panel,"_Limiter ","[l]",5,0);
   mainpanel_panelentry(panel,"_Output Cal. ","[o]",6,0);
@@ -896,6 +924,7 @@
       }
 
       clippanel_feedback();
+      eqpanel_feedback();
       
     }
   }

<p><p>1.6       +24 -0     postfish/mainpanel.h

Index: mainpanel.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/mainpanel.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- mainpanel.h	24 Dec 2003 09:49:16 -0000	1.5
+++ mainpanel.h	17 Feb 2004 11:52:17 -0000	1.6
@@ -1,9 +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"
 
 struct postfish_mainpanel;
 typedef struct postfish_mainpanel postfish_mainpanel;
 
 #include "clippanel.h"
+#include "eqpanel.h"
 
 struct postfish_mainpanel{
   GtkWidget *topframe;

<p><p>1.18      +80 -16    postfish/multibar.c

Index: multibar.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/multibar.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- multibar.c	16 Feb 2004 05:00:54 -0000	1.17
+++ multibar.c	17 Feb 2004 11:52:17 -0000	1.18
@@ -1,3 +1,26 @@
+/*
+ *
+ *  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 <stdio.h>
 #include <stdlib.h>
 #include <math.h>
@@ -352,27 +375,55 @@
     /* blank side padding to bg of parent */
     gdk_draw_rectangle(m->backing,gc,1,0,0,xpad,height);
     gdk_draw_rectangle(m->backing,gc,1,width,0,xpad,height);
-    
-    /* dark trough */
-    gdk_draw_rectangle(m->backing,mid_gc,1,
-		       xpad,height-lpad,width-xpad,lpad);
 
+
+    /* blank sides of trough */
+    gdk_draw_rectangle(m->backing,gc,1,
+		       0,height-lpad,
+		       m->thumblo_x+xpad,lpad);
+    gdk_draw_rectangle(m->backing,gc,1,
+		       m->thumbhi_x+xpad,height-lpad,
+		       width-m->thumbhi_x,lpad);
+    
     /* frame */
     gdk_draw_line(m->backing,dark_gc,xpad-1,0,width,0);
-    gdk_draw_line(m->backing,dark_gc,xpad-1,0,xpad-1,height-2);
-
-    gdk_draw_line(m->backing,light_gc,xpad-1,height-1,width+1,height-1);
-    gdk_draw_line(m->backing,light_gc,width+1,0,width+1,height-1);
-
+    gdk_draw_line(m->backing,dark_gc,xpad-1,0,xpad-1,height-lpad);
     gdk_draw_line(m->backing,dark_gc,xpad,height-lpad,width,height-lpad);
     gdk_draw_line(m->backing,dark_gc,width,height-lpad,width,1);
 
-
+    gdk_draw_line(m->backing,light_gc,xpad-1,height-lpad+1,
+		  width+1,height-lpad+1);
+    gdk_draw_line(m->backing,light_gc,width+1,0,width+1,height-lpad+1);
     gdk_draw_line(m->backing,light_gc,xpad,1,width-1,1);
-    if(lpad>2)
-      gdk_draw_line(m->backing,light_gc,xpad,1,xpad,height-lpad);
-    else
-      gdk_draw_line(m->backing,light_gc,xpad,1,xpad,height-lpad-1);
+    gdk_draw_line(m->backing,light_gc,xpad,1,xpad,height-lpad-1);
+
+
+
+    /* dark trough */
+    if(lpad>2){
+      gdk_draw_rectangle(m->backing,mid_gc,1,
+			 xpad+m->thumblo_x,height-lpad+1,
+			 m->thumbhi_x-m->thumblo_x+1,lpad-1);
+
+      gdk_draw_line(m->backing,dark_gc,
+		    m->thumblo_x+xpad-1,height-lpad+1,
+		    m->thumblo_x+xpad-1,height-1);
+
+      gdk_draw_line(m->backing,light_gc,
+		    m->thumblo_x+xpad-1,height-1,
+		    m->thumbhi_x+xpad+1,height-1);
+
+      gdk_draw_line(m->backing,light_gc,
+		    m->thumbhi_x+xpad+1,height-1,
+		    m->thumbhi_x+xpad+1,height-lpad+1);
+
+      dark_gc=widget->style->dark_gc[GTK_STATE_ACTIVE];
+      gdk_draw_line(m->backing,dark_gc,
+		    m->thumblo_x+xpad,height-lpad,
+		    m->thumbhi_x+xpad,height-lpad);
+      
+
+    }
 
   }
 
@@ -718,6 +769,9 @@
   compute(widget,0,0,0);
   for(i=0;i<m->thumbs;i++)
     m->thumbpixel[i]=val_to_pixel(widget,m->thumbval[i]);
+  m->thumblo_x=val_to_pixel(widget,m->thumblo);
+  m->thumbhi_x=val_to_pixel(widget,m->thumbhi);
+
   draw_and_expose(widget);
 
   return TRUE;
@@ -914,9 +968,7 @@
 static GtkDrawingAreaClass *parent_class = NULL;
 
 static void multibar_class_init (MultibarClass *class){
-  GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
-  GdkWindow *root=gdk_get_default_root_window();
   parent_class = g_type_class_peek_parent (class);
 
   widget_class->expose_event = expose;
@@ -985,6 +1037,8 @@
   m->thumbgrab=-1;
   m->thumblo=levels[0];
   m->thumbhi=levels[n];
+  m->thumblo_x=val_to_pixel(ret,m->thumblo);
+  m->thumbhi_x=val_to_pixel(ret,m->thumbhi);
 
   if(thumbs<0)thumbs=0;
   if(thumbs>3)thumbs=3;
@@ -1094,12 +1148,22 @@
 void multibar_thumb_bounds(Multibar *m,double lo, double hi){
   GtkWidget *w=GTK_WIDGET(m);
   if(lo>hi)return;
+
+  if(lo<m->levels[0])lo=m->levels[0];
+  if(hi<m->levels[0])hi=m->levels[0];
+  if(lo>m->levels[m->labels])lo=m->levels[m->labels];
+  if(hi>m->levels[m->labels])hi=m->levels[m->labels];
+
   m->thumblo=lo;
   m->thumbhi=hi;
 
+  m->thumblo_x=val_to_pixel(w,lo);
+  m->thumbhi_x=val_to_pixel(w,hi);
+
   vals_bound(m);
   if(m->callback)m->callback(GTK_WIDGET(m),m->callbackp);
   draw_and_expose(w);
 }
 
 
+

<p><p>1.10      +26 -0     postfish/multibar.h

Index: multibar.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/multibar.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- multibar.h	16 Feb 2004 05:00:54 -0000	1.9
+++ multibar.h	17 Feb 2004 11:52:18 -0000	1.10
@@ -1,3 +1,26 @@
+/*
+ *
+ *  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.
+ *
+ * 
+ */
+
 #ifndef __MULTIBAR_H__
 #define __MULTIBAR_H__
 
@@ -66,6 +89,9 @@
   double    thumblo;
   double    thumbhi;
 
+  int    thumblo_x;
+  int    thumbhi_x;
+
   int       xpad;
 
   void  (*callback)(GtkWidget *,gpointer);

<p><p>1.5       +2 -6      postfish/postfish-gtkrc

Index: postfish-gtkrc
===================================================================
RCS file: /usr/local/cvsroot/postfish/postfish-gtkrc,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- postfish-gtkrc	16 Feb 2004 05:00:54 -0000	1.4
+++ postfish-gtkrc	17 Feb 2004 11:52:18 -0000	1.5
@@ -50,7 +50,7 @@
 
         text[NORMAL]="#c0c0d0" 
         text[ACTIVE]="#ffb0b0" 
-        font_name = "sans 8"    
+        font_name = "sans 6"    
 }
 
 style "clipbar" {
@@ -67,11 +67,7 @@
         bg[NORMAL]="#ffffff" 
         bg[ACTIVE]="#ffffff" 
 
-	font_name = "fixed 8"	
-	GtkMisc::xpad = 10
-	GtkMisc::xalign = 1.0
-	GtkWidget::width-request=100
-	GtkLabel::justify = right
+	font_name = "Nimbus Mono L, Courier New, Monospace 8"	
 }
 
 style "darkpanel" {

<p><p>1.10      +1 -0      postfish/postfish.h

Index: postfish.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/postfish.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- postfish.h	20 Dec 2003 11:24:17 -0000	1.9
+++ postfish.h	17 Feb 2004 11:52:18 -0000	1.10
@@ -53,6 +53,7 @@
 #define todB(x)   ((x)==0?-400.f:log((x)*(x))*4.34294480f)
 #define fromdB(x) (exp((x)*.11512925f))  
 #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)
 

<p><p>1.6       +124 -33   postfish/readout.c

Index: readout.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/readout.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- readout.c	15 Feb 2004 15:14:15 -0000	1.5
+++ readout.c	17 Feb 2004 11:52:18 -0000	1.6
@@ -1,41 +1,130 @@
+/*
+ *
+ *  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 <stdlib.h>
 #include "readout.h"
 
-static GtkFrameClass *parent_class = NULL;
+static GtkDrawingAreaClass *parent_class = NULL;
+
+static void draw(GtkWidget *widget){
+  Readout *r=READOUT(widget);
+
+  int width=widget->allocation.width;
+  int height=widget->allocation.height;
+  int px,py;
+  GdkGC *gc=widget->style->bg_gc[0];
+  GdkGC *text_gc=widget->style->text_gc[0];
+  GdkGC *light_gc=widget->style->light_gc[0];
+  GdkGC *dark_gc=widget->style->dark_gc[0];
+
+  /* blank pane */
+  
+  gdk_draw_rectangle(r->backing,gc,1,
+		     0,0,width,height);
+
+  /* draw layout */
+  pango_layout_get_pixel_size(r->layout,&px,&py);
+
+  gdk_draw_layout (r->backing,text_gc,
+		   width-2-px-(py/2),(height-py)/2,
+		   r->layout);
+  
+  /* draw frame */
+  gdk_draw_rectangle(r->backing,dark_gc,0,
+		     0,0,width-2,height-2);
+
+  gdk_draw_line(r->backing,light_gc,1,1,width-3,1);
+  gdk_draw_line(r->backing,light_gc,1,1,1,height-3);
+
+  gdk_draw_line(r->backing,light_gc,width-1,0,width-1,height-1);
+  gdk_draw_line(r->backing,light_gc,0,height-1,width-1,height-1);
+
+}
+
+static void draw_and_expose(GtkWidget *widget){
+  Readout *r=READOUT(widget);
+  if(!GDK_IS_DRAWABLE(r->backing))return;
+  draw(widget);
+  if(!GTK_WIDGET_DRAWABLE(widget))return;
+  if(!GDK_IS_DRAWABLE(widget->window))return;
+  gdk_draw_drawable(widget->window,
+                    widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                    r->backing,
+                    0, 0,
+                    0, 0,
+                    widget->allocation.width,             
+                    widget->allocation.height);
+}
+
+static gboolean expose( GtkWidget *widget, GdkEventExpose *event ){
+  Readout *r=READOUT(widget);
+  gdk_draw_drawable(widget->window,
+                    widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                    r->backing,
+                    event->area.x, event->area.y,
+                    event->area.x, event->area.y,
+                    event->area.width, event->area.height);
+  
+  return FALSE;
+}
+
+static void size_request (GtkWidget *widget,GtkRequisition *requisition){
+  int x,y;
+  Readout *r=READOUT(widget);
+  
+  pango_layout_get_pixel_size(r->layout,&x,&y);
+  
+  requisition->width = x+4+y;
+  requisition->height = y+6;
+
+}
+
+static gboolean configure(GtkWidget *widget, GdkEventConfigure *event){
+  Readout *r=READOUT(widget);
+  
+  if (r->backing)
+    gdk_drawable_unref(r->backing);
+  
+  r->backing = gdk_pixmap_new(widget->window,
+                              widget->allocation.width,
+                              widget->allocation.height,
+                              -1);
+  draw_and_expose(widget);
+
+  return TRUE;
+}
 
 static void readout_class_init (ReadoutClass *class){
   GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
   parent_class = g_type_class_peek_parent (class);
 
+  widget_class->expose_event = expose;
+  widget_class->configure_event = configure;
+  widget_class->size_request = size_request;
 }
 
 static void readout_init (Readout *r){
-  GtkWidget *widget=GTK_WIDGET(r);
-  GtkWidget *notebook=gtk_notebook_new();
-  GtkWidget *box=gtk_event_box_new();
-  
-  gtk_notebook_popup_disable(GTK_NOTEBOOK(notebook));
-  gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook),FALSE);
-  gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook),FALSE);
-  gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook),FALSE);
-
-  r->sizelabel=gtk_label_new(NULL);
-  r->label=gtk_label_new(NULL);
-  gtk_container_add(GTK_CONTAINER(box),r->label);
-  
-  gtk_container_add(GTK_CONTAINER(widget),notebook);
-  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),box,NULL);
-  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),r->sizelabel,NULL);
-
-  gtk_misc_set_alignment(GTK_MISC(r->label),1.0,.5);
-  gtk_misc_set_padding(GTK_MISC(r->label),4,3);
-  gtk_misc_set_padding(GTK_MISC(r->sizelabel),4,3);
-
-  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook),0);
-
-  gtk_widget_show(notebook);
-  gtk_widget_show(box);
-  gtk_widget_show(r->label);
-  gtk_widget_show(r->sizelabel);
+
 }
 
 GType readout_get_type (void){
@@ -54,7 +143,7 @@
       0
     };
     
-    m_type = g_type_register_static (GTK_TYPE_FRAME, "Readout", &m_info, 0);
+    m_type = g_type_register_static (GTK_TYPE_DRAWING_AREA, "Readout", &m_info, 0);
   }
 
   return m_type;
@@ -64,17 +153,19 @@
   GtkWidget *ret= GTK_WIDGET (g_object_new (readout_get_type (), NULL));
   Readout *r=READOUT(ret);
 
-  gtk_label_set_markup(GTK_LABEL(r->sizelabel),markup);
-  readout_set(r,markup);
+  r->layout=calloc(1,sizeof(r->layout));
+  r->layout=gtk_widget_create_pango_layout(ret,markup);
+
   return ret;
 }
 
 void readout_set(Readout  *r,char *label){
-  gtk_label_set_markup(GTK_LABEL(r->label),label);
+  pango_layout_set_text(r->layout,label,-1);
+  draw_and_expose(GTK_WIDGET(r));
 }
 
 const gchar *readout_get(Readout  *r){
-  return gtk_label_get_label(GTK_LABEL(r->label));
+  return  pango_layout_get_text(r->layout);
 }
 
 

<p><p>1.4       +28 -8     postfish/readout.h

Index: readout.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/readout.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- readout.h	18 Oct 2003 08:10:49 -0000	1.3
+++ readout.h	17 Feb 2004 11:52:18 -0000	1.4
@@ -1,3 +1,26 @@
+/*
+ *
+ *  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.
+ *
+ * 
+ */
+
 #ifndef __READOUT_H__
 #define __READOUT_H__
 
@@ -6,10 +29,7 @@
 #include <glib.h>
 #include <glib-object.h>
 #include <gtk/gtkcontainer.h>
-#include <gtk/gtkframe.h>
-#include <gtk/gtknotebook.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkeventbox.h>
+#include <gtk/gtkdrawingarea.h>
 
 G_BEGIN_DECLS
 
@@ -24,14 +44,14 @@
 
 struct _Readout{
 
-  GtkFrame frame;
-  GtkWidget *label;
-  GtkWidget *sizelabel;
+  GtkDrawingArea canvas;  
+  GdkPixmap *backing;
+  PangoLayout *layout;
 };
 
 struct _ReadoutClass{
 
-  GtkFrameClass parent_class;
+  GtkDrawingAreaClass parent_class;
   void (* readout) (Readout *m);
 
 };

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

Index: version.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/version.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- version.h	16 Feb 2004 05:00:54 -0000	1.29
+++ version.h	17 Feb 2004 11:52:18 -0000	1.30
@@ -1,2 +1,2 @@
-#define VERSION "$Id: version.h,v 1.29 2004/02/16 05:00:54 xiphmont Exp $ "
-/* DO NOT EDIT: Automated versioning hack [Mon Feb 16 00:00:26 EST 2004] */
+#define VERSION "$Id: version.h,v 1.30 2004/02/17 11:52:18 xiphmont Exp $ "
+/* DO NOT EDIT: Automated versioning hack [Tue Feb 17 06:50:57 EST 2004] */

<p><p>1.1                  postfish/eq.c

Index: eq.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"
#include "freq.h"
#include "eq.h"

extern int input_size;

ig_atomic_t eq_active;

freq_state eq;

int pull_eq_feedback(double **peak,double **rms){
  return pull_freq_feedback(&eq,peak,rms);
}

/* called only by initial setup */
int eq_load(void){
  return freq_load(&eq,input_size);
}

/* called only in playback thread */
int eq_reset(){
  return freq_reset(&eq);
}

tatic void workfunc(double *data,freq_state *f,
                     double *peak, double *rms){

  return;
}

/* called only by playback thread */
time_linkage *eq_read(time_linkage *in){
  return freq_read(in,&eq,workfunc);
}

<p><p>1.1                  postfish/eq.h

Index: eq.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.
 *
 * 
 */

#include "postfish.h"

extern int pull_eq_feedback(double **peak,double **rms);
extern int eq_load(void);
extern int eq_reset();
extern time_linkage *eq_read(time_linkage *in);

<p><p>1.1                  postfish/eqpanel.c

Index: eqpanel.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 "readout.h"
#include "multibar.h"
#include "mainpanel.h"
#include "subpanel.h"
#include "feedback.h"
#include "freq.h"
#include "eq.h"

extern sig_atomic_t eq_active;
extern int input_ch;
extern int input_size;
extern int input_rate;

typedef struct {
  GtkWidget *slider;
  GtkWidget *readout;
  int number;
} bar;

bar bars[freqs];

tatic void slider_change(GtkWidget *w,gpointer in){
  char buffer[80];
  bar *b=(bar *)in;
  gdouble val=multibar_get_value(MULTIBAR(b->slider),0);
  
  sprintf(buffer,"%+5.1f dB",val);
  readout_set(READOUT(b->readout),buffer);
  
  //eq_setlevel(val,p->number);

}

void eqpanel_create(postfish_mainpanel *mp,
                    GtkWidget *windowbutton,
                    GtkWidget *activebutton){
  int i;
  char *labels[15]={"-110","-100","-90","-80","-70","-60","-50","-40",
                    "-30","-20","-10","0","+10","+20","+30"};
  double levels[16]={-120,-110,-100,-90,-80,-70,-60,-50,-40,
                     -30,-20,-10,0,10,20,30};

  subpanel_generic *panel=subpanel_create(mp,windowbutton,activebutton,
                                          &eq_active,
                                          "_Equalization filter"," [e] ");
  
  GtkWidget *slidertable=gtk_table_new(freqs,3,0);

  for(i=0;i<freqs;i++){
    const char *labeltext="";
    if((i&1)==0)labeltext=freq_frequency_label(i);

    GtkWidget *label=gtk_label_new(labeltext);
    bars[i].readout=readout_new("+00.0 dB");
    bars[i].slider=multibar_new(15,labels,levels,1,
                                LO_ATTACK|LO_DECAY|HI_DECAY);
    bars[i].number=i;

    multibar_callback(MULTIBAR(bars[i].slider),slider_change,bars+i);
    multibar_thumb_set(MULTIBAR(bars[i].slider),0.,0);
    multibar_thumb_bounds(MULTIBAR(bars[i].slider),-60,30);

    gtk_misc_set_alignment(GTK_MISC(label),1,.5);

    gtk_table_attach(GTK_TABLE(slidertable),label,0,1,i,i+1,
                     GTK_FILL,0,10,0);
    gtk_table_attach(GTK_TABLE(slidertable),bars[i].readout,1,2,i,i+1,
                     GTK_FILL,0,0,0);
    gtk_table_attach(GTK_TABLE(slidertable),bars[i].slider,2,3,i,i+1,
                     GTK_FILL|GTK_EXPAND,GTK_FILL|GTK_EXPAND,0,0);
  }

  gtk_box_pack_start(GTK_BOX(panel->subpanel_box),slidertable,1,1,4);

}

void eqpanel_feedback(void){
#if 0
  int clip[input_ch],count;
  double peak[input_ch];
  if(pull_declip_feedback(clip,peak,&count)){
    int i;
    for(i=0;i<input_ch;i++){
      double val[2],zero[2];
      val[0]=-1.,zero[0]=-1.;
      val[1]=(count?clip[i]*100./count-.1:-1);
      zero[1]=-1.;
      multibar_set(MULTIBAR(feedback_bars[i]),zero,val,2);
      val[1]=(count?peak[i]:-1);
      multibar_set(MULTIBAR(trigger_bars[i]),zero,val,2);
      if(clip[i]){
        multibar_setwarn(MULTIBAR(mainpanel_inbar));
        multibar_setwarn(MULTIBAR(feedback_bars[i]));
        multibar_setwarn(MULTIBAR(trigger_bars[i]));
      }
    }
  }
#endif
}

void eqpanel_reset(void){
  int i;
  for(i=0;i<freqs;i++)
    multibar_reset(MULTIBAR(bars[i].slider));
}

<p><p>1.1                  postfish/eqpanel.h

Index: eqpanel.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.
 *
 * 
 */

#include "postfish.h"
extern void eqpanel_create(postfish_mainpanel *mp,
                           GtkWidget *windowbutton,
                           GtkWidget *activebutton);
extern void eqpanel_feedback(void);
extern void eqpanel_reset(void);

<p><p>1.1                  postfish/freq.c

Index: freq.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 <math.h>
#include <sys/types.h>
#include "feedback.h"
#include "freq.h"

extern int input_rate;
extern int input_ch;
extern int input_size;

/* feedback! */
typedef struct freq_feedback{
  feedback_generic parent_class;
  double **peak;
  double **rms;
} freq_feedback;

/* accessed only in playback thread/setup */
static double frequencies[freqs+1];
static char *freq_labels[freqs]={
  "31", "37","44","53",
  "63", "75","88","105",
  "125","150","180","210",
  "250","300","350","420",
  "500","600", "700", "840",
  "1k", "1.2k", "1.4k", "1.7k",
  "2k", "2.4k", "2.8k", "3.4k",
  "4k", "4.8k", "5.6k", "6.7k",
  "8k", "9.5k", "11k", "13k",
  "16k","19k",  "22k"
};

void _analysis(char *base,int i,double *v,int n,int bark,int dB){
  int j;
  FILE *of;
  char buffer[80];

  sprintf(buffer,"%s_%d.m",base,i);
  of=fopen(buffer,"w");
  
  if(!of)perror("failed to open data dump file");
  
  for(j=0;j<n;j++){
    if(bark){
      float b=toBark((4000.f*j/n)+.25);
      fprintf(of,"%f ",b);
    }else
      fprintf(of,"%f ",(double)j);
    
    if(dB){
      if(j==0||j==n-1)
        fprintf(of,"%f\n",todB(v[j]));
      else{
        fprintf(of,"%f\n",todB(hypot(v[j],v[j+1])));
        j++;
      }
    }else{
      fprintf(of,"%f\n",v[j]);
    }
  }
  fclose(of);
}

tatic feedback_generic *new_freq_feedback(void){
  int i;
  freq_feedback *ret=malloc(sizeof(*ret));
  ret->peak=malloc(input_ch*sizeof(*ret->peak));
  ret->rms=malloc(input_ch*sizeof(*ret->rms));

  for(i=0;i<input_ch;i++){
    ret->peak[i]=malloc(freqs*sizeof(**ret->peak));
    ret->rms[i]=malloc(freqs*sizeof(**ret->rms));
  }

  return (feedback_generic *)ret;
}

/* total, peak, rms are pulled in array[freqs][input_ch] order */

int pull_freq_feedback(freq_state *ff,double **peak,double **rms){
  freq_feedback *f=(freq_feedback *)feedback_pull(&ff->feedpool);
  int i,j;
  
  if(!f)return 0;
  
  if(peak)
    for(i=0;i<freqs;i++)
      for(j=0;j<input_ch;j++)
        peak[i][j]=f->peak[j][i];

  if(rms)
    for(i=0;i<freqs;i++)
      for(j=0;j<input_ch;j++)
        rms[i][j]=f->rms[j][i];
  
  feedback_old(&ff->feedpool,(feedback_generic *)f);
  return 1;
}

/* called only by initial setup */
int freq_load(freq_state *f,int blocksize){
  int i,j;
  
  memset(f,0,sizeof(*f));

  drft_init(&f->fft,blocksize*2);
  f->blocksize=blocksize;
  
  f->fillstate=0;
  f->cache_samples=0;
  f->cache=malloc(input_ch*sizeof(*f->cache));
  for(i=0;i<input_ch;i++)
    f->cache[i]=malloc(input_size*sizeof(**f->cache));
  f->lap=malloc(input_ch*sizeof(*f->lap));
  for(i=0;i<input_ch;i++)
    f->lap[i]=malloc(input_size*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.data[i]=malloc(input_size*sizeof(**f->out.data));

  /* fill out the frequencies we potentially offer */
  /* yes this gets repeated.  it's pre-threading, not a big deal */
  for(i=0;i<freqs;i++)
    frequencies[i]=fromOC(i*.25-1.);
  frequencies[freqs-1]=22000.;
  frequencies[freqs]=1e20;

<p>  /* unlike old postfish, we offer all frequencies via smoothly
     supersampling the spectrum */
  /* I'm too lazy to figure out the integral symbolically, use this
     fancy CPU-thing for something */
  
  f->ho_window=malloc(freqs*sizeof(*f->ho_window));
  {
    double lastf=0.;
    double *working=alloca((blocksize+1)*sizeof(*working));

    for(i=0;i<freqs;i++){
      double thisf=frequencies[i];
      double nextf=frequencies[i+1];

      /* conceptually simple, easy to verify, absurdly inefficient,
         but hey, we're only doing it at init */
      memset(working,0,sizeof(*working)*(blocksize+1));
      
      for(j=0;j<((blocksize+1)<<5);j++){
        double localf= .5*j*input_rate/(blocksize<<5);
        int localbin= j>>5;
        double 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);

        }else if(localf>=thisf && localf<nextf){
          if(i+1==freqs)
            localwin=1.;
          else
            localwin= sin((nextf-localf)/(nextf-thisf)*M_PIl*.5);
          
          localwin*=localwin;
          working[localbin]+=localwin*(1./32);
          
        }
      }

      /* now take what we learned and distill it a bit */
      for(j=0;j<blocksize+1;j++)if(working[j]!=0.)break;
      f->ho_bin_lo[i]=j;
      for(;j<blocksize+1;j++)if(working[j]==0.)break;
      f->ho_bin_hi[i]=j;
      f->ho_window[i]=malloc((f->ho_bin_hi[i]-f->ho_bin_lo[i])*
                             sizeof(**f->ho_window));
      for(j=f->ho_bin_lo[i];j<f->ho_bin_hi[i];j++)
        f->ho_area[i]+=f->ho_window[i][j-f->ho_bin_lo[i]]=working[j];

      f->ho_area[i]=1./f->ho_area[i];
      lastf=thisf;

    }
  }
      
  /* fill in time window */
  f->window=malloc(blocksize*sizeof(*f->window)); 
  /* we actually use 2x blocks, but the window is nonzero only in half */
  
  for(i=0;i<blocksize;i++)f->window[i]=sin(M_PIl*i/blocksize);
  for(i=0;i<blocksize;i++)f->window[i]*=f->window[i];
  for(i=0;i<blocksize;i++)f->window[i]=sin(f->window[i]*M_PIl*.5);

  return(0);
}

/* called only in playback thread */
int freq_reset(freq_state *f){
  /* reset cached pipe state */
  f->fillstate=0;
  while(pull_freq_feedback(f,NULL,NULL));
  return 0;
}

const char *freq_frequency_label(int n){
  if(n<0)return "";
  if(n>freqs)return "";
  return freq_labels[n];
}

tatic void transform_work(double *work,freq_state *f,double *peak,double *rms){
  double *workoff=work+f->blocksize/2;
  int i,j,k;
  
  /* window the time data */
  memset(work,0,sizeof(*work)*f->blocksize);
  memset(work+f->blocksize*3/2,0,sizeof(*work)*f->blocksize/2);
  for(i=0;i<f->blocksize;i++)workoff[i]*=f->window[i];
  
  /* transform the time data */
  drft_forward(&f->fft,work);
  for(i=0;i<f->blocksize;i++)workoff[i]*=(1./f->blocksize);

  /* fill in metrics */
  memset(peak,0,sizeof(*peak)*freqs);
  memset(rms,0,sizeof(*rms)*freqs);
  {
    double sq_mags[f->blocksize+1];
    sq_mags[0]=work[0]*work[0];
    sq_mags[f->blocksize]=work[f->blocksize*2-1]*work[f->blocksize*2-1];
    for(i=1;i<f->blocksize;i++)
      sq_mags[i]=work[i*2]*work[i*2]+work[i*2-1]*work[i*2-1];

    for(i=0;i<freqs;i++){
      double *ho_window=f->ho_window[i];
      for(k=0,j=f->ho_bin_lo[i];j<f->ho_bin_hi[i];j++,k++){
        double val=sq_mags[j]*ho_window[k];
        rms[i]+=val;
        if(val>peak[i])peak[i]=val;
      }
      rms[i]=sqrt(rms[i]*f->ho_area[i]);
      peak[i]=sqrt(peak[i]);
    }
  }
}

tatic void feedback_work(double *peak,double *rms,
                   double *feedback_peak,double *feedback_rms){
  int i;
  for(i=0;i<freqs;i++){
    feedback_rms[i]+=rms[i]*rms[i];
    if(feedback_peak[i]<peak[i])feedback_peak[i]=peak[i];
  }
}

tatic void lap_work(double *work,double *lap,double *out,freq_state *f){
  double *workoff=work+f->blocksize/2;
  int i,j;

  /* back to time we go */
  drft_backward(&f->fft,work);
  
  /* lap and out */
  if(out)
    for(i=0;i<f->blocksize/2;i++)
      out[i]=lap[i]+workoff[i]*f->window[i];
  
  for(i=f->blocksize/2,j=0;i<f->blocksize;i++)
    lap[j++]=workoff[i]*f->window[i];

}

<p>/* called only by playback thread */
time_linkage *freq_read(time_linkage *in, freq_state *f,
                        void (*func)(double *data,freq_state *f,
                                     double *peak, double *rms)){
  int i;

  double feedback_peak[input_ch][freqs];
  double feedback_rms[input_ch][freqs];

  double peak[freqs];
  double rms[freqs];

  int blocks=0;

  memset(peak,0,sizeof(peak));
  memset(rms,0,sizeof(rms));

  {
    double work[f->blocksize*2];
    
    switch(f->fillstate){
    case 0: /* prime the lapping and cache */
      for(i=0;i<input_ch;i++){
        double *temp=in->data[i];

        memset(work+f->blocksize/2,0,sizeof(*work)*f->blocksize/2);
        memcpy(work+f->blocksize,temp,sizeof(*work)*f->blocksize/2);

        transform_work(work,f,peak,rms);
        func(work,f,peak,rms);
        feedback_work(peak,rms,feedback_peak[i],feedback_rms[i]);
        lap_work(work,f->lap[i],0,f);
        blocks++;	

        memset(f->cache[i],0,sizeof(**f->cache)*input_size);
        in->data[i]=f->cache[i];
        f->cache[i]=temp;
      }
      f->cache_samples=in->samples;
      f->fillstate=1;
      f->out.samples=0;
      if(in->samples==in->size)goto tidy_up;
        
      for(i=0;i<input_ch;i++)
        memset(in->data[i],0,sizeof(**in->data)*in->size);
      in->samples=0;
      /* fall through */
    case 1: /* nominal processing */
      for(i=0;i<input_ch;i++){
        double *temp=f->cache[i];
        int j;
        for(j=0;j+f->blocksize<=f->out.size;j+=f->blocksize/2){

          memset(work,0,sizeof(*work)*f->blocksize/2);
          memcpy(work+f->blocksize/2,temp+j,sizeof(*work)*f->blocksize);
          memset(work+f->blocksize*3/2,0,sizeof(*work)*f->blocksize/2);

          transform_work(work,f,&peak[i],&rms[i]);
          func(work,f,peak,rms);
          feedback_work(peak,rms,feedback_peak[i],feedback_rms[i]);
          lap_work(work,f->lap[i],f->out.data[i]+j,f);
          blocks++;	
        }

        memset(work,0,sizeof(*work)*f->blocksize/2);
        memcpy(work+f->blocksize/2,temp+j,sizeof(*work)*f->blocksize/2);
        memcpy(work+f->blocksize,in->data[i],sizeof(*work)*f->blocksize/2);
        memset(work+f->blocksize*3/2,0,sizeof(*work)*f->blocksize/2);
        
        transform_work(work,f,&peak[i],&rms[i]);
        func(work,f,peak,rms);
        feedback_work(peak,rms,feedback_peak[i],feedback_rms[i]);
        lap_work(work,f->lap[i],f->out.data[i]+j,f);
        blocks++;	
        
        f->cache[i]=in->data[i];
        in->data[i]=temp;
      }
      f->out.samples=f->cache_samples;
      f->cache_samples=in->samples;
      if(f->out.samples<f->out.size)f->fillstate=2;
      break;
    case 2: /* we've pushed out EOF already */
      f->out.samples=0;
    }
  }

  /* finish up the state feedabck */
  blocks/=input_ch;
  {
    int j;
    double scale=1./blocks;
    freq_feedback *ff=
      (freq_feedback *)feedback_new(&f->feedpool,new_freq_feedback);

    for(i=0;i<input_ch;i++)
      for(j=0;j<freqs;j++)
        feedback_rms[i][j]=sqrt(feedback_rms[i][j]*scale);

      
    for(i=0;i<input_ch;i++){
      memcpy(ff->peak[i],feedback_peak[i],freqs*sizeof(**feedback_peak));
      memcpy(ff->rms[i],feedback_rms[i],freqs*sizeof(**feedback_rms));
    } 
    feedback_push(&f->feedpool,(feedback_generic *)ff);
  }

 tidy_up:
  {
    int tozero=f->out.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);
  }

  return &f->out;
}

<p><p>1.1                  postfish/freq.h

Index: freq.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.
 *
 * 
 */

#include "postfish.h"
#include "smallft.h"

#define freqs 39

typedef struct {
  drft_lookup fft;
  time_linkage out;
  feedback_generic_pool feedpool;
  
  int blocksize;
  double **ho_window;
  double   ho_area[freqs];
  int      ho_bin_lo[freqs];
  int      ho_bin_hi[freqs];
  
  double *window;
  double **lap;
  double **cache;
  int cache_samples;
  int fillstate;     /* 0: uninitialized
                        1: normal
                        2: eof processed */
} freq_state;

extern int pull_freq_feedback(freq_state *ff,double **peak,double **rms);
extern int freq_load(freq_state *f,int blocksize);
extern int freq_reset(freq_state *f);
extern const char *freq_frequency_label(int n);
extern time_linkage *freq_read(time_linkage *in, freq_state *f,
                               void (*func)(double *data,freq_state *f,
                                            double *peak, double *rms));

<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