[xiph-cvs] cvs commit: postfish main.c Makefile fisharray.h mainpanel.c postfish.c

Monty xiphmont at xiph.org
Fri Oct 10 01:02:13 PDT 2003



xiphmont    03/10/10 04:02:13

  Modified:    .        Makefile fisharray.h mainpanel.c postfish.c
  Added:       .        main.c
  Log:
  avoid losing work; first playback

Revision  Changes    Path
1.3       +2 -2      postfish/Makefile

Index: Makefile
===================================================================
RCS file: /usr/local/cvsroot/postfish/Makefile,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Makefile	9 Oct 2003 00:33:36 -0000	1.2
+++ Makefile	10 Oct 2003 08:02:11 -0000	1.3
@@ -5,8 +5,8 @@
 CC=gcc
 LD=gcc
 
-SRC = mainpanel.c multibar.c readout.c
-OBJ = mainpanel.o multibar.o readout.o
+SRC = main.c mainpanel.c multibar.c readout.c
+OBJ = main.o mainpanel.o multibar.o readout.o
 GCF = `pkg-config --cflags gtk+-2.0`
 
 all:	

<p><p>1.3       +218 -3    postfish/fisharray.h

Index: fisharray.h
===================================================================
RCS file: /usr/local/cvsroot/postfish/fisharray.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- fisharray.h	10 Oct 2003 05:42:41 -0000	1.2
+++ fisharray.h	10 Oct 2003 08:02:12 -0000	1.3
@@ -1,4 +1,5 @@
-static char *ff_xpm[16][66] = {
+static char *ff_xpm[19][66] = {
+  /* 0 */
   {
     "40 40 23 1",
     " 	c None",
@@ -52,7 +53,7 @@
     "   $%%%$$~{{~,,~{{]]!------&*******=$   ",
     "    $$$$$$,~]]]]~,-$%=*$$$$$$=&&&&=$$   ",
     "       ++#$$----$$%&;**%$###$$$$$$$$    ",
-   "        +++#$$$$$$$%&&=$$#######        ",
+    "        +++#$$$$$$$%&&=$$#######        ",
     "         +++++++++#$$$$$#######         ",
     "          ++++++++++##########          ",
     "           +++++++++#########           ",
@@ -64,6 +65,7 @@
     "                 +++###                 ",
     "                  ++##                  ",
     "                   ++                   "},
+  /* 1 */
   {
     "40 40 22 1",
     " 	c None",
@@ -128,6 +130,7 @@
     "                 +++###                 ",
     "                  ++##                  ",
     "                   ++                   "},
+  /* 2 */
   {
     "40 40 22 1",
     " 	c None",
@@ -192,6 +195,7 @@
     "                 +++###                 ",
     "                  ++##                  ",
     "                   ++                   "},
+  /* 3 */
   {
     "40 40 20 1",
     " 	c None",
@@ -254,6 +258,7 @@
     "                 +++###                 ",
     "                  ++##                  ",
     "                   ++                   "},
+  /* 4 */
   {
     "40 40 25 1",
     " 	c None",
@@ -321,6 +326,7 @@
     "                 +++###                 ",
     "                  ++##                  ",
     "                   ++                   "},
+  /* 5 */
   {
     "40 40 24 1",
     " 	c None",
@@ -387,6 +393,7 @@
     "                 +++###                 ",
     "                  ++##                  ",
     "                   ++                   "},
+  /* 6 */
   {
     "40 40 23 1",
     " 	c None",
@@ -452,6 +459,7 @@
     "                 +++***                 ",
     "                  ++**                  ",
     "                   ++                   "},
+  /* 7 */
   {
     "40 40 22 1",
     " 	c None",
@@ -516,6 +524,7 @@
     "                 +++%%%                 ",
     "                  ++%%                  ",
     "                   ++                   "},
+  /* 8 */
   {
     "40 40 21 1",
     " 	c None",
@@ -579,6 +588,7 @@
     "                 +++&&&                 ",
     "                  ++&&                  ",
     "                   ++                   "},
+  /* 9 */
   {
     "40 40 20 1",
     " 	c None",
@@ -641,6 +651,7 @@
     "                 +++$$$                 ",
     "                  ++$$                  ",
     "                   ++                   "},
+  /* 10 */
   {
     "40 40 24 1",
     " 	c None",
@@ -707,6 +718,7 @@
     "                 +++###                 ",
     "                  ++##                  ",
     "                   ++                   "},
+  /* 11 */
   {
     "40 40 22 1",
     " 	c None",
@@ -771,6 +783,7 @@
     "                 +++###                 ",
     "                  ++##                  ",
     "                   ++                   "},
+  /* 12 */
   {"40 40 23 1",
    " 	c None",
    ".	c #7999B4",
@@ -835,6 +848,7 @@
    "                 +++###                 ",
    "                  ++##                  ",
    "                   ++                   "},
+  /* 13 */
   {"40 40 23 1",
    " 	c None",
    ".	c #7999B4",
@@ -899,6 +913,7 @@
    "                 +++###                 ",
    "                  ++##                  ",
    "                   ++                   "},
+  /* 14 */
   {"40 40 23 1",
    " 	c None",
    ".	c #7999B4",
@@ -963,6 +978,7 @@
    "                 +++###                 ",
    "                  ++##                  ",
    "                   ++                   "},
+  /* 15 */
   {"40 40 23 1",
    " 	c None",
    ".	c #7999B4",
@@ -1026,5 +1042,204 @@
    "                ++++####                ",
    "                 +++###                 ",
    "                  ++##                  ",
-   "                   ++                   "}
+   "                   ++                   "},
+  /* 16 */
+  {"40 40 23 1",
+   " 	c None",
+   ".	c #7999B4",
+   "+	c #4B6C99",
+   "@	c #8EB0C8",
+   "#	c #27536C",
+   "$	c #111E1E",
+   "%	c #04423C",
+   "&	c #059B9A",
+   "*	c #06E1E0",
+   "=	c #147A64",
+   "-	c #3C3E04",
+   ";	c #1CC2A4",
+   ">	c #2CFEFC",
+   ",	c #84824C",
+   "'	c #EDEEEC",
+   ")	c #CCCACC",
+   "!	c #5D602C",
+   "~	c #A1A20A",
+   "{	c #E7E809",
+   "]	c #BECD18",
+   "^	c #9CEE4C",
+   "/	c #46E09D",
+   "(	c #76D260",
+   "                   .+                   ",
+   "                  @.++                  ",
+   "                 @@.+++                 ",
+   "                @@@.++++                ",
+   "               @@@@.+++++               ",
+   "              @@@@@.++++++              ",
+   "             @@@@@@.+++++++             ",
+   "            @@@@@@@.####++++            ",
+   "           @@@@@@.#$$$$$$#+++           ",
+   "          @@@@@@.$%&****=$$#++          ",
+   "         @@.. at .-$%;*>>>**;=$$++         ",
+   "        @.#$$#$$&***>>>>***&%$++        ",
+   "       @+$,')!$$$$$&;*****;*;%$++       ",
+   "      @@$$''''$,~~-$%=******;;%%++      ",
+   "     @@+$'''''.!{{~{~$=;;;;;;&&$$##     ",
+   "    @@.$$$'''$,!{{~{{,$=;;&&==$$$$$$$   ",
+   "   @@.$,$!$$$!$],]~{!{~$%%%%$$=;***&$   ",
+   "  #$$$~{]-#).$,{{{~{]{],$$$%=;******$$  ",
+   " $%&&$-{{]!$-~{{{{{{,{,{~-$%***>>***$#+ ",
+   "#$***&$-{{{{{{{{{{{{]{]]!]~-*******&$#++",
+   "#$$;;*&$-{{{{{!!!!!{,{,{]~!]*****&%$$##+",
+   " +$$$=;&$]{{{^===$-]~]~]!]~]****&%$$### ",
+   "  ##$$=;%~{{{/>*&-]],],]]],(******;#$#  ",
+   "   #%$$;&{{^/**&-]{{{{{]!{]/*******=$   ",
+   "   $$*;=${{]$$$$~{{{]]]]~]];*******=$   ",
+   "   $%%%$$~{{~,,~{{]]!------&*******=$   ",
+   "    $$$$$$,~]]]]~,-$%=*$$$$$$=&&&&=$$   ",
+   "       ++#$$----$$%&;**%$###$$$$$$$$    ",
+   "        +++#$$$$$$$%&&=$$#######        ",
+   "         +++++++++#$$$$$#######         ",
+   "          ++++++++++##########          ",
+   "           +++++++++#########           ",
+   "            ++++++++########            ",
+   "             +++++++#######             ",
+   "              ++++++######              ",
+   "               +++++#####               ",
+   "                ++++####                ",
+   "                 +++###                 ",
+   "                  ++##                  ",
+   "                   ++                   "},
+  /* 17 */
+  {"40 40 23 1",
+   " 	c None",
+   ".	c #7999B4",
+   "+	c #4B6C99",
+   "@	c #8EB0C8",
+   "#	c #27536C",
+   "$	c #111E1E",
+   "%	c #04423C",
+   "&	c #059B9A",
+   "*	c #06E1E0",
+   "=	c #147A64",
+   "-	c #3C3E04",
+   ";	c #1CC2A4",
+   ">	c #2CFEFC",
+   ",	c #84824C",
+   "'	c #EDEEEC",
+   ")	c #CCCACC",
+   "!	c #5D602C",
+   "~	c #A1A20A",
+   "{	c #E7E809",
+   "]	c #BECD18",
+   "^	c #9CEE4C",
+   "/	c #46E09D",
+   "(	c #76D260",
+   "                   .+                   ",
+   "                  @.++                  ",
+   "                 @@.+++                 ",
+   "                @@@.++++                ",
+   "               @@@@.+++++               ",
+   "              @@@@@.++++++              ",
+   "             @@@@@@.+++++++             ",
+   "            @@@@@@@.####++++            ",
+   "           @@@@@@.#$$$$$$#+++           ",
+   "          @@@@@@.$%&****=$$#++          ",
+   "         @@.. at .-$%;*>>>**;=$$++         ",
+   "        @.#$$#$$&***>>>>***&%$++        ",
+   "       @+$,')!$$$$$&;*****;*;%$++       ",
+   "      @@$$!'!$$,~~-$%=******;;%%++      ",
+   "     @@+$!$$$!.!{{~{~$=;;;;;;&&$$##     ",
+   "    @@.$$''!!',!{{~{{,$=;;&&==$$$$$$$   ",
+   "   @@.$,$,''''$],]~{!{~$%%%%$$=;***&$   ",
+   "  #$$$~{]-#).$,{{{~{]{],$$$%=;******$$  ",
+   " $%&&$-{{]!$-~{{{{{{,{,{~-$%***>>***$#+ ",
+   "#$***&$-{{{{{{{{{{{{]{]]!]~-*******&$#++",
+   "#$$;;*&$-{{{{{!!!!!{,{,{]~!]*****&%$$##+",
+   " +$$$=;&$]{{{^===$-]~]~]!]~]****&%$$### ",
+   "  ##$$=;%~{{{/>*&-]],],]]],(******;#$#  ",
+   "   #%$$;&{{^/**&-]{{{{{]!{]/*******=$   ",
+   "   $$*;=${{]$$$$~{{{]]]]~]];*******=$   ",
+   "   $%%%$$~{{~,,~{{]]!------&*******=$   ",
+   "    $$$$$$,~]]]]~,-$%=*$$$$$$=&&&&=$$   ",
+   "       ++#$$----$$%&;**%$###$$$$$$$$    ",
+   "        +++#$$$$$$$%&&=$$#######        ",
+   "         +++++++++#$$$$$#######         ",
+   "          ++++++++++##########          ",
+   "           +++++++++#########           ",
+   "            ++++++++########            ",
+   "             +++++++#######             ",
+   "              ++++++######              ",
+   "               +++++#####               ",
+   "                ++++####                ",
+   "                 +++###                 ",
+   "                  ++##                  ",
+   "                   ++                   "},
+  /* 18 */
+  {"40 40 23 1",
+   " 	c None",
+   ".	c #7999B4",
+   "+	c #4B6C99",
+   "@	c #8EB0C8",
+   "#	c #27536C",
+   "$	c #111E1E",
+   "%	c #04423C",
+   "&	c #059B9A",
+   "*	c #06E1E0",
+   "=	c #147A64",
+   "-	c #3C3E04",
+   ";	c #1CC2A4",
+   ">	c #2CFEFC",
+   ",	c #84824C",
+   "'	c #EDEEEC",
+   ")	c #CCCACC",
+   "!	c #5D602C",
+   "~	c #A1A20A",
+   "{	c #E7E809",
+   "]	c #BECD18",
+   "^	c #9CEE4C",
+   "/	c #46E09D",
+   "(	c #76D260",
+   "                   .+                   ",
+   "                  @.++                  ",
+   "                 @@.+++                 ",
+   "                @@@.++++                ",
+   "               @@@@.+++++               ",
+   "              @@@@@.++++++              ",
+   "             @@@@@@.+++++++             ",
+   "            @@@@@@@.####++++            ",
+   "           @@@@@@.#$$$$$$#+++           ",
+   "          @@@@@@.$%&****=$$#++          ",
+   "         @@.. at .-$%;*>>>**;=$$++         ",
+   "        @.#$$#$$&***>>>>***&%$++        ",
+   "       @+$,')!$$$$$&;*****;*;%$++       ",
+   "      @@$,$$$!$,~~-$%=******;;%%++      ",
+   "     @@+$''-!'.!{{~{~$=;;;;;;&&$$##     ",
+   "    @@.$$''!!',!{{~{{,$=;;&&==$$$$$$$   ",
+   "   @@.$,$,''''$],]~{!{~$%%%%$$=;***&$   ",
+   "  #$$$~{]-#).$,{{{~{]{],$$$%=;******$$  ",
+   " $%&&$-{{]!$-~{{{{{{,{,{~-$%***>>***$#+ ",
+   "#$***&$-{{{{{{{{{{{{]{]]!]~-*******&$#++",
+   "#$$;;*&$-{{{{{!!!!!{,{,{]~!]*****&%$$##+",
+   " +$$$=;&$]{{{^===$-]~]~]!]~]****&%$$### ",
+   "  ##$$=;%~{{{/>*&-]],],]]],(******;#$#  ",
+   "   #%$$;&{{^/**&-]{{{{{]!{]/*******=$   ",
+   "   $$*;=${{]$$$$~{{{]]]]~]];*******=$   ",
+   "   $%%%$$~{{~,,~{{]]!------&*******=$   ",
+   "    $$$$$$,~]]]]~,-$%=*$$$$$$=&&&&=$$   ",
+   "       ++#$$----$$%&;**%$###$$$$$$$$    ",
+   "        +++#$$$$$$$%&&=$$#######        ",
+   "         +++++++++#$$$$$#######         ",
+   "          ++++++++++##########          ",
+   "           +++++++++#########           ",
+   "            ++++++++########            ",
+   "             +++++++#######             ",
+   "              ++++++######              ",
+   "               +++++#####               ",
+   "                ++++####                ",
+   "                 +++###                 ",
+   "                  ++##                  ",
+   "                   ++                   "},
+
+
 };
