[xiph-commits] r14592 - trunk/spectrum

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Sun Mar 16 22:37:12 PDT 2008


Author: xiphmont
Date: 2008-03-16 22:37:11 -0700 (Sun, 16 Mar 2008)
New Revision: 14592

Modified:
   trunk/spectrum/analyzer.h
   trunk/spectrum/panel.c
   trunk/spectrum/plot.c
   trunk/spectrum/plot.h
   trunk/spectrum/process.c
   trunk/spectrum/version.h
Log:
Add subtraction modes, add noise floor sampling (not used yet)


Modified: trunk/spectrum/analyzer.h
===================================================================
--- trunk/spectrum/analyzer.h	2008-03-16 08:37:16 UTC (rev 14591)
+++ trunk/spectrum/analyzer.h	2008-03-17 05:37:11 UTC (rev 14592)
@@ -85,9 +85,11 @@
 extern void *process_thread(void *dummy);
 extern void process_dump(int mode);
 extern void rundata_clear();
+extern void clear_noise_floor();
 extern float **process_fetch(int res, int scale, int mode, int link, 
 			     int *active, int width, 
-			     float *ymax, float *pmax, float *pmin);
+			     float *ymax, float *pmax, float *pmin,
+			     float **floor, int noise);
 
 extern int inputs;
 extern int total_ch;
@@ -113,19 +115,23 @@
 extern sig_atomic_t process_active;
 extern sig_atomic_t process_exit;
 
-#define LINKS 10
-static char *link_entries[LINKS]={"independent","summed",".1\xCE\xA9 shunt","1\xCE\xA9 shunt","10\xCE\xA9 shunt",
-				  "resp/phase","THD","THD-2","THD+N","THD-2+N"};
+#define LINKS 12
+static char *link_entries[LINKS]={"independent","sum","subtract ref","subtract from",
+				  "imp .1\xCE\xA9 shunt","imp 1\xCE\xA9 shunt",
+				  "imp 10\xCE\xA9 shunt",
+				  "response/phase","THD","THD (-2nd)","THD+N","THD+N (-2nd)"};
 #define LINK_INDEPENDENT  0
 #define LINK_SUMMED       1
-#define LINK_IMPEDENCE_p1 2
-#define LINK_IMPEDENCE_1  3
-#define LINK_IMPEDENCE_10 4
-#define LINK_PHASE        5
-#define LINK_THD          6
-#define LINK_THD2         7
-#define LINK_THDN         8
-#define LINK_THDN2        9
+#define LINK_SUB_REF      2
+#define LINK_SUB_FROM     3
+#define LINK_IMPEDENCE_p1 4
+#define LINK_IMPEDENCE_1  5
+#define LINK_IMPEDENCE_10 6
+#define LINK_PHASE        7
+#define LINK_THD          8
+#define LINK_THD2         9
+#define LINK_THDN        10
+#define LINK_THDN2       11
 
 #endif
 

Modified: trunk/spectrum/panel.c
===================================================================
--- trunk/spectrum/panel.c	2008-03-16 08:37:16 UTC (rev 14591)
+++ trunk/spectrum/panel.c	2008-03-17 05:37:11 UTC (rev 14592)
@@ -54,6 +54,7 @@
 int plot_link=0;
 int plot_hold=0;
 int plot_depth=90;
+int plot_noise=0;
 int plot_last_update=0;
 int *active;
 
@@ -135,7 +136,28 @@
   process_dump(plot_mode);
 }
 
+static void noise(GtkWidget *widget,struct panel *p){
+  if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))){
+    if(plot_noise){
+      plot_noise=0;
+      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),0);
+      clear_noise_floor();
+      plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth,0);
+    }else{
+      plot_noise=1;
+      plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth,0);
+    }
+  }else{
+    if(plot_noise){
+      gtk_button_set_label(GTK_BUTTON(widget),"clear _noise floor");
+      plot_noise=2;
+      plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth,1);
+    }else
+      gtk_button_set_label(GTK_BUTTON(widget),"sample _noise floor");
+  }
+}
 
