[xiph-cvs] r6531 - trunk/postfish

xiphmont at xiph.org xiphmont at xiph.org
Sun Apr 18 16:18:17 PDT 2004



Author: xiphmont
Date: 2004-04-18 19:18:16 -0400 (Sun, 18 Apr 2004)
New Revision: 6531

Modified:
   trunk/postfish/Makefile
   trunk/postfish/clippanel.c
   trunk/postfish/declip.c
   trunk/postfish/main.c
   trunk/postfish/mainpanel.c
   trunk/postfish/mainpanel.h
   trunk/postfish/multibar.c
   trunk/postfish/output.c
   trunk/postfish/postfish-gtkrc
   trunk/postfish/postfish.h
   trunk/postfish/version.h
Log:
Implement mute-button infrastructure tie-in

Implement muted channel support/passthrough in declipper

Signal path 'cleanup' in declipper; eliminate any clicks/thumps
  during realtime parameter adjustment

Remaining: realtime burst-CPU demand elimination in FFTW blocksize changes

<p><p>Modified: trunk/postfish/Makefile
===================================================================
--- trunk/postfish/Makefile	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/Makefile	2004-04-18 23:18:16 UTC (rev 6531)
@@ -15,12 +15,12 @@
         declip.c reconstruct.c multicompand.c windowbutton.c subpanel.c \
         feedback.c freq.c eq.c eqpanel.c compandpanel.c subband.c lpc.c \
         bessel.c suppresspanel.c suppress.c singlecomp.c singlepanel.c \
-	limit.c limitpanel.c
+	limit.c limitpanel.c mute.c mutedummy.c
 OBJ = main.o mainpanel.o multibar.o readout.o input.o output.o clippanel.o \
         declip.o reconstruct.o multicompand.o windowbutton.o subpanel.o \
         feedback.o freq.o eq.o eqpanel.o compandpanel.o subband.o lpc.o \
         bessel.o suppresspanel.o suppress.o singlecomp.o singlepanel.o \
-	limit.o limitpanel.o
+	limit.o limitpanel.o mute.o mutedummy.o
 GCF = `pkg-config --cflags gtk+-2.0` -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED
 
 all:	