+
+

<p><p>1.5       +161 -63   postfish/mainpanel.c

Index: mainpanel.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/mainpanel.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- mainpanel.c	10 Oct 2003 05:42:41 -0000	1.4
+++ mainpanel.c	10 Oct 2003 08:02:12 -0000	1.5
@@ -3,14 +3,14 @@
 #include <gdk/gdkkeysyms.h>
 #include <signal.h>
 #include <stdio.h>
+#include <pthread.h>
 #include "fisharray.h"
 #include "buttonicons.h"
 #include "multibar.h"
 #include "readout.h"
-#define VERSION "$Id: mainpanel.c,v 1.4 2003/10/10 05:42:41 xiphmont Exp $ "
+#define VERSION "$Id: mainpanel.c,v 1.5 2003/10/10 08:02:12 xiphmont Exp $ "
 
 typedef struct {
-  GtkWidget *toplevel;
   GtkWidget *topframe;
   GtkWidget *toplabel;
 
@@ -22,29 +22,113 @@
 
   GtkWidget *wintable;
   GtkWidget *twirlimage;
-  GdkPixmap *ff[16];
-  GdkBitmap *fb[16];
+  GdkPixmap *ff[19];
+  GdkBitmap *fb[19];
 
   GtkWidget *buttonpanel[7];
-  GtkWidget *buttonactive[7];
-
-
   GtkWidget *quitbutton;
   
   /* we need these widgets */
+  GtkWidget *toplevel;
+
   GtkWidget *masterdB_r;
   GtkWidget *masterdB_s;
   GtkWidget *masterdB_a;
-  
+
+  GtkWidget *buttonactive[7];
+  GtkWidget *cue_set[2];
+  GtkWidget *cue_reset[2];
+
+  GtkWidget *deckactive[7];
+
+  /* ui state */
+  int fishframe;
+  int fishframe_init;
+  guint fishframe_timer;
+ 
 } postfish_mainpanel;
 