+
 static void depthchange(GtkWidget *widget,struct panel *p){
   int choice=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
   switch(choice){
@@ -155,7 +177,7 @@
     plot_depth=140;
     break;
   }
-  plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth);
+  plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth,plot_noise);
 }
 
 static void set_fg(GtkWidget *c, gpointer in){
@@ -170,6 +192,17 @@
     gtk_container_forall (GTK_CONTAINER(c),set_fg,in);
 }
 
+static void set_via_active(struct panel *p, int *active, int *bactive){
+  int fi,i;
+  int ch=0;
+  for(fi=0;fi<inputs;fi++){
+    for(i=ch;i<ch+channels[fi];i++)
+      gtk_widget_set_sensitive(p->chbuttons[i],1);
+    ch+=channels[fi];
+  }
+  plot_set_active(PLOT(p->plot),active,bactive);  
+}
+
 static void chlabels(GtkWidget *widget,struct panel *p){
   /* scan state, update labels on channel buttons, set sensitivity
      based on grouping and mode */
@@ -187,6 +220,9 @@
   case LINK_IMPEDENCE_10:
   case LINK_THD:
   case LINK_THDN:
+  case LINK_THD2:
+  case LINK_THDN2:
+  case LINK_SUB_REF:
 
     /*  first channel in each group insensitive/inactive, used as a reference */
     ch=0;
@@ -205,11 +241,8 @@
     plot_set_active(PLOT(p->plot),active,bactive);
     break;    
 
-
   case LINK_SUMMED: /* summing mode */
-
-    /* sum mode is a special case; all the data comes on first vector of
-       the group if any elements of the group are active at all */
+  case LINK_SUB_FROM: /* subtract channels from reference */
     ch=0;
     for(fi=0;fi<inputs;fi++){
       int any=0;
@@ -221,15 +254,11 @@
       ch+=channels[fi];
     }
 
-    /* fall through */
+    set_via_active(p,active,bactive);
+    break;
+
   case LINK_INDEPENDENT: /* normal/independent mode */
-    ch=0;
-    for(fi=0;fi<inputs;fi++){
-      for(i=ch;i<ch+channels[fi];i++)
-	gtk_widget_set_sensitive(p->chbuttons[i],1);
-      ch+=channels[fi];
-    }
-    plot_set_active(PLOT(p->plot),active,bactive);
+    set_via_active(p,active,bactive);
     break;    
 
   case LINK_PHASE: /* response/phase */
@@ -257,10 +286,12 @@
   switch(plot_link){
   case LINK_THD:
   case LINK_THDN:
+  case LINK_THD2:
+  case LINK_THDN2:
   case LINK_IMPEDENCE_p1:
   case LINK_IMPEDENCE_1:
   case LINK_IMPEDENCE_10:
-
+  case LINK_SUB_REF:
     ch=0;
     for(fi=0;fi<inputs;fi++){
       for(i=ch;i<ch+channels[fi];i++){
@@ -274,6 +305,20 @@
       ch+=channels[fi];
     }
     break;    
+  case LINK_SUB_FROM:
+    ch=0;
+    for(fi=0;fi<inputs;fi++){
+      for(i=ch;i<ch+channels[fi];i++){
+	if(i==ch){
+	  gtk_button_set_label(GTK_BUTTON(p->chbuttons[i]),"output");
+	}else{
+	  sprintf(buf,"channel %d", i-ch);
+	  gtk_button_set_label(GTK_BUTTON(p->chbuttons[i]),buf);
+	}
+      }
+      ch+=channels[fi];
+    }
+    break;    
 
   case LINK_INDEPENDENT:
   case LINK_SUMMED:
@@ -311,6 +356,7 @@
   /* set colors */
   switch(plot_link){
   case LINK_SUMMED:
+  case LINK_SUB_FROM:
     ch=0;
     for(fi=0;fi<inputs;fi++){
       GdkColor rgb = chcolor(ch);
@@ -340,24 +386,24 @@
 
 static void reschange(GtkWidget *widget,struct panel *p){
   plot_res=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
-  plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth);
+  plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth,plot_noise);
 }
 
 static void scalechange(GtkWidget *widget,struct panel *p){
   plot_scale=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
-  plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth);
+  plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth,plot_noise);
 }
 
 static void modechange(GtkWidget *widget,struct panel *p){
   plot_mode=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
   replot(p);
-  plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth);
+  plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth,plot_noise);
 }
 
 static void linkchange(GtkWidget *widget,struct panel *p){
   plot_link=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
   replot(p);
-  plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth);
+  plot_setting(PLOT(p->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth,plot_noise);
   chlabels(widget,p);
 }
 