Modified: trunk/postfish/clippanel.c
===================================================================
--- trunk/postfish/clippanel.c	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/clippanel.c	2004-04-18 23:18:16 UTC (rev 6531)
@@ -326,20 +326,22 @@
 }
 
 void clippanel_feedback(int displayit){
-  int clip[input_ch],count;
+  int clip[input_ch],count[input_ch];
   float peak[input_ch];
-  if(pull_declip_feedback(clip,peak,&count)){
+
+  if(pull_declip_feedback(clip,peak,count)){
     int i;
     for(i=0;i<input_ch;i++){
       float val[2],zero[2];
+
       val[0]=-1.,zero[0]=-1.;
-      val[1]=(count?clip[i]*100./count-.1:-1);
+      val[1]=(count[i]?clip[i]*100./count[i]-.1:-1);
       zero[1]=-1.;
 
       multibar_set(MULTIBAR(feedback_bars[i]),zero,val,2,
                    (displayit && declip_visible));
       
-      val[0]=(count?peak[i]:-1);
+      val[0]=peak[i];
       multibar_set(MULTIBAR(trigger_bars[i]),zero,val,1,
                    (displayit && declip_visible));
 

Modified: trunk/postfish/declip.c
===================================================================
--- trunk/postfish/declip.c	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/declip.c	2004-04-18 23:18:16 UTC (rev 6531)
@@ -43,8 +43,9 @@
 static u_int32_t *widthlookup=0;
 static float *window=0;
 static float width=.5;
-static float **lap=0;
+static float **lap;
 static float **cache;
+static u_int32_t cache_active;
 static int cache_samples;
 static int fillstate=0; /* 0: uninitialized
                            1: normal
@@ -53,21 +54,44 @@
 
 /* accessed across threads */
 sig_atomic_t *declip_active;
+int *declip_prev_active;
+
 sig_atomic_t declip_visible=0;
-sig_atomic_t declip_converge=2; /* 0=over, 1=full, 2=half, 3=partial, 4=approx */
 
 static float *chtrigger=0;
 static sig_atomic_t pending_blocksize=0;
 static float convergence=0.;
 static float iterations=0.;
 
+#include <stdio.h>
+static void _analysis(char *base,int i,float *v,int n,int dB,int offset){
+  int j;
+  FILE *of;
+  char buffer[80];
 
+  sprintf(buffer,"%s_%d.m",base,i);
+  of=fopen(buffer,"a");
+  
+  if(!of)perror("failed to open data dump file");
+  
+  for(j=0;j<n;j++){
+    fprintf(of,"%f ",(float)j+offset);
+    if(dB)
+      fprintf(of,"%f\n",todB(v[j]));
+    else
+      fprintf(of,"%f\n",(v[j]));
+  }
+  fprintf(of,"\n");
+  fclose(of);
+}
+
+
 /* feedback! */
 typedef struct declip_feedback{
   feedback_generic parent_class;
   float *peak;
-  int *clipcount;
-  int total;
+  int   *clipcount;
+  int   *total;
 } declip_feedback;
 
 static feedback_generic_pool feedpool;
@@ -76,16 +100,17 @@
   declip_feedback *ret=malloc(sizeof(*ret));
   ret->clipcount=malloc((input_ch)*sizeof(*ret->clipcount));
   ret->peak=malloc((input_ch)*sizeof(*ret->peak));
+  ret->total=malloc((input_ch)*sizeof(*ret->total));
   return (feedback_generic *)ret;
 }
 
-static void push_declip_feedback(int *clip,float *peak,int total){
+static void push_declip_feedback(int *clip,float *peak,int *total){
   int n=input_ch;
   declip_feedback *f=(declip_feedback *)
     feedback_new(&feedpool,new_declip_feedback);
   memcpy(f->clipcount,clip,n*sizeof(*clip));
   memcpy(f->peak,peak,n*sizeof(*peak));
-  f->total=total;
+  memcpy(f->total,total,n*sizeof(*total));
   feedback_push(&feedpool,(feedback_generic *)f);
 }
 
@@ -96,16 +121,59 @@
 
   if(clip)memcpy(clip,f->clipcount,sizeof(*clip)*input_ch);
   if(peak)memcpy(peak,f->peak,sizeof(*peak)*input_ch);
-  if(total)*total=f->total;
+  if(total)memcpy(total,f->total,sizeof(*total)*input_ch);
 
   feedback_old(&feedpool,(feedback_generic *)f);
   return 1;
 }
 
+static void setup_window(int left,int right){
+  int max=(left<right?right:left);
+  int i,j;
+
+  for(i=0;i<max-left;i++)
+    window[i]=0;
+
+  for(j=0;j<left;i++,j++)
+    window[i]=sin( M_PIl*j/(left*2) );
+
+  for(j=right;j<right*2;i++,j++)
+    window[i]=sin( M_PIl*j/(right*2) );
+
+  for(;i<max*2;i++)
+    window[i]=0;
+
+  for(i=0;i<max*2;i++) window[i]*=window[i];
+  for(i=0;i<max*2;i++) window[i]=sin(window[i]*M_PIl*.5);
+}
+
+static void setup_blocksize(int newblocksize){
+  int i;
+  if(blocksize)fftwf_destroy_plan(fftwf_weight);
+  blocksize=newblocksize;
+
+  fftwf_weight=fftwf_plan_dft_r2c_1d(blocksize*2,
+				     work,
+				     (fftwf_complex *)freq,
+				     FFTW_MEASURE);
+
+  lopad=1-rint(fromBark(toBark(0.)-width)*blocksize*2/input_rate);
+  hipad=rint(fromBark(toBark(input_rate*.5)+width)*blocksize*2/input_rate)+lopad;
+  for(i=0;i<blocksize;i++){
+    float bark=toBark(input_rate*i/(blocksize*2));
+    int hi=rint(fromBark(bark-width)*(blocksize*2)/input_rate)-1+lopad;
+    int lo=rint(fromBark(bark+width)*(blocksize*2)/input_rate)+1+lopad;
+    widthlookup[i]=(hi<<16)+lo;
+  }
+
+  reconstruct_reinit(blocksize*2);
+}
+
 /* called only by initial setup */
 int declip_load(void){
   int i;
   declip_active=calloc(input_ch,sizeof(*declip_active));
+  declip_prev_active=calloc(input_ch,sizeof(*declip_prev_active));
   chtrigger=malloc(input_ch*sizeof(*chtrigger));
   for(i=0;i<input_ch;i++)
     chtrigger[i]=1.;
@@ -121,10 +189,24 @@
   cache=malloc(input_ch*sizeof(*cache));
   for(i=0;i<input_ch;i++)
     cache[i]=malloc(input_size*sizeof(**cache));
+
   lap=malloc(input_ch*sizeof(*lap));
   for(i=0;i<input_ch;i++)
     lap[i]=malloc(input_size*sizeof(**lap));
+  
+  window=malloc(input_size*2*sizeof(window));
 
+  {    
+    /* alloc for largest possible blocksize */
+    int blocksize=input_size*2;
+    int loestpad=1-rint(fromBark(toBark(0.)-width)*blocksize*2/input_rate);
+    int hiestpad=rint(fromBark(toBark(input_rate*.5)+width)*blocksize*2/input_rate)+loestpad;
+    widthlookup=malloc((hiestpad+1)*sizeof(*widthlookup));
+    freq=fftwf_malloc((blocksize*2+2)*sizeof(freq));
+    work=fftwf_malloc((blocksize*2)*sizeof(freq));
+  }
+
+  pending_blocksize=input_size*2;
   return(0);
 }
 
@@ -203,16 +285,13 @@
 }
 
 /* work,freq are passed through the static buffer fftwf requires */
-static void declip(float *lap,float *out,
-		   int blocksize,float trigger,
+static void declip(int blocksize,float trigger,
                    float epsilon, float iteration,
-		   int *runningtotal, int *runningcount,float *peak,
-		   int active){
+		   int *runningtotal, int *runningcount){
   float flag[blocksize*2];
-  int    iterbound,i,j,count=0;
+  int    iterbound,i,count=0;
   
   for(i=blocksize/2;i<blocksize*3/2;i++){
-    if(fabs(work[i])>*peak)*peak=fabs(work[i]);
     flag[i]=0.;
     if(work[i]>=trigger || work[i]<=-trigger){
       flag[i]=1.;
@@ -223,52 +302,36 @@
   *runningtotal+=blocksize;
   *runningcount+=count;
 
-  if(active){
-
+  if(count){
     for(i=0;i<blocksize/2;i++)flag[i]=0.;
     for(i=blocksize*3/2;i<blocksize*2;i++)flag[i]=0.;
-
-    for(i=0;i<blocksize/2;i++)work[i]=0.;
+    
     for(i=0;i<blocksize;i++)work[i+blocksize/2]*=window[i];
-    for(i=blocksize*3/2;i<blocksize*2;i++)work[i]=0.;
-
+    
     fftwf_execute(fftwf_weight);
     sliding_bark_average(freq,blocksize*2,width);
     iterbound=blocksize*iteration;
     if(iterbound<10)iterbound=10;
-
-    if(count)reconstruct(work,freq,flag,epsilon,iterbound);
-
-    if(out)
-      for(i=0;i<blocksize/2;i++)
-	out[i]=lap[i]+work[i+blocksize/2]*window[i];
     
-    for(i=blocksize/2,j=0;i<blocksize;i++)
-      lap[j++]=work[i+blocksize/2]*window[i];
-
-  }else{
-
-    if(out)
-      for(i=0;i<blocksize/2;i++)
-	out[i]=work[i+blocksize/2];
-  
-    for(i=blocksize/2,j=0;i<blocksize;i++)
-      lap[j++]=work[i+blocksize/2]*window[i]*window[i];
-  }
-  for(i=blocksize/2;i<input_size;i++)
-    lap[i]=0.;
+    reconstruct(work,freq,flag,epsilon,iterbound);
+    
+    for(i=0;i<blocksize;i++)work[i+blocksize/2]*=window[i];
+  }else
+    for(i=0;i<blocksize;i++)work[i+blocksize/2]*=window[i]*window[i];
 }
 
 /* called only by playback thread */
+static int offset=0;
 time_linkage *declip_read(time_linkage *in){
-  int i;
+  int i,j,k;
   float local_trigger[input_ch];
-  int total=0;
   int count[input_ch];
+  int total[input_ch];
   float peak[input_ch];
+  u_int32_t active=0;
+  int next_blocksize=pending_blocksize;
+  int orig_blocksize;
 
-  time_linkage dummy;
-
   float local_convergence;
   float local_iterations;
   
@@ -280,98 +343,299 @@
 
   memset(count,0,sizeof(count));
   memset(peak,0,sizeof(peak));
+  memset(total,0,sizeof(total));
 
-  if(pending_blocksize!=blocksize){
-    if(blocksize){
-      free(widthlookup);
-      free(window);
-      fftwf_destroy_plan(fftwf_weight);
-      fftwf_free(freq);
-      fftwf_free(work);
+  switch(fillstate){
+  case 0: /* prime the lapping and cache */
+
+    /* set up for the blocksize we're actually using for now */
+    {
+      setup_blocksize(next_blocksize);
+      setup_window(blocksize/2,blocksize/2);
     }
-    blocksize=pending_blocksize;
 
-    freq=fftwf_malloc((blocksize*2+2)*sizeof(freq));
-    work=fftwf_malloc((blocksize*2)*sizeof(freq));
-    fftwf_weight=fftwf_plan_dft_r2c_1d(blocksize*2,
-				       work,
-				       (fftwf_complex *)freq,
-				       FFTW_MEASURE);
+    for(i=0;i<input_ch;i++){
+      int channel_active=declip_active[i]; 
+      declip_prev_active[i]=channel_active;
 
-    lopad=1-rint(fromBark(toBark(0.)-width)*blocksize*2/input_rate);
-    hipad=rint(fromBark(toBark(input_rate*.5)+width)*blocksize*2/input_rate)+lopad;
-    widthlookup=malloc((hipad+1)*sizeof(*widthlookup));
-    for(i=0;i<blocksize;i++){
-      float bark=toBark(input_rate*i/(blocksize*2));
-      int hi=rint(fromBark(bark-width)*(blocksize*2)/input_rate)-1+lopad;
-      int lo=rint(fromBark(bark+width)*(blocksize*2)/input_rate)+1+lopad;
-      widthlookup[i]=(hi<<16)+lo;
-    }
-    
-    window=malloc(blocksize*sizeof(*window));
-    for(i=0;i<blocksize;i++) window[i]=sin( M_PIl*i/blocksize );
-    for(i=0;i<blocksize;i++) window[i]*=window[i];
-    for(i=0;i<blocksize;i++) window[i]=sin(window[i]*M_PIl*.5);
+      /* peak feedback */
+      if(declip_visible){
+	float *l=in->data[i];
+	for(j=0;j<in->samples;j++)
+	  if(fabs(l[j])>peak[i])peak[i]=fabs(l[j]);
+      }
 
-    reconstruct_reinit(blocksize*2);
-  }
+      if(channel_active){
+	
+	/* fill work with the block spanning cache/in (first 1/4, last 1/4 are zeroed) */
+	memset(work,0,sizeof(*work)*blocksize);
+	memcpy(work+blocksize,in->data[i],sizeof(*work)*blocksize/2);
+	memset(work+blocksize+blocksize/2,0,sizeof(*work)*blocksize/2);
+	declip(blocksize,local_trigger[i],local_convergence,local_iterations,
+	       total+i,count+i);
 
-  switch(fillstate){
-  case 0: /* prime the lapping and cache */
-    for(i=0;i<input_ch;i++){
-      float *temp=in->data[i];
-      total=0;
-      memset(work+blocksize/2,0,sizeof(*work)*blocksize/2);
-      memcpy(work+blocksize,temp,sizeof(*work)*blocksize/2);
-      declip(lap[i],0,blocksize,
-	     local_trigger[i],local_convergence,local_iterations,
-	     &total,count+i,peak+i,declip_active[i]);
-      
-      memset(cache[i],0,sizeof(**cache)*input_size);
-      in->data[i]=cache[i];
-      cache[i]=temp;
+	/* second half of work goes to lap */
+	memcpy(lap[i],work+blocksize,sizeof(*work)*blocksize/2);
+
+	/* now iterate the pieces purely within in */
+	for(j=0;j+blocksize<=in->size;j+=blocksize/2){
+	  memset(work,0,sizeof(*work)*blocksize);
+	  memcpy(work+blocksize/2,in->data[i]+j,sizeof(*work)*blocksize);
+	  memset(work+blocksize+blocksize/2,0,sizeof(*work)*blocksize/2);
+
+	  declip(blocksize,local_trigger[i],local_convergence,local_iterations,
+		 total+i,count+i);
+
+	  /* second half of work goes to lap */
+	  {
+	    float *llap=lap[i]+j;
+	    float *lwork=work+blocksize/2;
+	    for(k=0;k<blocksize/2;k++)
+	      llap[k]+=lwork[k];
+	    memcpy(llap+k,lwork+k,sizeof(*work)*blocksize/2);
+	  }
+	}
+
+      }else{
+	/* no declipping to do, so direct cache/lap buffer rotation */
+
+	float *temp=cache[i];
+	cache[i]=in->data[i];
+	in->data[i]=temp;
+	memset(temp,0,sizeof(*temp)*input_size);
+      }
     }
     cache_samples=in->samples;
+    cache_active=in->active;
     fillstate=1;
     out.samples=0;
-    if(in->samples==in->size)goto tidy_up;
+    if(in->samples==in->size)break;
     
     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 */
+    orig_blocksize=blocksize;
+
+    /* the 'gap' transition and finishing off the output block is done
+       first as it may need to handle a blocksize transition (and a
+       temporary transition window */
+
+    if(next_blocksize != orig_blocksize){
+      if(next_blocksize > orig_blocksize) setup_blocksize(next_blocksize);
+      setup_window(orig_blocksize/2,next_blocksize/2);
+    }
+
+    /* the gap piece is also special in that it may need to deal with
+       a transition to/from mute and/or a transition to/from bypass */
+    
     for(i=0;i<input_ch;i++){
-      float *temp=cache[i];
-      int j;
-      total=0;
-      for(j=0;j+blocksize<=out.size;j+=blocksize/2){
-	memcpy(work+blocksize/2,temp+j,sizeof(*work)*blocksize);
-	declip(lap[i],out.data[i]+j,blocksize,
-	       local_trigger[i],local_convergence,local_iterations,
-	       &total,count+i,peak+i,declip_active[i]);
+      int channel_active=declip_active[i];
+
+      /* peak feedback */
+      if(declip_visible){
+	float *l=in->data[i];
+	for(j=0;j<in->samples;j++)
+	  if(fabs(l[j])>peak[i])peak[i]=fabs(l[j]);
       }
-      memcpy(work+blocksize/2,temp+j,sizeof(*work)*blocksize/2);
-      memcpy(work+blocksize,in->data[i],sizeof(*work)*blocksize/2);
-      
-      declip(lap[i],out.data[i]+j,blocksize,
-	     local_trigger[i],local_convergence,local_iterations,
-	     &total,count+i,peak+i,declip_active[i]);
-      
-      cache[i]=in->data[i];
-      in->data[i]=temp;
+
+      if( mute_channel_muted(in->active,i) &&
+	  mute_channel_muted(cache_active,i)){
+	/* Cache: Muted=True , Bypass=X 
+	   Input: Muted=True , Bypass=X */
+
+	/* we may need cache for a later transition, so keep it up to date */
+	float *temp=cache[i];
+	cache[i]=in->data[i];
+	in->data[i]=temp;
+
+      }else{
+	if(mute_channel_muted(cache_active,i)){
+	  if(channel_active){
+	    /* Cache: Muted=True , Bypass=X 
+	       Input: Muted=False, Bypass=False */
+	    
+	    /* rotate cache */
+	    float *temp=cache[i];
+	    cache[i]=in->data[i];
+	    in->data[i]=temp;
+	    /* zero the lap */
+	    memset(lap[i],0,sizeof(*lap[i])*blocksize/2);
+
+	  }else{
+	  /* Cache: Muted=True , Bypass=X 
+	     Input: Muted=False, Bypass=True */
+
+	    /* silence->bypass; transition must happen in the current outblock */
+	    active|=(1<<i); /* audible output in out.data[i] */
+	    memset(out.data[i],0,sizeof(*out.data[i])*input_size);
+	    for(j=input_size-blocksize/2,k=0;j<input_size;j++,k++)
+	      out.data[i][j]=cache[i][j]*window[k]*window[k];
+
+	    float *temp=cache[i];
+	    cache[i]=in->data[i];
+	    in->data[i]=temp;
+	  }
+	}else{
+	  active|=(1<<i); /* audible output in out.data[i] */
+
+	  if(mute_channel_muted(in->active,i)){
+	    if(declip_prev_active[i]){
+	      /* Cache: Muted=False, Bypass=False
+		 Input: Muted=True,  Bypass=X     */
+
+	      /* transition to mute, so lap is finished output.  Rotate all */
+	      float *temp=cache[i];
+	      cache[i]=in->data[i];
+	      in->data[i]=temp;
+
+	      temp=out.data[i];
+	      out.data[i]=lap[i];
+	      lap[i]=temp;
+	    }else{
+	      /* Cache: Muted=False, Bypass=True
+		 Input: Muted=True,  Bypass=X     */
+	      
+	      /* rotate in/cache/out, transition out */
+	      float *temp=out.data[i];
+	      out.data[i]=cache[i];
+	      cache[i]=in->data[i];
+	      in->data[i]=temp;
+	      for(j=input_size-blocksize/2,k=0;j<input_size;j++,k++){
+		float w=(1.-window[k]);
+		out.data[i][j]*=w*w;
+	      }
+	    }
+	  }else{
+	    if(!declip_prev_active[i]){
+	      if(!channel_active){
+		/* Cache: Muted=False, Bypass=True
+		   Input: Muted=False, Bypass=True     */
+
+		/* all bypass! rotate in/cache/out */
+		float *temp=out.data[i];
+		out.data[i]=cache[i];
+		cache[i]=in->data[i];
+		in->data[i]=temp;
+	      }else{
+		/* Cache: Muted=False, Bypass=True
+		   Input: Muted=False, Bypass=False     */
+		
+		/* transition the lap */
+		for(j=0,k=blocksize/2;j<blocksize/2;j++,k++)
+		  lap[i][j]=in->data[i][j]*window[k]*window[k];
+	      
+		/* all rotate in/cache/out */
+		float *temp=out.data[i];
+		out.data[i]=cache[i];
+		cache[i]=in->data[i];
+		in->data[i]=temp;
+	      }
+	    }else{
+	      if(!channel_active){
+		/* Cache: Muted=False, Bypass=False
+		   Input: Muted=False, Bypass=True     */
+		
+		/* finish off lap, then rotate all */
+		for(j=input_size-blocksize/2,k=0;j<input_size;j++,k++)
+		  lap[i][j]+=cache[i][j]*window[k]*window[k];
+		float *temp=cache[i];
+		cache[i]=in->data[i];
+		in->data[i]=temp;
+		
+		temp=out.data[i];
+		out.data[i]=lap[i];
+		lap[i]=temp;
+	      }else{
+		/* Cache: Muted=False, Bypass=False
+		   Input: Muted=False, Bypass=False */
+
+		/* nominal case; the only one involving declipping the gap */
+		memset(work,0,sizeof(*work)*blocksize/2);
+		memcpy(work+blocksize/2,cache[i]+input_size-blocksize/2,sizeof(*work)*blocksize/2);
+		memcpy(work+blocksize,in->data[i],sizeof(*work)*blocksize/2);
+		memset(work+blocksize+blocksize/2,0,sizeof(*work)*blocksize/2);
+
+		declip(blocksize,local_trigger[i],local_convergence,local_iterations,
+		       total+i,count+i);
+
+		/* finish lap from last frame */
+		{
+		  float *llap=lap[i]+input_size-blocksize/2;
+		  float *lwork=work+blocksize/2;
+		  for(j=0;j<blocksize/2;j++)
+		    llap[j]+=lwork[j];
+		}
+		/* rotate buffers */
+		float *temp=out.data[i];
+		out.data[i]=lap[i];
+		lap[i]=temp;
+
+		temp=in->data[i];
+		in->data[i]=cache[i];
+		cache[i]=temp;
+		
+		/* begin lap for this frame */
+		memcpy(lap[i],work+blocksize,sizeof(*work)*blocksize/2);
+	      }
+	    }
+	  }
+	}
+      }
+      declip_prev_active[i]=channel_active;
     }
+
+    /* also rotate metadata */
     out.samples=cache_samples;
     cache_samples=in->samples;
+    cache_active=in->active;
+
+    /* finish transition to new blocksize (if a change is in progress) */
+    if(next_blocksize != orig_blocksize){
+      if(next_blocksize <= orig_blocksize) setup_blocksize(next_blocksize);
+      setup_window(blocksize/2,blocksize/2);
+    }
+
+    /* declip the rest of the current frame */
+    for(i=0;i<input_ch;i++){
+      if(!mute_channel_muted(cache_active,i)){
+	/* declip */
+	if(declip_prev_active[i]){
+	  
+	  for(j=0;j+blocksize<=in->size;j+=blocksize/2){
+	    memset(work,0,sizeof(*work)*blocksize);
+	    memcpy(work+blocksize/2,cache[i]+j,sizeof(*work)*blocksize);
+	    memset(work+blocksize+blocksize/2,0,sizeof(*work)*blocksize/2);
+	    declip(blocksize,local_trigger[i],local_convergence,local_iterations,
+		   total+i,count+i);
+	    
+	    {
+	      float *llap=lap[i]+j;
+	      float *lwork=work+blocksize/2;
+	      for(k=0;k<blocksize/2;k++)
+		llap[k]+=lwork[k];
+	      memcpy(llap+k,lwork+k,sizeof(*work)*blocksize/2);
+	    }
+	  }
+	}
+      }
+    }
     if(out.samples<out.size)fillstate=2;
     break;
   case 2: /* we've pushed out EOF already */
     out.samples=0;
   }
 
-  push_declip_feedback(count,peak,total);
+  push_declip_feedback(count,peak,total); /* we can push one (and
+                                             exactly one) for every
+                                             block that comes in *or*
+                                             one for every block that
+                                             goes out.  In declip,
+                                             it's for every block that
+                                             comes in */
 
- tidy_up:
   {
     int tozero=out.size-out.samples;
     if(tozero)
@@ -379,5 +643,13 @@
         memset(out.data[i]+out.samples,0,sizeof(**out.data)*tozero);
   }
 
+  out.active=active;
+
+  /* XXXX Temporary! Until later plugins can handle mute, we zero out
+     muted channels here */
+  for(i=0;i<input_ch;i++)
+    if((active & (1<<i))==0)
+      memset(out.data[i],0,sizeof(*out.data[i])*input_size);
+
   return &out;
 }

Modified: trunk/postfish/main.c
===================================================================
--- trunk/postfish/main.c	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/main.c	2004-04-18 23:18:16 UTC (rev 6531)
@@ -37,6 +37,7 @@
 #include "multicompand.h"
 #include "singlecomp.h"
 #include "limit.h"
+#include "mute.h"
 
 pthread_mutex_t master_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
@@ -55,6 +56,7 @@
   if(multicompand_load())exit(1);
   if(singlecomp_load())exit(1);
   if(limit_load())exit(1);
+  if(mute_load())exit(1);
 
   /* look at stdout... do we have a file or device? */
   if(!isatty(STDOUT_FILENO)){

Modified: trunk/postfish/mainpanel.c
===================================================================
--- trunk/postfish/mainpanel.c	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/mainpanel.c	2004-04-18 23:18:16 UTC (rev 6531)
@@ -43,12 +43,13 @@
 }
 
 static void action_zero(GtkWidget *widget,postfish_mainpanel *p){
-  const char *time=gtk_entry_get_text(GTK_ENTRY(p->entry_a));
-  off_t cursor=input_time_to_cursor(time);
+  char buf[14];
+  off_t cursor;
 
   output_halt_playback();
-  input_seek(cursor);
-  readout_set(READOUT(p->cue),(char *)time);
+  cursor=input_seek(0);
+  input_cursor_to_time(cursor,buf);
+  readout_set(READOUT(p->cue),buf);
   multibar_reset(MULTIBAR(p->inbar));
   multibar_reset(MULTIBAR(p->outbar));
   clippanel_reset();
@@ -60,8 +61,8 @@
 }
 
 static void action_end(GtkWidget *widget,postfish_mainpanel *p){
-  off_t cursor=input_time_to_cursor("9999:59:59.99");
   char buf[14];
+  off_t cursor=input_time_to_cursor("9999:59:59.99");
 
   output_halt_playback();
   cursor=input_seek(cursor);
@@ -248,20 +249,6 @@
   }
 }
 
-static void action_reseta(GtkWidget *widget,postfish_mainpanel *p){
-  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){
-  char time[14];
-  input_cursor_to_time(0.,time);
-  gtk_entry_set_text(GTK_ENTRY(p->entry_b),time);
-  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(p->cue_b),0);
-}
-
 static void shutdown(void){
   gtk_main_quit ();
 }
@@ -879,13 +866,6 @@
                         G_CALLBACK (action_seta), panel);
       gtk_box_pack_start(GTK_BOX(cuebox),temp,0,0,0);
       
-      temp=gtk_button_new_with_label("^A");
-      gtk_widget_add_accelerator (temp, "activate", panel->group, GDK_a, GDK_CONTROL_MASK, 0);
-      g_signal_connect (G_OBJECT (temp), "clicked",
-			G_CALLBACK (action_reseta), panel);
-      gtk_widget_set_name(temp,"reseta");
-      gtk_box_pack_start(GTK_BOX(cuebox),temp,0,0,0);
-
       panel->cue_b=temp=gtk_toggle_button_new_with_label(" b ");
       gtk_widget_add_accelerator (temp, "activate", panel->group, GDK_b, 0, 0);
       g_signal_connect (G_OBJECT (temp), "clicked",
@@ -900,14 +880,6 @@
       gtk_box_pack_start(GTK_BOX(cuebox),panel->entry_b,0,0,0);
       gtk_box_pack_start(GTK_BOX(cuebox),temp,0,0,0);
 
-      temp=gtk_button_new_with_label("^B");
-      gtk_widget_add_accelerator (temp, "activate", panel->group, GDK_b, GDK_CONTROL_MASK, 0);
-      g_signal_connect (G_OBJECT (temp), "clicked",
-			G_CALLBACK (action_resetb), panel);
-      gtk_widget_set_name(temp,"resetb");
-      gtk_box_pack_start(GTK_BOX(cuebox),temp,0,0,0);
-
-
       gtk_entry_set_width_chars(GTK_ENTRY(panel->entry_a),13);
       gtk_entry_set_width_chars(GTK_ENTRY(panel->entry_b),13);
       gtk_entry_set_text(GTK_ENTRY(panel->entry_a),"    :  :00.00");
@@ -943,7 +915,7 @@
       gtk_table_attach_defaults(GTK_TABLE(ttable),conflabel,0,1,6,7);
       gtk_table_attach(GTK_TABLE(ttable),confbox,1,2,6,7,
                        GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,0,3);
-      gtk_table_attach(GTK_TABLE(ttable),panel,2,3,6,7,0,0,0,0);
+      gtk_table_attach_defaults(GTK_TABLE(ttable),panel,2,3,6,7);
 
       gtk_box_pack_start(GTK_BOX(confbox),conf,1,1,0);
     }
@@ -975,7 +947,7 @@
     gtk_table_attach_defaults(GTK_TABLE(channeltable),temp,1,2+input_ch*2,0,1);
   }
 
-  mainpanel_chentry(panel,channeltable,"Mute ",0,0,0,0);
+  mainpanel_chentry(panel,channeltable,"Mute ",0,0,0,mutedummy_create);
   mainpanel_chentry(panel,channeltable,"_Declip ",1,1,0,clippanel_create);
   mainpanel_chentry(panel,channeltable,"_Multicomp ",2,0,1,0);
   mainpanel_chentry(panel,channeltable,"_Onecomp ",3,0,1,0);

Modified: trunk/postfish/mainpanel.h
===================================================================
--- trunk/postfish/mainpanel.h	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/mainpanel.h	2004-04-18 23:18:16 UTC (rev 6531)
@@ -31,6 +31,7 @@
 #include "compandpanel.h"
 #include "singlepanel.h"
 #include "limitpanel.h"
+#include "mutedummy.h"
 
 struct postfish_mainpanel{
   GtkWidget *twirlimage;

Modified: trunk/postfish/multibar.c
===================================================================
--- trunk/postfish/multibar.c	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/multibar.c	2004-04-18 23:18:16 UTC (rev 6531)
@@ -462,7 +462,6 @@
   if(m->thumbs){
     int height=widget->allocation.height,i,j;
     GdkGC *black_gc=widget->style->black_gc;
-    int y=height/2-3;
     int y0=height/3-1;
     int y1=height-3;
 

Modified: trunk/postfish/output.c
===================================================================
--- trunk/postfish/output.c	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/output.c	2004-04-18 23:18:16 UTC (rev 6531)
@@ -34,6 +34,7 @@
 #include "singlecomp.h"
 #include "suppress.h"
 #include "limit.h"
+#include "mute.h"
 
 extern int input_size;
 sig_atomic_t playback_active=0;
@@ -232,8 +233,13 @@
     /* get data */
     link=input_read();
     result=link->samples;
+
+    link=mute_read(link);
+    result|=link->samples;
+
     link=declip_read(link);
     result|=link->samples;
+
     link=multicompand_read(link);
     result|=link->samples;
     link=singlecomp_read(link);

Modified: trunk/postfish/postfish-gtkrc
===================================================================
--- trunk/postfish/postfish-gtkrc	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/postfish-gtkrc	2004-04-18 23:18:16 UTC (rev 6531)
@@ -174,7 +174,6 @@
 widget "*.GtkEntry" style "readout"
 widget "*.GtkHScale" style "slider"
 widget "*.GtkToggleButton*" style "button-poppy"
-widget "*.reset*" style "quitbutton"
 widget "*.GtkButton*" style "button-poppy"
 widget "*.GtkCheckButton" style "check-poppy"
 widget "*.Windowbutton*" style "button-poppy"

Modified: trunk/postfish/postfish.h
===================================================================
--- trunk/postfish/postfish.h	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/postfish.h	2004-04-18 23:18:16 UTC (rev 6531)
@@ -92,6 +92,7 @@
   int channels;
   int rate;
   float **data;
+  u_int32_t active; /* active channel bitmask */
 } time_linkage;
 
 extern pthread_mutex_t master_mutex;
@@ -107,5 +108,7 @@
 extern int input_ch;
 
 extern void mainpanel_go(int n,char *list[],int ch);
+extern int mute_channel_muted(u_int32_t bitmap,int i);
 
 #endif
+

Modified: trunk/postfish/version.h
===================================================================
--- trunk/postfish/version.h	2004-04-18 09:56:07 UTC (rev 6530)
+++ trunk/postfish/version.h	2004-04-18 23:18:16 UTC (rev 6531)
@@ -1,2 +1,2 @@
 #define VERSION "$Id$ "
-/* DO NOT EDIT: Automated versioning hack [Sat Apr 17 01:27:16 EDT 2004] */
+/* DO NOT EDIT: Automated versioning hack [Sun Apr 18 18:58:52 EDT 2004] */

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list