+extern sig_atomic_t playback_active;
+extern sig_atomic_t playback_exit;
+extern void *playback_thread(void *dummy);
+
+static void action_play(GtkWidget *dummy,postfish_mainpanel *p){
+  if(!playback_active){
+    pthread_t playback_thread_id;
+    playback_active=1;
+    animate_fish(p);
+    pthread_create(&playback_thread_id,NULL,&playback_thread,NULL);
+  }else{
+    playback_exit=1;
+    sched_yield();
+    while(1){
+      if(playback_active){
+	sched_yield();
+      }else
+	break;
+    }
+  }
+}
+
+/* gotta have the Fucking Fish */
+int reanimate_fish(postfish_mainpanel *p){
+  if(playback_active || (p->fishframe>0 && p->fishframe<12)){
+    /* continue spinning */
+    p->fishframe++;
+    if(p->fishframe==12)p->fishframe=0;
+
+    gtk_image_set_from_pixmap(GTK_IMAGE(p->twirlimage),
+			      p->ff[p->fishframe],
+			      p->fb[p->fishframe]);
+
+    if(p->fishframe==0 && !playback_active){
+      /* reschedule to blink */
+      p->fishframe_timer=
+	gtk_timeout_add(rand()%1000*30,(GtkFunction)reanimate_fish,p);
+      return FALSE;
+    }
+  }else{
+    p->fishframe++;
+    if(p->fishframe==1)p->fishframe=12;
+    if(p->fishframe==19)p->fishframe=0;
+
+    gtk_image_set_from_pixmap(GTK_IMAGE(p->twirlimage),
+			      p->ff[p->fishframe],
+			      p->fb[p->fishframe]);
 
 
+    if(p->fishframe==12){
+      /* reschedule to animate */
+      p->fishframe_timer=
+	gtk_timeout_add(10,(GtkFunction)reanimate_fish,p);
+      return FALSE;
+    }
+    if(p->fishframe==0){
+      /* reschedule to blink */
+      p->fishframe_timer=
+	gtk_timeout_add(rand()%1000*30,(GtkFunction)reanimate_fish,p);
+      return FALSE;
+    }
+    return TRUE;
+  }
+}
+
+int animate_fish(postfish_mainpanel *p){
+  if(p->fishframe_init){
+    gtk_timeout_remove(p->fishframe_timer);
+    p->fishframe_timer=
+      gtk_timeout_add(80,(GtkFunction)reanimate_fish,p);
+  }else{
+    p->fishframe_init=1;
+    p->fishframe_timer=
+      gtk_timeout_add(rand()%1000*30,(GtkFunction)reanimate_fish,p);
+  }
+}
+
 static void shutdown(void){
   gtk_main_quit ();
 }
 