@@ -544,7 +590,7 @@
     for(i=0;i<3;i++)
       gtk_combo_box_append_text (GTK_COMBO_BOX (menu), entries[i]);
     gtk_combo_box_set_active(GTK_COMBO_BOX(menu),plot_scale);
-    plot_setting(PLOT(panel->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth);
+    plot_setting(PLOT(panel->plot),plot_res,plot_scale,plot_mode,plot_link,plot_depth,plot_noise);
     gtk_box_pack_start(GTK_BOX(bbox),menu,0,0,0);
     
     g_signal_connect (G_OBJECT (menu), "changed",
@@ -648,6 +694,14 @@
     gtk_box_pack_start(GTK_BOX(bbox),button,0,0,0);
   }
 
+  /* noise floor */
+  {
+    GtkWidget *button=gtk_toggle_button_new_with_mnemonic("sample _noise floor");
+    gtk_widget_add_accelerator (button, "activate", panel->group, GDK_n, 0, 0);
+    g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (noise), panel);
+    gtk_box_pack_start(GTK_BOX(bbox),button,0,0,0);
+  }
+
   gtk_box_pack_end(GTK_BOX(rightbox),bbox,0,0,0);
   gtk_box_pack_start(GTK_BOX(mainbox),rightbox,0,0,0);
 

Modified: trunk/spectrum/plot.c
===================================================================
--- trunk/spectrum/plot.c	2008-03-16 08:37:16 UTC (rev 14591)
+++ trunk/spectrum/plot.c	2008-03-17 05:37:11 UTC (rev 14592)
@@ -210,6 +210,22 @@
     gdk_draw_rectangle(p->backing,gc,1,padx,0,width-padx,height-p->pady+1);
   }
 
+  /* draw the noise floor if active */
+  if(p->floor){
+    GdkColor rgb = {0,0xd000,0xd000,0xd000};
+    gdk_gc_set_rgb_fg_color(p->drawgc,&rgb);
+    
+    for(i=0;i<width-padx;i++){
+      float val=p->floor[i];
+      int y;
+
+      /* No noise floor is passed back for display in the modes where it's irrelevant */
+      y= rint((height-p->pady-1)/p->disp_depth*(p->disp_ymax-val));
+      if(y<height-p->pady)
+	gdk_draw_line(p->backing,p->drawgc,padx+i,y,padx+i,height-p->pady-1);
+    }
+  }
+
   /* draw the light x grid */
   {
     int i;
@@ -444,7 +460,7 @@
   }
   
   /* draw actual data */