-
 sig_atomic_t master_att;
 static void masterdB_change(GtkRange *r, gpointer in){
   postfish_mainpanel *p=in;
@@ -155,85 +239,95 @@
 static gboolean keybinding(GtkWidget *widget,
                            GdkEventKey *event,
                            gpointer in){
+  postfish_mainpanel *p=in;
+
+#if 0
   fprintf(stderr,"keypress: M%d C%d S%d L%d '%x'\n",
           event->state&GDK_MOD1_MASK,
           event->state&GDK_CONTROL_MASK,
           event->state&GDK_SHIFT_MASK,
           event->state&GDK_LOCK_MASK,
           event->keyval);
+#endif
 
   /* do not capture Alt accellerators */
   if(event->state&GDK_MOD1_MASK) return FALSE;
+  if(event->state&GDK_CONTROL_MASK) return FALSE;
 
   switch(event->keyval){
   case GDK_m:
     /* trigger master dB */
+    gtk_widget_activate(p->masterdB_a);
     break;
   case GDK_minus:
-
+    gtk_range_set_value(GTK_RANGE(p->masterdB_s),
+			gtk_range_get_value(GTK_RANGE(p->masterdB_s))-.1);
     break;
   case GDK_underscore:
-
+    gtk_range_set_value(GTK_RANGE(p->masterdB_s),
+			gtk_range_get_value(GTK_RANGE(p->masterdB_s))-1.);
     break;
   case GDK_equal:
-
+    gtk_range_set_value(GTK_RANGE(p->masterdB_s),
+			gtk_range_get_value(GTK_RANGE(p->masterdB_s))+.1);
     break;
   case GDK_plus:
-
+    gtk_range_set_value(GTK_RANGE(p->masterdB_s),
+			gtk_range_get_value(GTK_RANGE(p->masterdB_s))+1.);
     break;
   case GDK_d:
-
+    gtk_widget_activate(p->buttonactive[0]);
     break;
   case GDK_t:
-
+    gtk_widget_activate(p->buttonactive[1]);
     break;
   case GDK_n:
-
+    gtk_widget_activate(p->buttonactive[2]);
     break;
   case GDK_e:
-
+    gtk_widget_activate(p->buttonactive[3]);
     break;
   case GDK_c:
-
+    gtk_widget_activate(p->buttonactive[4]);
     break;
   case GDK_l:
-
+    gtk_widget_activate(p->buttonactive[5]);
     break;
   case GDK_o:
-
+    gtk_widget_activate(p->buttonactive[6]);
     break;
   case GDK_a:
-
+    gtk_widget_activate(p->cue_set[0]);
     break;
   case GDK_A:
-
+    gtk_widget_activate(p->cue_reset[0]);
     break;
   case GDK_b:
-
+    gtk_widget_activate(p->cue_set[1]);
     break;
   case GDK_B:
-
+    gtk_widget_activate(p->cue_reset[1]);
     break;
-    //  case GDK_BackSpace:
-
+  case GDK_BackSpace:
+    gtk_widget_activate(p->deckactive[0]);
     break;
   case GDK_less:
-
+    gtk_widget_activate(p->deckactive[1]);
     break;
   case GDK_comma:
-
+    gtk_widget_activate(p->deckactive[2]);
     break;
   case GDK_space:
-
+    gtk_widget_activate(p->deckactive[3]);
     break;
   case GDK_period:
-
+    gtk_widget_activate(p->deckactive[4]);
     break;
   case GDK_greater:
-
+    gtk_widget_activate(p->deckactive[5]);
     break;
   case GDK_End:
-
+    gtk_widget_activate(p->deckactive[6]);
     break;
   default:
     return FALSE;
@@ -293,7 +387,7 @@
                     G_CALLBACK (keybinding), panel);
   
 
-  for(i=0;i<16;i++)
+  for(i=0;i<19;i++)
     panel->ff[i]=gdk_pixmap_create_from_xpm_d(root,
                                               panel->fb+i,NULL,ff_xpm[i]);
   xpm_bar[0]=gdk_pixmap_create_from_xpm_d(root,
@@ -457,29 +551,28 @@
     /* master action bar */
     {
       GtkWidget *bar_table=gtk_table_new(1,8,1);
-      GtkWidget *buttons[7];
       char buffer[20];
       for(i=0;i<7;i++){
         GtkWidget *box=gtk_vbox_new(0,3);
         GtkWidget *label=gtk_label_new(text_bar[i]);
 
         if(i==3)
-	  buttons[i]=gtk_toggle_button_new();
+	  panel->deckactive[i]=gtk_toggle_button_new();
         else
-	  buttons[i]=gtk_button_new();
+	  panel->deckactive[i]=gtk_button_new();
 
         gtk_box_pack_start(GTK_BOX(box),gim_bar[i],0,0,0);
         gtk_box_pack_start(GTK_BOX(box),label,0,0,0);
-	gtk_container_add (GTK_CONTAINER(buttons[i]), box);
+	gtk_container_add (GTK_CONTAINER(panel->deckactive[i]), box);
       }
 
-      gtk_table_attach_defaults(GTK_TABLE(bar_table),buttons[0],0,1,0,1);
-      gtk_table_attach_defaults(GTK_TABLE(bar_table),buttons[1],1,2,0,1);
-      gtk_table_attach_defaults(GTK_TABLE(bar_table),buttons[2],2,3,0,1);
-      gtk_table_attach_defaults(GTK_TABLE(bar_table),buttons[3],3,5,0,1);
-      gtk_table_attach_defaults(GTK_TABLE(bar_table),buttons[4],5,6,0,1);
-      gtk_table_attach_defaults(GTK_TABLE(bar_table),buttons[5],6,7,0,1);
-      gtk_table_attach_defaults(GTK_TABLE(bar_table),buttons[6],7,8,0,1);
+      gtk_table_attach_defaults(GTK_TABLE(bar_table),panel->deckactive[0],0,1,0,1);
+      gtk_table_attach_defaults(GTK_TABLE(bar_table),panel->deckactive[1],1,2,0,1);
+      gtk_table_attach_defaults(GTK_TABLE(bar_table),panel->deckactive[2],2,3,0,1);
+      gtk_table_attach_defaults(GTK_TABLE(bar_table),panel->deckactive[3],3,5,0,1);
+      gtk_table_attach_defaults(GTK_TABLE(bar_table),panel->deckactive[4],5,6,0,1);
+      gtk_table_attach_defaults(GTK_TABLE(bar_table),panel->deckactive[5],6,7,0,1);
+      gtk_table_attach_defaults(GTK_TABLE(bar_table),panel->deckactive[6],7,8,0,1);
 
       gtk_table_attach(GTK_TABLE(ttable),bar_table,1,3,4,5,
                        GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,
@@ -489,6 +582,11 @@
                              0,0,
                        0,0);
 
+
+      g_signal_connect (G_OBJECT (panel->deckactive[3]), "clicked",
+			G_CALLBACK (action_play), panel);
+
+
     }
 
     /* cue bar */
@@ -502,13 +600,14 @@
       GtkWidget *framea=gtk_vseparator_new();
       GtkWidget *frameb=gtk_vseparator_new();
 
-      GtkWidget *set_a=gtk_button_new_with_label("[a]");
-      GtkWidget *set_b=gtk_button_new_with_label("[b]");
-      GtkWidget *reset_a=gtk_button_new_with_label("[A]");
-      GtkWidget *reset_b=gtk_button_new_with_label("[B]");
-
       GtkWidget *panelb=gtk_check_button_new_with_mnemonic("c_ue list");
 
+      panel->cue_set[0]=gtk_button_new_with_label("[a]");
+      panel->cue_set[1]=gtk_button_new_with_label("[b]");
+      panel->cue_reset[0]=gtk_button_new_with_label("[A]");
+      panel->cue_reset[1]=gtk_button_new_with_label("[B]");
+
+
       gtk_entry_set_width_chars(GTK_ENTRY(entry_a),13);
       gtk_entry_set_width_chars(GTK_ENTRY(entry_b),13);
       gtk_entry_set_text(GTK_ENTRY(entry_a),"    :  :00.00");
@@ -525,12 +624,11 @@
                         G_CALLBACK (timeevent_unselect), NULL);
 
 
-      gtk_widget_set_name(reset_a,"reseta");
-      gtk_widget_set_name(reset_b,"resetb");
+      gtk_widget_set_name(panel->cue_reset[0],"reseta");
+      gtk_widget_set_name(panel->cue_reset[1],"resetb");
 
       gtk_misc_set_alignment(GTK_MISC(cuelabel),1,.5);
 
-
       gtk_table_attach_defaults(GTK_TABLE(ttable),cuelabel,0,1,5,6);
       gtk_table_attach_defaults(GTK_TABLE(ttable),cuebox,1,2,5,6);
       gtk_table_attach_defaults(GTK_TABLE(ttable),panelb,2,3,5,6);
@@ -539,15 +637,15 @@
 
       gtk_box_pack_start(GTK_BOX(cuebox),framea,1,1,3);
 
-      gtk_box_pack_start(GTK_BOX(cuebox),set_a,0,0,0);
+      gtk_box_pack_start(GTK_BOX(cuebox),panel->cue_set[0],0,0,0);
       gtk_box_pack_start(GTK_BOX(cuebox),entry_a,0,0,0);
-      gtk_box_pack_start(GTK_BOX(cuebox),reset_a,0,0,0);
+      gtk_box_pack_start(GTK_BOX(cuebox),panel->cue_reset[0],0,0,0);
 
       gtk_box_pack_start(GTK_BOX(cuebox),frameb,1,1,3);
 
-      gtk_box_pack_start(GTK_BOX(cuebox),set_b,0,0,0);
+      gtk_box_pack_start(GTK_BOX(cuebox),panel->cue_set[1],0,0,0);
       gtk_box_pack_start(GTK_BOX(cuebox),entry_b,0,0,0);
-      gtk_box_pack_start(GTK_BOX(cuebox),reset_b,0,0,0);
+      gtk_box_pack_start(GTK_BOX(cuebox),panel->cue_reset[1],0,0,0);
 
     }
 
@@ -578,11 +676,10 @@
 }
 
 #include <stdlib.h>
-int main(int argc, char *argv[]){
-  postfish_mainpanel mainpanel;
-
+void mainpanel_go(int argc,char *argv[]){
+  postfish_mainpanel p;
   char *homedir=getenv("HOME");
-
+  memset(&p,0,sizeof(p));
   gtk_rc_add_default_file("/etc/postfish/postfishrc");
   if(homedir){
     char *rcfile="/.postfishrc";
@@ -592,12 +689,13 @@
     gtk_rc_add_default_file(homerc);
   }
   gtk_init (&argc, &argv);
-
+  
   {
     char *labels[]={"_0 left","_1 right","_2 mid","_3 side",0};
-    mainpanel_create(&mainpanel,labels);
+    mainpanel_create(&p,labels);
   }
-
+  
+  animate_fish(&p);
   gtk_main ();
-}
 
+}

<p><p>1.7       +2 -2      postfish/postfish.c

Index: postfish.c
===================================================================
RCS file: /usr/local/cvsroot/postfish/postfish.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- postfish.c	16 Sep 2003 08:55:12 -0000	1.6
+++ postfish.c	10 Oct 2003 08:02:12 -0000	1.7
@@ -2,7 +2,7 @@
  *
  *  postfish.c
  *    
- *      Copyright (C) 2002 Monty
+ *      Copyright (C) 2002-2003 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
@@ -2004,7 +2004,7 @@
     form_init(&editf,120,1);
     form_init(&noneditf,50,0);
     box(stdscr,0,0);