-  {
+  if(p->ydata){
     int cho=0;
     int gi;
     for(gi=0;gi<p->groups;gi++){
@@ -537,9 +553,8 @@
 
 static void size_request (GtkWidget *widget,GtkRequisition *requisition){
   Plot *p=PLOT(widget);
-  /* no smaller than 800x600 */
   requisition->width = 800;
-  requisition->height = 600;
+  requisition->height = 440;
   int axisy=0,axisx=0,pady=0,padx=0,phax=0,px,py,i;
 
   /* find max lin layout */
@@ -618,7 +633,6 @@
 
 static gboolean configure(GtkWidget *widget, GdkEventConfigure *event){
   Plot *p=PLOT(widget);
-  int i;
 
   if (p->backing)
     g_object_unref(p->backing);
@@ -628,15 +642,8 @@
 			      widget->allocation.height,
 			      -1);
 
-  if(p->ydata){
-    for(i=0;i<p->total_ch;i++)free(p->ydata[i]);
-    free(p->ydata);
-  }
-
-  p->ydata=malloc(p->total_ch*sizeof(*p->ydata));
-  for(i=0;i<p->total_ch;i++)
-    p->ydata[i]=
-      calloc(widget->allocation.width,sizeof(**p->ydata));
+  p->ydata=NULL;
+  p->configured=1;
   
   compute_metadata(widget);
   plot_refresh(p,NULL);
@@ -765,22 +772,25 @@
 }
 
 void plot_refresh (Plot *p, int *process){
-  int i;
   float ymax,pmax,pmin;
   int width=GTK_WIDGET(p)->allocation.width-p->padx;
   int height=GTK_WIDGET(p)->allocation.height-p->pady;
   float **data;
-  
-  if(!p->ydata)return;
+  float *floor;
 
+  if(!p->configured)return;
+
   if(process)
     memcpy(p->ch_process,process,p->total_ch*sizeof(*process));
   
   data = process_fetch(p->res, p->scale, p->mode, p->link, 
-		       p->ch_process,width,&ymax,&pmax,&pmin);
+		       p->ch_process,width,&ymax,&pmax,&pmin,&floor,p->noise);
   
-  for(i=0;i<p->total_ch;i++)
-    memcpy(p->ydata[i],data[i],width*sizeof(**p->ydata));
+  p->ydata=data;
+  if(floor)
+    p->floor=floor;
+  else
+    p->floor=NULL;
 
   /* graph limit updates are conditional depending on mode/link */
   pmax+=5;
@@ -809,60 +819,65 @@
     break;
   }
 
-  //if(p->ymax>ymax)ymax=p->ymax;
-  //if(pmax<p->pmax)pmax=p->pmax;
-  //if(pmin>p->pmin)pmin=p->pmin;
-
-  /* scale regression is conditional and damped. Start the timer/run
-     the timer while any one scale measure should be dropping by more
-     than 50px. If any peaks occur above, reset timer.  Once timer
-     runs out, drop 5px per frame */
+  if(p->mode == 0){
+    /* "Instantaneous' mode scale regression is conditional and
+       damped. Start the timer/run the timer while any one scale measure
+       should be dropping by more than 50px. If any peaks occur above,
+       reset timer.  Once timer runs out, drop 5px per frame */
 #define PXTHRESH 25
 #define PXDEL 10.
 #define TIMERFRAMES 20
-  if(p->ymax>ymax){
-    float oldzero = (height-1)/p->depth*p->ymax;
-    float newzero = (height-1)/p->depth*ymax;
-
-    if(newzero+PXTHRESH<oldzero){
-      if(p->ymaxtimer){
-	p->ymaxtimer--;
+    if(p->ymax>ymax){
+      float oldzero = (height-1)/p->depth*p->ymax;
+      float newzero = (height-1)/p->depth*ymax;
+      
+      if(newzero+PXTHRESH<oldzero){
+	if(p->ymaxtimer){
+	  p->ymaxtimer--;
+	}else{
+	  p->ymax = (oldzero-PXDEL)*p->depth/(height-1);
+	}
       }else{
-	p->ymax = (oldzero-PXDEL)*p->depth/(height-1);
+	p->ymaxtimer = TIMERFRAMES;
       }
-    }else{
+    }else
       p->ymaxtimer = TIMERFRAMES;
-    }
-  }else
-    p->ymaxtimer = TIMERFRAMES;
-
-  if(p->pmax>pmax || p->pmin<pmin){
-    float newmax = (height-1)/(p->pmax-p->pmin)*(p->pmax-pmax);
-    float newmin = (height-1)/(p->pmax-p->pmin)*(pmin-p->pmin);
-
-    if(newmax>PXTHRESH || newmin>PXTHRESH){
-      if(p->phtimer){
-	p->phtimer--;
+    
+    if(p->pmax>pmax || p->pmin<pmin){
+      float newmax = (height-1)/(p->pmax-p->pmin)*(p->pmax-pmax);
+      float newmin = (height-1)/(p->pmax-p->pmin)*(pmin-p->pmin);
+      
+      if(newmax>PXTHRESH || newmin>PXTHRESH){
+	if(p->phtimer){
+	  p->phtimer--;
+	}else{
+	  if(newmax>PXTHRESH)
+	    p->pmax -= PXDEL/(height-1)*(p->pmax-p->pmin);
+	  if(newmin>PXTHRESH)
+	    p->pmin += PXDEL/(height-1)*(p->pmax-p->pmin);
+	}
       }else{
-	if(newmax>PXTHRESH)
-	  p->pmax -= PXDEL/(height-1)*(p->pmax-p->pmin);
-	if(newmin>PXTHRESH)
-	  p->pmin += PXDEL/(height-1)*(p->pmax-p->pmin);
+	p->phtimer = TIMERFRAMES;
       }
-    }else{
+    }else
       p->phtimer = TIMERFRAMES;
-    }
-  }else
-    p->phtimer = TIMERFRAMES;
-
+  }
+    
   if(ymax<p->depth-140.)ymax=p->depth-140.;
   if(ymax>140.)ymax=140.;
   if(pmax>180)pmax=180;
   if(pmin<-180)pmin=-180;  
-  if(ymax>p->ymax)p->ymax=ymax;
-  if(pmax>p->pmax)p->pmax=pmax;
-  if(pmin<p->pmin)p->pmin=pmin;
 
+  if(p->mode == 0){
+    if(ymax>p->ymax)p->ymax=ymax;
+    if(pmax>p->pmax)p->pmax=pmax;
+    if(pmin<p->pmin)p->pmin=pmin;
+  }else{
+    p->ymax=ymax;
+    p->pmax=pmax;
+    p->pmin=pmin;
+  }
+
   p->disp_depth = p->depth;
   p->disp_ymax = p->ymax;
   p->disp_pmax = p->pmax;
@@ -915,13 +930,14 @@
   return(p->ydata);
 }
 
-void plot_setting (Plot *p, int res, int scale, int mode, int link, int depth){
+void plot_setting (Plot *p, int res, int scale, int mode, int link, int depth, int noise){
   GtkWidget *widget=GTK_WIDGET(p);
   p->res=res;
   p->scale=scale;
   p->mode=mode;
   p->depth=depth;
   p->link=link;
+  p->noise=noise;
 
   p->ymax=-140;
   p->pmax=0;

Modified: trunk/spectrum/plot.h
===================================================================
--- trunk/spectrum/plot.h	2008-03-16 08:37:16 UTC (rev 14591)
+++ trunk/spectrum/plot.h	2008-03-17 05:37:11 UTC (rev 14592)
@@ -55,7 +55,9 @@
   PangoLayout **imp_layout;
   PangoLayout **phase_layout;
 
+  int configured;
   float **ydata;
+  float *floor;
 
   int groups;
   int *ch;
@@ -67,6 +69,7 @@
   int link;
   int scale;
   int res;
+  int noise;
   int *rate;
 
   int xgrid[11];
@@ -106,7 +109,7 @@
 GType          plot_get_type        (void);
 GtkWidget*     plot_new             (int n, int inputs, int *channels, int *rate);
 void	       plot_refresh         (Plot *m, int *process);
-void	       plot_setting         (Plot *m, int res, int scale, int mode, int link, int depth);
+void	       plot_setting         (Plot *m, int res, int scale, int mode, int link, int depth, int noise);
 void	       plot_draw            (Plot *m);
 void	       plot_clear           (Plot *m);
 int 	       plot_width           (Plot *m);

Modified: trunk/spectrum/process.c
===================================================================
--- trunk/spectrum/process.c	2008-03-16 08:37:16 UTC (rev 14591)
+++ trunk/spectrum/process.c	2008-03-17 05:37:11 UTC (rev 14592)
@@ -46,13 +46,20 @@
 int feedback_increment=0;
 
 float *feedback_count;
-float **feedback_work;
+float **plot_data;
+float *plot_floor=NULL;
+float **work_floor=NULL;
 float *process_work;
 
 float **feedback_acc;
 float **feedback_max;
 float **feedback_instant;
 
+/* Gentlemen, power up the Variance hammer */
+float **floor_y;
+float **floor_yy;
+int floor_count;
+
 float **ph_acc;
 float **ph_max;
 float **ph_instant;
@@ -62,6 +69,7 @@
 int metascale = -1;
 int metawidth = -1;
 int metares = -1;
+int metanoise = 0;
 
 sig_atomic_t acc_clear=0;
 sig_atomic_t acc_rewind=0;
@@ -409,11 +417,13 @@
   blockbuffer=malloc(total_ch*sizeof(*blockbuffer));
   process_work=calloc(blocksize+2,sizeof(*process_work));
   feedback_count=calloc(total_ch,sizeof(*feedback_count));
-  feedback_work=calloc(total_ch,sizeof(*feedback_work));
+  plot_data=calloc(total_ch,sizeof(*plot_data));
 
   feedback_acc=malloc(total_ch*sizeof(*feedback_acc));
   feedback_max=malloc(total_ch*sizeof(*feedback_max));
   feedback_instant=malloc(total_ch*sizeof(*feedback_instant));
+  floor_y=malloc(total_ch*sizeof(*floor_y));
+  floor_yy=malloc(total_ch*sizeof(*floor_yy));
 
   ph_acc=malloc(total_ch*sizeof(*ph_acc));
   ph_max=malloc(total_ch*sizeof(*ph_max));
@@ -423,6 +433,8 @@
   for(i=0;i<total_ch;i++){
     blockbuffer[i]=calloc(blocksize,sizeof(**blockbuffer));
 
+    floor_y[i]=calloc(blocksize/2+1,sizeof(**floor_y));
+    floor_yy[i]=calloc(blocksize/2+1,sizeof(**floor_yy));
     feedback_acc[i]=calloc(blocksize/2+1,sizeof(**feedback_acc));
     feedback_max[i]=calloc(blocksize/2+1,sizeof(**feedback_max));
     feedback_instant[i]=calloc(blocksize/2+1,sizeof(**feedback_instant));
@@ -656,10 +668,13 @@
   acc_clear=0;
 }
 
+extern int plot_noise;
+
 /* return 0 on EOF, 1 otherwise */
 static int process(){
   int fi,i,j,ch;
   int eof_all;
+  int noise=plot_noise;  
 
   /* for each file, FOR SCIENCE! */
   for(fi=0;fi<inputs;fi++){
@@ -715,6 +730,11 @@
 	  float sqI = I*I;
 	  float sqM = sqR+sqI;
 
+	  if(noise==1){
+	    floor_yy[i][j>>1]+=sqM*sqM;
+	    floor_y[i][j>>1]+=sqM;
+	  }
+	  
 	  /* deal with phase accumulate/rotate */
 	  if(i==ch){
 	    /* normalize/store ref for later rotation */
@@ -756,6 +776,8 @@
     }
     ch+=channels[fi];
   }
+  if(noise==1)
+    floor_count++;
   feedback_increment++;
   write(eventpipe[1],"",1);
   return 1;
@@ -842,21 +864,34 @@
 
 }
 
+void clear_noise_floor(){
+  int i;
+  for(i=0;i<total_ch;i++){
+    memset(floor_y[i],0,(blocksize/2+1)*sizeof(**floor_y));
+    memset(floor_yy[i],0,(blocksize/2+1)*sizeof(**floor_yy));
+  }
+  floor_count=0;
+}
+
 /* how many bins to 'trim' off the edge of calculated data when we
    know we've hit a boundary of marginal measurement */
 #define binspan 5
 
 float **process_fetch(int res, int scale, int mode, int link, 
 		      int *active, int width, 
-		      float *ymax, float *pmax, float *pmin){
+		      float *ymax, float *pmax, float *pmin,
+		      float **yfloor,int noise){
   int ch,ci,i,j,fi;
   float **data;
   float **ph;
 
+  *yfloor=NULL;
+
   /* are our scale mappings up to date? */
   if(res != metares || scale != metascale || width != metawidth){
     if(!xmappingL) xmappingL = calloc(inputs, sizeof(*xmappingL));
     if(!xmappingH) xmappingH = calloc(inputs, sizeof(*xmappingH));
+    metanoise=-1;
 
     for(fi=0;fi<inputs;fi++){
 
@@ -939,13 +974,93 @@
     }
 
     for(i=0;i<total_ch;i++)
-      if(feedback_work[i]){
-	feedback_work[i] = realloc(feedback_work[i],(width+1)*sizeof(**feedback_work));
+      if(plot_data[i]){
+	plot_data[i] = realloc(plot_data[i],(width+1)*sizeof(**plot_data));
       }else{
-	feedback_work[i] = malloc((width+1)*sizeof(**feedback_work));
+	plot_data[i] = malloc((width+1)*sizeof(**plot_data));
       }
   }
+
+  /* 'illustrate' the noise floor */
+  if(noise){
+    switch(link){
+    case LINK_INDEPENDENT:
+    case LINK_SUMMED:
+    case LINK_SUB_FROM:
+    case LINK_SUB_REF:	
       
+      if(plot_floor)
+	plot_floor=realloc(plot_floor,(width+1)*sizeof(*plot_floor));
+      else
+	plot_floor=calloc((width+1),sizeof(*plot_floor));
+      if(!work_floor)
+	work_floor = calloc(total_ch,sizeof(*work_floor));
+
+      if(metanoise!=link){
+	float *y = plot_floor;
+	float d = 1./floor_count;
+	int ch=0;
+	metanoise=link;
+	for(i=0;i<width;i++)
+	  y[i]=-300;
+	
+	for(fi=0;fi<inputs;fi++){
+	  float *L = xmappingL[fi];
+	  float *H = xmappingH[fi];
+	  
+	  for(ci=0;ci<channels[fi];ci++){
+	    float *fy = floor_y[ci+ch];
+	    float *fyy = floor_yy[ci+ch];
+	    float *w;
+	    if(work_floor[ci+ch])
+	      w = work_floor[ci+ch] = realloc(work_floor[ci+ch],(width+1)*sizeof(**work_floor));
+	    else
+	      w = work_floor[ci+ch] = calloc((width+1),sizeof(**work_floor));
+	    
+	    for(i=0;i<width;i++){
+	      int first=floor(L[i]);
+	      int last=floor(H[i]);
+	      float esum;
+	      float vsum;
+	      float v = fyy[first] - fy[first]*fy[first]*d;
+
+	      if(first==last){
+		float del=H[i]-L[i];
+		esum=fy[first]*del;
+		vsum=v*del;
+	      }else{
+		float del=1.-(L[i]-first);
+		esum=fy[first]*del;
+		vsum=v*del;
+		
+		for(j=first+1;j<last;j++){
+		  v = fyy[j] - fy[j]*fy[j]*d;
+		  esum+=fy[j];
+		  vsum+=v;
+		}
+
+		v = fyy[last] - fy[last]*fy[last]*d;
+		del=(H[i]-last);
+		esum+=fy[last]*del;
+		vsum+=v*del;
+	      }
+	      
+	      esum*=d;
+	      w[i] = esum+sqrt(vsum);
+	      w[i] = todB_a(w+i)*.5;
+
+	      if(w[i]>y[i])y[i]=w[i];
+	    }
+	  }
+	  ch+=channels[fi];
+	}
+      }
+      *yfloor=plot_floor;
+      break; 
+    }
+  }else
+    metanoise=-1;
+  
   /* mode selects the base data set */
   switch(mode){    
   case 0: /* independent / instant */
@@ -974,7 +1089,7 @@
     case LINK_INDEPENDENT:
       
       for(ci=0;ci<channels[fi];ci++){
-	float *y = feedback_work[ci+ch];
+	float *y = plot_data[ci+ch];
 	float *m = data[ci+ch];
 	if(active[ch+ci]){
 	  for(i=0;i<width;i++){
@@ -1006,7 +1121,7 @@
 
     case LINK_SUMMED:
       {
-	float *y = feedback_work[ch];
+	float *y = plot_data[ch];
 	memset(y,0,(width+1)*sizeof(*y));
       
 	for(ci=0;ci<channels[fi];ci++){
@@ -1041,15 +1156,101 @@
       }
       break;
       
+    case LINK_SUB_FROM:
+      {
+	float *y = plot_data[ch];
+	if(active[ch]==0){
+	  for(i=0;i<width;i++)
+	    y[i]=-300;
+	}else{
+	  for(ci=0;ci<channels[fi];ci++){
+	    float *m = data[ci+ch];
+	    if(ci==0 || active[ch+ci]){
+	      for(i=0;i<width;i++){
+		int first=floor(L[i]);
+		int last=floor(H[i]);
+		float sum;
+		
+		if(first==last){
+		  float del=H[i]-L[i];
+		  sum=m[first]*del;
+		}else{
+		  float del=1.-(L[i]-first);
+		  sum=m[first]*del;
+		  
+		  for(j=first+1;j<last;j++)
+		    sum+=m[j];
+		  
+		  del=(H[i]-last);
+		  sum+=m[last]*del;
+		}
+		
+		if(ci==0){
+		  y[i]=sum;
+		}else{
+		  y[i]-=sum;
+		}
+	      }
+	    }
+	  }
+	  
+	  for(i=0;i<width;i++){
+	    float v = (y[i]>0?y[i]:0);
+	    float sum=todB_a(&v)*.5;
+	    if(sum>*ymax)*ymax=sum;
+	    y[i]=sum;	  
+	  }
+	}
+      }
+      break;
+    case LINK_SUB_REF:
+      {
+	float *r = plot_data[ch];
+	for(ci=0;ci<channels[fi];ci++){
+	  float *y = plot_data[ch+ci];
+	  float *m = data[ci+ch];
+	  if(ci==0 || active[ch+ci]){
+	    for(i=0;i<width;i++){
+	      int first=floor(L[i]);
+	      int last=floor(H[i]);
+	      float sum;
+	      
+	      if(first==last){
+		float del=H[i]-L[i];
+		sum=m[first]*del;
+	      }else{
+		float del=1.-(L[i]-first);
+		sum=m[first]*del;
+		
+		for(j=first+1;j<last;j++)
+		  sum+=m[j];
+		
+		del=(H[i]-last);
+		sum+=m[last]*del;
+	      }
+	      
+	      if(ci==0){
+		r[i]=sum;
+	      }else{
+		sum=(r[i]>sum?0.f:sum-r[i]);
+		y[i]=todB_a(&sum)*.5;
+		if(y[i]>*ymax)*ymax=y[i];
+	      }
+	    }
+	  }
+	}
+      }
+      break;
+      
     case LINK_IMPEDENCE_p1:
     case LINK_IMPEDENCE_1:
     case LINK_IMPEDENCE_10:
       {
 	float shunt = (link == LINK_IMPEDENCE_p1?.1:(link == LINK_IMPEDENCE_1?1:10));
-	float *r = feedback_work[ch];
+	float *r = plot_data[ch];
 
 	for(ci=0;ci<channels[fi];ci++){
-	  float *y = feedback_work[ci+ch];
+	  float *y = plot_data[ci+ch];
 	  float *m = data[ch+ci];
 	  
 	  if(ci==0 || active[ch+ci]){
@@ -1104,7 +1305,7 @@
 
 	  for(ci=1;ci<channels[fi];ci++){
 	    if(active[ch+ci]){
-	      float *y = feedback_work[ci+ch];	      
+	      float *y = plot_data[ci+ch];	      
 	      for(i=0;i<width;i++){
 		if(r[i]<max-40 || r[i]<-70){
 		  int j=i-binspan;
@@ -1124,8 +1325,6 @@
 	      }
 	    }
  	  }
-	  fprintf(stderr,"ymax=%f\n",*ymax);
-
 	}
       }
       break;
@@ -1133,8 +1332,8 @@
     case LINK_PHASE: /* response/phase */
 
       if(channels[fi]>=2){
-	float *om = feedback_work[ch];
-	float *op = feedback_work[ch+1];
+	float *om = plot_data[ch];
+	float *op = plot_data[ch+1];
 
 	float *r = data[ch];
 	float *m = data[ch+1];
@@ -1258,16 +1457,17 @@
       break;
 
     case LINK_THD: /* THD */
-      break;
-      
+    case LINK_THD2: /* THD-2 */
     case LINK_THDN: /* THD+N */
+    case LINK_THDN2: /* THD+N-2 */
+
+
       break;
       
     }
     ch+=channels[fi];
   }
 
-  return feedback_work;
-
+  return plot_data;
 }
 

Modified: trunk/spectrum/version.h
===================================================================
--- trunk/spectrum/version.h	2008-03-16 08:37:16 UTC (rev 14591)
+++ trunk/spectrum/version.h	2008-03-17 05:37:11 UTC (rev 14592)
@@ -1,2 +1,2 @@
-#define VERSION "$Id: version.h 6914 2004-06-29 03:05:41Z xiphmont $ "
-/* DO NOT EDIT: Automated versioning hack [Sun Mar 16 01:54:54 EDT 2008] */
+#define VERSION "$Id$ "
+/* DO NOT EDIT: Automated versioning hack [Mon Mar 17 02:40:15 EDT 2008] */


Property changes on: trunk/spectrum/version.h
___________________________________________________________________
Name: svn:keywords
   + Id



More information about the commits mailing list