-    mvaddstr(0, 2, " Postfish Filter $Id: postfish.c,v 1.6 2003/09/16 08:55:12 xiphmont Exp $ ");
+    mvaddstr(0, 2, " Postfish Filter $Id: postfish.c,v 1.7 2003/10/10 08:02:12 xiphmont Exp $ ");
     mvaddstr(LINES-1, 2, 
              "  [<]<<   [,]<   [Spc] Play/Pause   [Bksp] Stop/Cue   [.]>   [>]>>  ");
 

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

Index: main.c
===================================================================
/*
 *
 *  postfish
 *    
 *      Copyright (C) 2002-2003 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.
 *
 * 
 */

/* This project is a small, tightly tailored application.  it is not
   designed to be nigh-infinitely extensible, nor is it designed to be
   reusable code.  It's monolithic, inflexible, and designed that way
   on purpose. */

/* sound playback code is OSS-specific for now */

#define _GNU_SOURCE
#define _LARGEFILE_SOURCE 
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#define _REENTRANT 1
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#define __USE_GNU 1
#include <pthread.h>
#include <string.h>
#include <math.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>

#include "mainpanel.h"

#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)

tatic int outfileno=-1;
static int loop_flag=1;
static int inbytes=0;
static int outbytes=2;
static int rate=0;
static int ch=0;
static int signp=0;

/* working space */

tatic long block=8192;

tatic off_t Acursor=0;
static off_t Bcursor=-1;
static long  T=-1;
static off_t cursor=0;

<p>pthread_mutex_t master_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;

ig_atomic_t primed=0;
sig_atomic_t playback_active=0;
sig_atomic_t playback_exit=0;

int eventpipe[2];

typedef struct {
  FILE *f;
  
  off_t begin;
  off_t end;
  off_t data;

} file_entry;

file_entry *file_list=NULL;
int file_entries=0;
int current_file_entry_number=-1;
file_entry *current_file_entry=NULL;
int seekable=0;

int aseek(off_t pos){
  int i;

  if(pos<0)pos=0;
  if(!seekable){
    current_file_entry=file_list;
    current_file_entry_number=0;
    return -1;
  }

  pthread_mutex_lock(&master_mutex);
  for(i=0;i<file_entries;i++){
    current_file_entry=file_list+i;
    current_file_entry_number=i;
    if(current_file_entry->begin<=pos && current_file_entry->end>pos){
      fseeko(current_file_entry->f,
             pos-current_file_entry->begin+current_file_entry->data,
             SEEK_SET);
      cursor=pos;
      pthread_mutex_unlock(&master_mutex);
      return 0;
    }
  }
  i--;

  pos=current_file_entry->end;
  fseeko(current_file_entry->f,
         pos-current_file_entry->begin+current_file_entry->data,
         SEEK_SET);
  cursor=pos;
  pthread_mutex_unlock(&master_mutex);
  return(0);
}

int aread(double **buf){
  int read_b=0,i,j,k;
  int toread_b=block*ch*inbytes;
  unsigned char *readbuf;
  double M,S;
  
  pthread_mutex_lock(&master_mutex);

  /* the non-streaming case */
  if(Bcursor<0 && 
     cursor>=current_file_entry->end &&
     current_file_entry->end!=-1){
    pthread_mutex_unlock(&master_mutex);
    return -1; /* EOF */
  }

  /* the streaming case */
  if(feof(current_file_entry->f) && 
     current_file_entry_number+1>=file_entries){
    pthread_mutex_unlock(&master_mutex);
    return -1;
  }

  if(primed){
    for(j=0;j<ch;j++)
      memmove(buf[j],buf[j]+block/2,sizeof(**buf)*block/2);
    toread_b/=2;
  }

  readbuf=alloca(toread_b);

  while(toread_b){
    off_t ret;
    off_t read_this_loop=current_file_entry->end-cursor;
    if(read_this_loop>toread_b)read_this_loop=toread_b;

    ret=fread(readbuf+read_b,1,read_this_loop,current_file_entry->f);

    if(ret>0){
      read_b+=ret;
      toread_b-=ret;
      cursor+=ret;
    }else{
      if(current_file_entry_number+1>=file_entries){
        memset(readbuf+read_b,0,toread_b);
        read_b+=toread_b;
        toread_b=0;
      }
    }

    if(Bcursor!=-1 && cursor>=Bcursor){
      if(loop_flag)
        aseek(Acursor);
      else{
        pthread_mutex_unlock(&master_mutex);
        return(-1);
      }
    }else if(cursor>=current_file_entry->end){
      if(current_file_entry_number+1<file_entries){
        current_file_entry_number++;
        current_file_entry++;
        fseeko(current_file_entry->f,current_file_entry->data,SEEK_SET);
      }
    }
  }
  
  k=0;
  for(i=(primed?block/2:0);i<block;i++){
    for(j=0;j<ch;j++){
      int val=0;
      switch(inbytes){
      case 1:
        val=(readbuf[k]<<24);
        break;
      case 2:
        val=(readbuf[k]<<16)|(readbuf[k+1]<<24);
        break;
      case 3:
        val=(readbuf[k]<<8)|(readbuf[k+1]<<16)|(readbuf[k+2]<<24);
        break;
      case 4:
        val=(readbuf[k])|(readbuf[k+1]<<8)|(readbuf[k+2]<<16)|(readbuf[k+3]<<24);
        break;
      }
      if(signp)
        buf[j][i]=val*4.6566128730e-10;
      else
        buf[j][i]=(val^0x80000000UL)*4.6566128730e-10;

      k+=inbytes;
    }
    if(ch==2){
      M=(buf[0][i]+buf[1][i])*.5;
      S=(buf[0][i]-buf[1][i])*.5;
      buf[0][i]=M;
      buf[1][i]=S;
    }
  }    
  primed=1;
  pthread_mutex_unlock(&master_mutex);
  return 0;
}

void PutNumLE(long num,FILE *f,int bytes){
  int i=0;
  while(bytes--){
    fputc((num>>(i<<3))&0xff,f);
    i++;
  }
}

void WriteWav(FILE *f,long channels,long rate,long bits,long duration){
  if(ftell(f)>0)
    if(fseek(f,0,SEEK_SET))
      return;
  fprintf(f,"RIFF");
  PutNumLE(duration+44-8,f,4);
  fprintf(f,"WAVEfmt ");
  PutNumLE(16,f,4);
  PutNumLE(1,f,2);
  PutNumLE(channels,f,2);
  PutNumLE(rate,f,4);
  PutNumLE(rate*channels*((bits-1)/8+1),f,4);
  PutNumLE(((bits-1)/8+1)*channels,f,2);
  PutNumLE(bits,f,2);
  fprintf(f,"data");
  PutNumLE(duration,f,4);
}

int isachr(FILE *f){
  struct stat s;

  if(!fstat(fileno(f),&s))
    if(S_ISCHR(s.st_mode)) return 1;
  return 0;
}

/* playback must be halted to change blocksize. */
void *playback_thread(void *dummy){
  FILE *playback_fd=NULL;
  int i,j,k;
  int format=AFMT_S16_NE;
  int channels=ch;
  int irate=rate;
  unsigned char *audiobuf;
  int audiobufsize;
  int ret,fd;
  double **buf;
  double **work;
  double **save;
  int bigendianp=0;
  double scale;
  int last=0;
  off_t count=0;

  pthread_mutex_lock(&master_mutex);
  //block=wc.block_a;
  //scale=2./block;
  pthread_mutex_unlock(&master_mutex);

  if(outfileno==-1){
    playback_fd=fopen("/dev/dsp","wb");
  }else{
    playback_fd=fdopen(dup(outfileno),"wb");
  }
  if(!playback_fd){
    playback_active=0;
    playback_exit=0;
    return NULL;
  }

  /* is this file a block device? */
  if(isachr(playback_fd)){
    int fragment=0x7fff000d;

    fd=fileno(playback_fd);

    /* try to lower the DSP delay; this ioctl may fail gracefully */
    ret=ioctl(fd,SNDCTL_DSP_SETFRAGMENT,&fragment);
    if(ret){
      fprintf(stderr,"Could not set DSP fragment size; continuing.\n");
    }

    ret=ioctl(fd,SNDCTL_DSP_SETFMT,&format);
    if(ret || format!=AFMT_S16_NE){
      fprintf(stderr,"Could not set AFMT_S16_NE playback\n");
      exit(1);
    }
    ret=ioctl(fd,SNDCTL_DSP_CHANNELS,&channels);
    if(ret || channels!=ch){
      fprintf(stderr,"Could not set %d channel playback\n",ch);
      exit(1);
    }
    ret=ioctl(fd,SNDCTL_DSP_SPEED,&irate);
    if(ret || irate!=rate){
      fprintf(stderr,"Could not set %dHz playback\n",44100);
      exit(1);
    }

    if(AFMT_S16_NE==AFMT_S16_BE)bigendianp=1;

  }else{
    WriteWav(playback_fd,ch,rate,outbytes*8,-1);
  }

  buf=alloca(sizeof(*buf)*ch);
  work=alloca(sizeof(*work)*ch);
  save=alloca(sizeof(*save)*ch);
  for(i=0;i<ch;i++){
    buf[i]=alloca(sizeof(**buf)*block);
    work[i]=alloca(sizeof(**work)*block);
    save[i]=alloca(sizeof(**save)*block/2);
    memset(save[i],0,sizeof(**save)*block/2);
  }
  audiobufsize=block/2*ch*outbytes;
  audiobuf=alloca(audiobufsize);
  aseek(cursor);
  primed=0;

  while(1){
    if(playback_exit)break;

    /* get data */
    if(aread(buf))break;

<p>    /* processing goes here */

<p>    /* Back to L/R if stereo */
    
    if(ch==2){
      for(i=0;i<block;i++){
        double L=(buf[0][i]+buf[1][i])*.5;
        double R=(buf[0][i]-buf[1][i])*.5;
        buf[0][i]=L;
        buf[1][i]=R;
      }
    }

    /* final limiting */

    for(k=0,i=0;i<block/2;i++){
      for(j=0;j<ch;j++){
        int val=rint(buf[j][i]*32767.);
        if(val>32767)val=32767;
        if(val<-32768)val=-32768;
        if(bigendianp){
          audiobuf[k++]=val>>8;
          audiobuf[k++]=val;
        }else{
          audiobuf[k++]=val;
          audiobuf[k++]=val>>8;
        }
      }
    }
    {
      struct timeval tv;
      long foo;
      gettimeofday(&tv,NULL);
      foo=tv.tv_sec*10+tv.tv_usec/100000;
      if(last!=foo)
        write(eventpipe[1],"",1);
      last=foo;
    }

    count+=fwrite(audiobuf,1,audiobufsize,playback_fd);

  }

  if(!isachr(playback_fd))WriteWav(playback_fd,ch,rate,outbytes*8,count);

  fclose(playback_fd);
  playback_active=0;
  playback_exit=0;
  write(eventpipe[1],"",1);
  return(NULL);
}

int main(int argc, char **argv){
  off_t total=0;
  int i,j;
  int configfd;
  int stdinp=0;
  char *fname="stdin";

  /* parse command line and open all the input files */
  if(argc==1){
    /* look at stdin... is it a file, pipe, tty...? */
    if(isatty(STDIN_FILENO)){
      fprintf(stderr,
              "Postfish requires input either as a list of contiguous WAV\n"
              "files on the command line, or WAV data piped|redirected to\n"
              "stdin.\n");
      exit(1);
    }
    stdinp=1;    /* file coming in via stdin */
    file_entries=1;
  }else
    file_entries=argc-1;

  file_list=calloc(file_entries,sizeof(file_entry));
  for(i=1;i<=file_entries;i++){
    FILE *f;
    
    if(stdinp){
      int newfd=dup(STDIN_FILENO);
      f=fdopen(newfd,"rb");
    }else{
      f=fopen(argv[i],"rb");
      fname=argv[i];
    }

    if(f){
      unsigned char buffer[81];
      off_t filelength;
      int datap=0;
      int fmtp=0;
      file_list[i-1].f=f;
      
      /* parse header (well, sort of) and get file size */
      seekable=(fseek(f,0,SEEK_CUR)?0:1);
      if(!seekable){
        filelength=-1;
      }else{
        fseek(f,0,SEEK_END);
        filelength=ftello(f);
        fseek(f,0,SEEK_SET);
      }

      fread(buffer,1,12,f);
      if(strncmp(buffer,"RIFF",4) || strncmp(buffer+8,"WAVE",4)){
        fprintf(stderr,"%s: Not a WAVE file.\n",fname);
        exit(1);
      }

      while(fread(buffer,1,8,f)==8){
        unsigned long chunklen=
          buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);

        if(!strncmp(buffer,"fmt ",4)){
          int ltype;
          int lch;
          int lrate;
          int lbits;

          if(chunklen>80){
            fprintf(stderr,"%s: WAVE file fmt chunk too large to parse.\n",fname);
            exit(1);
          }
          fread(buffer,1,chunklen,f);
          
          ltype=buffer[0] |(buffer[1]<<8);
          lch=  buffer[2] |(buffer[3]<<8);
          lrate=buffer[4] |(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
          lbits=buffer[14]|(buffer[15]<<8);

          if(ltype!=1){
            fprintf(stderr,"%s: WAVE file not PCM.\n",fname);
            exit(1);
          }

          if(i==1){
            ch=lch;
            rate=lrate;
            inbytes=lbits/8;
            if(inbytes>1)signp=1;
          }else{
            if(ch!=lch){
              fprintf(stderr,"%s: WAVE files must all have same number of channels.\n",fname);
              exit(1);
            }
            if(rate!=lrate){
              fprintf(stderr,"%s: WAVE files must all be same sampling rate.\n",fname);
              exit(1);
            }
            if(inbytes!=lbits/8){
              fprintf(stderr,"%s: WAVE files must all be same sample width.\n",fname);
              exit(1);
            }
          }
          fmtp=1;
        } else if(!strncmp(buffer,"data",4)){
          off_t pos=ftello(f);
          if(!fmtp){
            fprintf(stderr,"%s: WAVE fmt chunk must preceed data chunk.\n",fname);
            exit(1);
          }
          datap=1;
          
          if(seekable)
            filelength=(filelength-pos)/(ch*inbytes)*(ch*inbytes)+pos;

          if(chunklen==0UL ||
             chunklen==0x7fffffffUL || 
             chunklen==0xffffffffUL){
            file_list[i-1].begin=total;
            total=file_list[i-1].end=0;
            fprintf(stderr,"%s: Incomplete header; assuming stream.\n",fname);
          }else if(filelength==-1 || chunklen+pos<=filelength){
            file_list[i-1].begin=total;
            total=file_list[i-1].end=total+chunklen;
            fprintf(stderr,"%s: Using declared file size.\n",fname);
          }else{
            file_list[i-1].begin=total;
            total=file_list[i-1].end=total+filelength-pos;
            fprintf(stderr,"%s: Using actual file size.\n",fname);
          }
          file_list[i-1].data=ftello(f);
          
          break;
        } else {
          fprintf(stderr,"%s: Unknown chunk type %c%c%c%c; skipping.\n",fname,
                  buffer[0],buffer[1],buffer[2],buffer[3]);
          for(j=0;j<(int)chunklen;j++)
            if(fgetc(f)==EOF)break;
        }
      }

      if(!datap){
        fprintf(stderr,"%s: WAVE file has no data chunk.\n",fname);
        exit(1);
      }
      
    }else{
      fprintf(stderr,"%s: Unable to open file.\n",fname);
      exit(1);
    }
  }

  /* look at stdout... do we have a file or device? */
  if(!isatty(STDOUT_FILENO)){
    /* apparently; assume this is the file/device for output */
    loop_flag=0;
    outfileno=dup(STDOUT_FILENO);
    dup2(STDERR_FILENO,STDOUT_FILENO);
  }

<p>  /* load config */
#if 0
  {
    configfd=open(".postfishrc",O_RDWR|O_CREAT,0666);
    if(configfd>=0)load_settings(configfd);
  }
#endif

  /* set up the hack for interthread gtk event triggering through
   input subversion */
  if(pipe(eventpipe)){
    fprintf(stderr,"Unable to open event pipe:\n"
            "  %s\n",strerror(errno));
    
    exit(1);
  }

  aseek(0);

  mainpanel_go(argc,argv);

  playback_exit=1;

  while(1){
    if(playback_active){
      sched_yield();
    }else
      break;
  }

  //save_settings(configfd);
  if(configfd>=0)close(configfd);
  return(0);
}

<p><p><p><p><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