[xiph-commits] r18353 - trunk/spectrum
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Sun Jun 3 20:26:49 PDT 2012
Author: xiphmont
Date: 2012-06-03 20:26:48 -0700 (Sun, 03 Jun 2012)
New Revision: 18353
Modified:
trunk/spectrum/analyzer.h
trunk/spectrum/io.c
trunk/spectrum/io.h
trunk/spectrum/spec_panel.c
trunk/spectrum/spec_plot.h
trunk/spectrum/spec_process.c
trunk/spectrum/spectrum.c
trunk/spectrum/version.h
trunk/spectrum/wave_panel.c
trunk/spectrum/wave_plot.c
trunk/spectrum/wave_plot.h
trunk/spectrum/wave_process.c
trunk/spectrum/waveform.c
trunk/spectrum/waveform.h
Log:
Add on-the-fly pipe reconfiguration to waveform viewer as well
Modified: trunk/spectrum/analyzer.h
===================================================================
--- trunk/spectrum/analyzer.h 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/analyzer.h 2012-06-04 03:26:48 UTC (rev 18353)
@@ -85,8 +85,7 @@
extern void process_dump(int mode);
extern void rundata_clear();
extern fetchdata *process_fetch(int scale, int mode, int link,
- int *process, int process_n,
- int height, int width);
+ int *process, int height, int width);
extern sig_atomic_t acc_rewind;
extern sig_atomic_t acc_loop;
Modified: trunk/spectrum/io.c
===================================================================
--- trunk/spectrum/io.c 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/io.c 2012-06-04 03:26:48 UTC (rev 18353)
@@ -26,7 +26,7 @@
#include <unistd.h>
#include "io.h"
-pthread_mutex_t ioparam_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+static pthread_mutex_t ioparam_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
int bits[MAX_FILES] = {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
int bigendian[MAX_FILES] = {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
int channels[MAX_FILES] = {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
@@ -58,6 +58,8 @@
int global_seekable=0;
int total_ch=0;
+static void (*lc)(void)=NULL;
+
static int host_is_big_endian() {
int32_t pattern = 0xfeedface; /* deadbeef */
unsigned char *bytewise = (unsigned char *)&pattern;
@@ -131,12 +133,11 @@
/* used to load or reload an input */
static int load_one_input(int fi){
- int i,reload=0;
+ int i;
if(f[fi]){
fclose(f[fi]);
f[fi]=NULL;
- reload=1;
blockbufferfill[fi]=0;
readbufferptr[fi]=0;
readbufferfill[fi]=0;
@@ -401,7 +402,7 @@
return 0;
}
-int input_load(void){
+int input_load(void (*load_callback)(void)){
int fi;
if(inputs==0){
/* look at stdin... is it a file, pipe, tty...? */
@@ -426,6 +427,11 @@
exit(1);
}
+ if(load_callback){
+ lc = load_callback;
+ load_callback();
+ }
+
return 0;
}
@@ -441,6 +447,8 @@
fprintf(stderr,"reloading....\n");
ret=1;
}
+
+ if(ret && lc)lc();
return ret;
}
Modified: trunk/spectrum/io.h
===================================================================
--- trunk/spectrum/io.h 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/io.h 2012-06-04 03:26:48 UTC (rev 18353)
@@ -46,10 +46,9 @@
#define MAX_FILES 16
#define readbuffersize 512
-extern pthread_mutex_t ioparam_mutex;
-extern int input_load(void);
-extern int pipe_reload(void);
+extern int input_load(void (*load_callback)(void));
extern void set_blockslice(int slice, int fi);
+extern int pipe_reload(void);
extern int input_read(int loop_p, int partial_p);
extern int rewind_files(void);
Modified: trunk/spectrum/spec_panel.c
===================================================================
--- trunk/spectrum/spec_panel.c 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/spec_panel.c 2012-06-04 03:26:48 UTC (rev 18353)
@@ -572,7 +572,8 @@
}
/* rate, channels, bits, channel active buttons */
-static void create_chbuttons(int *active){
+static void create_chbuttons(int *bits, int *rate, int *channels,
+ int *active){
int i,fi;
int ch=0;
char buffer[160];
@@ -649,21 +650,12 @@
/* update the spectral display; send new data */
fetchdata *f = process_fetch
(plot_scale, plot_mode, plot_link,
- process, plot_ch, plot_height(PLOT(plot)), plot_width(PLOT(plot)));
+ process, plot_height(PLOT(plot)), plot_width(PLOT(plot)));
- fprintf(stderr,"%f %f %d\n",f->ymax,f->data[0][0],f->active[0]);
-
/* the fetched data may indicate the underlying file data has
changed... */
if(f->reload){
- /* update group block slices */
- for(i=0;i<f->groups;i++){
- int sl=f->rate[i]/10;
- while(sl>blocksize/2)sl/=2;
- set_blockslice(sl,i);
- }
-
/* remove old group labels and channel buttons */
destroy_chbuttons();
@@ -672,12 +664,12 @@
/* create new buttons/labels */
{
- int newprocess[total_ch];
+ int newprocess[f->total_ch];
for(i=0;i<plot_ch && i<old_ch;i++)
newprocess[i]=process[i];
for(;i<plot_ch;i++)
newprocess[i]=0;
- create_chbuttons(newprocess);
+ create_chbuttons(f->bits,f->rate,f->channels,newprocess);
}
}
@@ -861,7 +853,7 @@
gtk_table_set_row_spacing (GTK_TABLE (toptable), 0, 6);
}
- create_chbuttons(NULL);
+ create_chbuttons(bits,rate,channels,NULL);
/* add the action buttons */
GtkWidget *bbox=gtk_vbox_new(0,0);
Modified: trunk/spectrum/spec_plot.h
===================================================================
--- trunk/spectrum/spec_plot.h 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/spec_plot.h 2012-06-04 03:26:48 UTC (rev 18353)
@@ -29,17 +29,6 @@
#include <gtk/gtk.h>
#include "io.h"
-G_BEGIN_DECLS
-
-#define PLOT_TYPE (plot_get_type ())
-#define PLOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PLOT_TYPE, Plot))
-#define PLOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PLOT_TYPE, PlotClass))
-#define IS_PLOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PLOT_TYPE))
-#define IS_PLOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PLOT_TYPE))
-
-typedef struct _Plot Plot;
-typedef struct _PlotClass PlotClass;
-
typedef struct {
int bits[MAX_FILES];
int channels[MAX_FILES];
@@ -71,6 +60,17 @@
float bold;
} plotparams;
+G_BEGIN_DECLS
+
+#define PLOT_TYPE (plot_get_type ())
+#define PLOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PLOT_TYPE, Plot))
+#define PLOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PLOT_TYPE, PlotClass))
+#define IS_PLOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PLOT_TYPE))
+#define IS_PLOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PLOT_TYPE))
+
+typedef struct _Plot Plot;
+typedef struct _PlotClass PlotClass;
+
struct _Plot{
GtkDrawingArea canvas;
Modified: trunk/spectrum/spec_process.c
===================================================================
--- trunk/spectrum/spec_process.c 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/spec_process.c 2012-06-04 03:26:48 UTC (rev 18353)
@@ -29,26 +29,26 @@
static fftwf_plan plan=NULL;
static int prev_total_ch=-1;
-pthread_mutex_t feedback_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-int feedback_increment=0;
+static pthread_mutex_t feedback_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+static int feedback_increment=0;
-float *feedback_count=NULL;
-float *process_work=NULL;
+static float *feedback_count=NULL;
+static float *process_work=NULL;
-float **feedback_acc=NULL;
-float **feedback_max=NULL;
-float **feedback_instant=NULL;
+static float **feedback_acc=NULL;
+static float **feedback_max=NULL;
+static float **feedback_instant=NULL;
-float **ph_acc=NULL;
-float **ph_max=NULL;
-float **ph_instant=NULL;
+static float **ph_acc=NULL;
+static float **ph_max=NULL;
+static float **ph_instant=NULL;
-float **xmappingL=NULL;
-float **xmappingM=NULL;
-float **xmappingH=NULL;
-int metascale = -1;
-int metawidth = -1;
-int metareload = 0;
+static float **xmappingL=NULL;
+static float **xmappingM=NULL;
+static float **xmappingH=NULL;
+static int metascale = -1;
+static int metawidth = -1;
+static int metareload = 0;
sig_atomic_t acc_rewind=0;
sig_atomic_t acc_loop=0;
@@ -343,8 +343,7 @@
/* the data returned is now 2 vals per bin; a min and a max. The spec
plot merely draws a vertical line between. */
fetchdata *process_fetch(int scale, int mode, int link,
- int *process_in, int process_n,
- int height, int width){
+ int *process_in, int height, int width){
int ch,ci,i,j,fi;
float **data;
float **ph;
Modified: trunk/spectrum/spectrum.c
===================================================================
--- trunk/spectrum/spectrum.c 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/spectrum.c 2012-06-04 03:26:48 UTC (rev 18353)
@@ -1,24 +1,24 @@
/*
*
* gtk2 spectrum analyzer
- *
+ *
* Copyright (C) 2004-2012 Monty
*
* This analyzer 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.
- *
+ *
* The analyzer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
- *
+ *
*/
#include "analyzer.h"
@@ -214,9 +214,17 @@
if(sig==SIGILL)sigill=1;
}
-int main(int argc, char **argv){
+void blockslice_callback(void){
int fi;
+ /* select the full-block slice size: ~10fps */
+ for(fi=0;fi<inputs;fi++){
+ blockslice[fi]=rate[fi]/10;
+ while(blockslice[fi]>blocksize/2)blockslice[fi]/=2;
+ }
+}
+int main(int argc, char **argv){
+
version=strstr(VERSION,"version.h");
if(version){
char *versionend=strchr(version,' ');
@@ -294,14 +302,8 @@
//signal(SIGINT,handler);
signal(SIGSEGV,handler);
- if(input_load())exit(1);
+ if(input_load(blockslice_callback))exit(1);
- /* select the full-block slice size: ~10fps */
- for(fi=0;fi<inputs;fi++){
- blockslice[fi]=rate[fi]/10;
- while(blockslice[fi]>blocksize/2)blockslice[fi]/=2;
- }
-
/* go */
panel_go(argc,argv);
Modified: trunk/spectrum/version.h
===================================================================
--- trunk/spectrum/version.h 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/version.h 2012-06-04 03:26:48 UTC (rev 18353)
@@ -1,2 +1,2 @@
#define VERSION "$Id$ "
-/* DO NOT EDIT: Automated versioning hack [Sun Jun 3 00:12:33 EDT 2012] */
+/* DO NOT EDIT: Automated versioning hack [Sun Jun 3 23:19:05 EDT 2012] */
Modified: trunk/spectrum/wave_panel.c
===================================================================
--- trunk/spectrum/wave_panel.c 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/wave_panel.c 2012-06-04 03:26:48 UTC (rev 18353)
@@ -1,187 +1,146 @@
/*
*
* gtk2 waveform viewer
- *
+ *
* Copyright (C) 2004-2012 Monty
*
* This analyzer 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.
- *
+ *
* The analyzer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
- *
+ *
*/
#include "waveform.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "fisharray.h"
-#include "io.h"
#include "wave_plot.h"
-sig_atomic_t increment_fish=0;
+GtkWidget *twirlimage;
+GdkPixmap *ff[19];
+GdkBitmap *fb[19];
-static struct panel {
- GtkWidget *twirlimage;
- GdkPixmap *ff[19];
- GdkBitmap *fb[19];
+GtkAccelGroup *group;
+GtkWidget *toplevel;
- GtkAccelGroup *group;
- GtkWidget *toplevel;
+guint fishframe_timer;
+int fishframe_init;
+int fishframe;
+GtkWidget *rightbox;
+GtkWidget *plot;
+GtkWidget *run;
+GtkWidget **chbuttons;
+GtkWidget **groupboxes;
+GtkWidget *rangemenu;
- guint fishframe_timer;
- int fishframe_init;
- int fishframe;
+int plot_ch=0;
+int plot_inputs=0;
- GtkWidget *plot;
- GtkWidget *run;
- GtkWidget **chbuttons;
- GtkWidget *rangemenu;
-} p;
-
-float plot_range=0;
int plot_scale=0;
int plot_span=0;
+float plot_range=0;
int plot_rchoice=0;
int plot_schoice=0;
int plot_spanchoice=0;
int plot_interval=0;
int plot_trigger=0;
+int plot_type=0;
int plot_hold=0;
int plot_bold=0;
int plot_sep=0;
+int plot_rate[MAX_FILES] = {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
-int plot_type=0;
-int plot_last_update=0;
-int *active;
+/* first up... the Fucking Fish */
+sig_atomic_t increment_fish=0;
-int overslice[MAX_FILES]= {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
+static int reanimate_fish(void){
+ if(process_active || (fishframe>0 && fishframe<12)){
+ /* continue spinning */
+ if(increment_fish || fishframe>0)fishframe++;
+ if(fishframe==1)increment_fish=0;
+ if(fishframe>=12)fishframe=0;
-static void override_base(GtkWidget *w, int active){
- gtk_widget_modify_base (w, GTK_STATE_NORMAL, &w->style->bg[active?GTK_STATE_ACTIVE:GTK_STATE_NORMAL]);
-}
+ gtk_image_set_from_pixmap(GTK_IMAGE(twirlimage),
+ ff[fishframe],
+ fb[fishframe]);
-static void set_slices(int interval, int span){
-
- /* update interval limited to < 25fps */
- //int temp = (interval < 50000 ? 50000:interval),fi;
-
- int temp=interval,fi;
-
- pthread_mutex_lock(&ioparam_mutex);
- if(temp <= span){
- /* if the fps-limited update interval is shorter than or equal to
- the span, we simply frame limit */
- for(fi=0;fi<inputs;fi++){
- blockslice[fi]=rint(rate[fi]/1000000.*temp);
- overslice[fi]=rint(rate[fi]/1000000.*temp);
- }
- }else{
- /* if the limited update interval is longer than the span, we
- overdraw */
- for(fi=0;fi<inputs;fi++)
- blockslice[fi]=rint(rate[fi]/1000000.*temp);
- for(fi=0;fi<inputs;fi++){
- overslice[fi]=rint(rate[fi]/1000000.*interval);
- }
- }
- pthread_mutex_unlock(&ioparam_mutex);
-}
-
-static void replot(struct panel *p){
- /* update the waveform display; send new data */
- if(!plot_hold){
- pthread_mutex_lock(&feedback_mutex);
- plot_refresh(PLOT(p->plot));
- plot_last_update=feedback_increment;
- pthread_mutex_unlock(&feedback_mutex);
- }
-}
-
-static void shutdown(void){
- gtk_main_quit();
-}
-
-/* gotta have the Fucking Fish */
-static int reanimate_fish(struct panel *p){
- if(process_active || (p->fishframe>0 && p->fishframe<12)){
- /* continue spinning */
- if(increment_fish)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 && !process_active){
+ if(fishframe==0 && !process_active){
/* reschedule to blink */
- p->fishframe_timer=
- g_timeout_add(rand()%1000*30,(GSourceFunc)reanimate_fish,p);
+ fishframe_timer=
+ g_timeout_add(rand()%1000*30,(GSourceFunc)reanimate_fish,NULL);
return FALSE;
}
}else{
- p->fishframe++;
- if(p->fishframe<=1)p->fishframe=12;
- if(p->fishframe>=19)p->fishframe=0;
+ fishframe++;
+ if(fishframe<=1)fishframe=12;
+ if(fishframe>=19)fishframe=0;
- gtk_image_set_from_pixmap(GTK_IMAGE(p->twirlimage),
- p->ff[p->fishframe],
- p->fb[p->fishframe]);
+ gtk_image_set_from_pixmap(GTK_IMAGE(twirlimage),
+ ff[fishframe],
+ fb[fishframe]);
- if(p->fishframe==12){
+ if(fishframe==12){
/* reschedule to animate */
- p->fishframe_timer=
- g_timeout_add(10,(GSourceFunc)reanimate_fish,p);
+ fishframe_timer=
+ g_timeout_add(10,(GSourceFunc)reanimate_fish,NULL);
return FALSE;
}
- if(p->fishframe==0){
+ if(fishframe==0){
/* reschedule to blink */
- p->fishframe_timer=
- g_timeout_add(rand()%1000*30,(GSourceFunc)reanimate_fish,p);
+ fishframe_timer=
+ g_timeout_add(rand()%1000*30,(GSourceFunc)reanimate_fish,NULL);
return FALSE;
}
}
return TRUE;
}
-static void animate_fish(struct panel *p){
- if(p->fishframe_init){
- g_source_remove(p->fishframe_timer);
- p->fishframe_timer=
- g_timeout_add(80,(GSourceFunc)reanimate_fish,p);
+static void animate_fish(void){
+ if(fishframe_init){
+ g_source_remove(fishframe_timer);
+ fishframe_timer=
+ g_timeout_add(80,(GSourceFunc)reanimate_fish,NULL);
}else{
- p->fishframe_init=1;
- p->fishframe_timer=
- g_timeout_add(rand()%1000*30,(GSourceFunc)reanimate_fish,p);
+ fishframe_init=1;
+ fishframe_timer=
+ g_timeout_add(rand()%1000*30,(GSourceFunc)reanimate_fish,NULL);
}
}
-static void set_fg(GtkWidget *c, gpointer in){
- GdkColor *rgb = in;
- gtk_widget_modify_fg(c,GTK_STATE_NORMAL,rgb);
- gtk_widget_modify_fg(c,GTK_STATE_ACTIVE,rgb);
- gtk_widget_modify_fg(c,GTK_STATE_PRELIGHT,rgb);
- gtk_widget_modify_fg(c,GTK_STATE_SELECTED,rgb);
+static void set_slices(int interval, int span){
+ int fi;
+ /* update interval limited to < 25fps */
+ //int temp = (interval < 50000 ? 50000:interval),fi;
+ for(fi=0;fi<plot_inputs;fi++)
+ set_blockslice(rint(plot_rate[fi]/1000000.*interval),fi);
+}
- /* buttons usually have internal labels */
- if(GTK_IS_CONTAINER(c))
- gtk_container_forall (GTK_CONTAINER(c),set_fg,in);
+static void override_base(GtkWidget *w, int active){
+ gtk_widget_modify_base
+ (w, GTK_STATE_NORMAL,
+ &w->style->bg[active?GTK_STATE_ACTIVE:GTK_STATE_NORMAL]);
}
+static void chlabels(GtkWidget *widget,gpointer in){
+ replot();
+}
+
static int rangechange_ign=0;
-static void rangechange(GtkWidget *widget,struct panel *p){
+static void rangechange(GtkWidget *widget,gpointer in){
if(!rangechange_ign){
int choice=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
plot_rchoice=choice;
@@ -217,11 +176,11 @@
plot_range=.001;
break;
}
- plot_setting(PLOT(p->plot),plot_range,plot_scale,plot_interval,plot_span,plot_rchoice,plot_schoice,plot_spanchoice,plot_type,NULL,NULL);
+ replot();
}
}
-static void scalechange(GtkWidget *widget,struct panel *p){
+static void scalechange(GtkWidget *widget,gpointer in){
int i;
int choice=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
plot_schoice=choice;
@@ -257,8 +216,8 @@
"0.01",
"0.001"};
for(i=0;i<10;i++){
- gtk_combo_box_remove_text (GTK_COMBO_BOX (p->rangemenu), i);
- gtk_combo_box_insert_text (GTK_COMBO_BOX (p->rangemenu), i, entries[i]);
+ gtk_combo_box_remove_text (GTK_COMBO_BOX (rangemenu), i);
+ gtk_combo_box_insert_text (GTK_COMBO_BOX (rangemenu), i, entries[i]);
}
}else{
@@ -274,17 +233,16 @@
"-40dB",
"-60dB"};
for(i=0;i<10;i++){
- gtk_combo_box_remove_text (GTK_COMBO_BOX (p->rangemenu), i);
- gtk_combo_box_insert_text (GTK_COMBO_BOX (p->rangemenu), i, entries[i]);
+ gtk_combo_box_remove_text (GTK_COMBO_BOX (rangemenu), i);
+ gtk_combo_box_insert_text (GTK_COMBO_BOX (rangemenu), i, entries[i]);
}
}
- gtk_combo_box_set_active(GTK_COMBO_BOX(p->rangemenu),plot_rchoice);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(rangemenu),plot_rchoice);
rangechange_ign=0;
-
- plot_setting(PLOT(p->plot),plot_range,plot_scale,plot_interval,plot_span,plot_rchoice,plot_schoice,plot_spanchoice,plot_type,NULL,NULL);
+ replot();
}
-static void spanchange(GtkWidget *widget,struct panel *p){
+static void spanchange(GtkWidget *widget,gpointer in){
int choice=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
plot_spanchoice=choice;
switch(choice){
@@ -330,12 +288,10 @@
}
set_slices(plot_interval,plot_span);
-
- plot_setting(PLOT(p->plot),plot_range,plot_scale,plot_interval,plot_span,plot_rchoice,plot_schoice,plot_spanchoice,plot_type,blockslice,overslice);
+ replot();
}
-/* intervals that are >= the span and would result in > 25fps are overdrawn */
-static void intervalchange(GtkWidget *widget,struct panel *p){
+static void intervalchange(GtkWidget *widget,gpointer in){
int choice=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
switch(choice){
case 0:
@@ -380,78 +336,175 @@
}
set_slices(plot_interval,plot_span);
-
- plot_setting(PLOT(p->plot),plot_range,plot_scale,plot_interval,plot_span,plot_rchoice,plot_schoice,plot_spanchoice,plot_type,blockslice,overslice);
+ replot();
}
-static void triggerchange(GtkWidget *widget,struct panel *p){
- int choice=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+static void triggerchange(GtkWidget *widget,gpointer in){
+ //int choice=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
/* nothing but free-run supported right now */
}
-static void runchange(GtkWidget *widget,struct panel *p){
+static void runchange(GtkWidget *widget,gpointer in){
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))){
if(!process_active){
pthread_t thread_id;
process_active=1;
process_exit=0;
- animate_fish(p);
+ animate_fish();
pthread_create(&thread_id,NULL,&process_thread,NULL);
}
}else{
process_exit=1;
- while(process_active)sched_yield();
}
}
-static void holdchange(GtkWidget *widget,struct panel *p){
+static void holdchange(GtkWidget *widget,gpointer in){
plot_hold=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
override_base(widget,plot_bold);
- replot(p);
- plot_draw(PLOT(p->plot));
+ replot();
}
-static void boldchange(GtkWidget *widget,struct panel *p){
+static void boldchange(GtkWidget *widget,gpointer in){
plot_bold=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
override_base(widget,plot_bold);
- plot_set_bold(PLOT(p->plot),plot_bold);
+ replot();
}
-static void sepchange(GtkWidget *widget,struct panel *p){
+static void sepchange(GtkWidget *widget,gpointer in){
plot_sep=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
override_base(widget,plot_sep);
- plot_set_sep(PLOT(p->plot),plot_sep);
+ replot();
}
-static void plotchange(GtkWidget *widget,struct panel *p){
+static void plotchange(GtkWidget *widget,gpointer in){
plot_type=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
- plot_setting(PLOT(p->plot),plot_range,plot_scale,plot_interval,plot_span,plot_rchoice,plot_schoice,plot_spanchoice,plot_type,blockslice,overslice);
+ replot();
}
-static void loopchange(GtkWidget *widget,struct panel *p){
+static void loopchange(GtkWidget *widget,gpointer in){
acc_loop=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
}
-static void rewindchange(GtkWidget *widget,struct panel *p){
+static void rewindchange(GtkWidget *widget,gpointer in){
acc_rewind=1;
}
-static void chlabels(GtkWidget *widget,struct panel *p){
- /* scan state, update labels on channel buttons, set sensitivity
- based on grouping and mode */
- int fi,ch,i;
- char buf[80];
+static void create_chbuttons(int *bits, int *rate, int *channels,
+ int *active){
+ int i,fi;
+ int ch=0;
+ char buffer[160];
- for(i=0;i<total_ch;i++)
- active[i]=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p->chbuttons[i]));
+ groupboxes = calloc(plot_inputs,sizeof(*groupboxes));
+ chbuttons = calloc(plot_ch,sizeof(*chbuttons));
+ for(fi=0;fi<plot_inputs;fi++){
+ GtkWidget *al=groupboxes[fi]=gtk_alignment_new(0,0,1,0);
+ GtkWidget *vbox=gtk_vbox_new(0,0);
+ GtkWidget *label;
- plot_set_active(PLOT(p->plot),active);
+ char *lastslash = strrchr(inputname[fi],'/');
+ sprintf(buffer,"%s",(lastslash?lastslash+1:inputname[fi]));
+ label=gtk_label_new(buffer);
+ gtk_widget_set_name(label,"readout");
+ gtk_box_pack_start(GTK_BOX(vbox),label,0,0,0);
+
+ sprintf(buffer,"%dHz %dbit",rate[fi],bits[fi]);
+ label=gtk_label_new(buffer);
+ gtk_widget_set_name(label,"readout");
+ gtk_box_pack_start(GTK_BOX(vbox),label,0,0,0);
+
+ for(i=ch;i<ch+channels[fi];i++){
+ GtkWidget *button=chbuttons[i]=gtk_toggle_button_new();
+
+ sprintf(buffer,"channel %d", i-ch);
+ gtk_button_set_label(GTK_BUTTON(button),buffer);
+
+ if(active)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),active[i]);
+ else
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),1);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (chlabels), NULL);
+ gtk_box_pack_start(GTK_BOX(vbox),button,0,0,0);
+ }
+
+ gtk_container_add(GTK_CONTAINER(al),vbox);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(al),0,10,0,0);
+ gtk_box_pack_start(GTK_BOX(rightbox),al,0,0,0);
+
+ ch+=channels[fi];
+ gtk_widget_show_all(al);
+ }
}
+static void destroy_chbuttons(){
+ int fi;
+
+ for(fi=0;fi<plot_inputs;fi++){
+ gtk_widget_destroy(groupboxes[fi]);
+ groupboxes[fi]=NULL;
+ }
+
+ free(groupboxes);
+ free(chbuttons);
+ groupboxes=NULL;
+ chbuttons=NULL;
+}
+
+static plotparams pp;
+void replot(void){
+ int i,process[plot_ch],old_ch=plot_ch;
+
+ for(i=0;i<plot_ch;i++)
+ process[i]=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chbuttons[i]));
+
+ /* update the waveform display; send new data */
+ fetchdata *f = process_fetch (plot_span, plot_scale, plot_range, process);
+ if(!f)return;
+
+ /* the fetched data may indicate the underlying file data has
+ changed... */
+ if(f->reload){
+
+ /* update group block slices */
+ memcpy(plot_rate,f->rate,sizeof(plot_rate));
+ set_slices(plot_interval,plot_span);
+
+ /* remove old group labels and channel buttons */
+ destroy_chbuttons();
+
+ plot_ch=f->total_ch;
+ plot_inputs=f->groups;
+
+ /* create new buttons/labels */
+ {
+ int newprocess[f->total_ch];
+ for(i=0;i<plot_ch && i<old_ch;i++)
+ newprocess[i]=process[i];
+ for(;i<plot_ch;i++)
+ newprocess[i]=0;
+ create_chbuttons(f->bits,f->rate,f->channels,newprocess);
+ }
+ }
+
+ pp.bold=plot_bold;
+ pp.trace_sep=plot_sep;
+ pp.span=plot_span;
+ pp.plotchoice=plot_type;
+ pp.spanchoice=plot_spanchoice;
+ pp.rangechoice=plot_rchoice;
+ pp.scalechoice=plot_schoice;
+
+ plot_draw(PLOT(plot),f,&pp);
+}
+
+static void shutdown(void){
+ gtk_main_quit();
+}
+
static gint watch_keyboard(GtkWidget *grab_widget,
GdkEventKey *event,
- gpointer func_data){
- struct panel *p=(struct panel *)func_data;
+ gpointer in){
if(event->type == GDK_KEY_PRESS){
if(event->state == GDK_CONTROL_MASK){
@@ -463,7 +516,7 @@
}
extern char *version;
-void panel_create(struct panel *panel){
+void panel_create(void){
int i;
GdkWindow *root=gdk_get_default_root_window();
@@ -471,21 +524,20 @@
GtkWidget *rightframe=gtk_frame_new (NULL);
GtkWidget *righttopbox=gtk_vbox_new(0,0);
GtkWidget *rightframebox=gtk_event_box_new();
- GtkWidget *rightbox=gtk_vbox_new(0,0);
GtkWidget *lefttable=gtk_table_new(4,2,0);
GtkWidget *plot_control_al;
GtkWidget *wbold;
- active = calloc(total_ch,sizeof(*active));
+ rightbox=gtk_vbox_new(0,0);
- panel->toplevel=gtk_window_new (GTK_WINDOW_TOPLEVEL);
- panel->group = gtk_accel_group_new ();
- gtk_window_add_accel_group (GTK_WINDOW(panel->toplevel), panel->group);
- gtk_window_set_title(GTK_WINDOW(panel->toplevel),(const gchar *)"Waveform Viewer");
- gtk_window_set_default_size(GTK_WINDOW(panel->toplevel),1024,400);
- //gtk_widget_set_size_request(GTK_WIDGET(panel->toplevel),1024,400);
- gtk_container_add (GTK_CONTAINER (panel->toplevel), topbox);
- g_signal_connect (G_OBJECT (panel->toplevel), "delete_event",
+ toplevel=gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ group = gtk_accel_group_new ();
+ gtk_window_add_accel_group (GTK_WINDOW(toplevel), group);
+ gtk_window_set_title(GTK_WINDOW(toplevel),(const gchar *)"Waveform Viewer");
+ gtk_window_set_default_size(GTK_WINDOW(toplevel),1024,400);
+ //gtk_widget_set_size_request(GTK_WIDGET(toplevel),1024,400);
+ gtk_container_add (GTK_CONTAINER (toplevel), topbox);
+ g_signal_connect (G_OBJECT (toplevel), "delete_event",
G_CALLBACK (shutdown), NULL);
gtk_widget_set_name(topbox,"panel");
@@ -497,8 +549,10 @@
{
GtkWidget *al=plot_control_al=gtk_alignment_new(0,0,0,0);
GtkWidget *box=gtk_hbox_new(0,6);
- GtkWidget *hold_display=gtk_check_button_new_with_mnemonic("_hold display");
- GtkWidget *trace_sep=gtk_check_button_new_with_mnemonic("trace _separation");
+ GtkWidget *hold_display=
+ gtk_check_button_new_with_mnemonic("_hold display");
+ GtkWidget *trace_sep=
+ gtk_check_button_new_with_mnemonic("trace _separation");
wbold=gtk_check_button_new_with_mnemonic("_bold");
gtk_table_attach(GTK_TABLE (lefttable), al,0,1,1,2,GTK_FILL,GTK_FILL,0,0);
gtk_container_add(GTK_CONTAINER (al),box);
@@ -509,18 +563,20 @@
gtk_widget_set_name(hold_display,"top-control");
gtk_widget_set_name(wbold,"top-control");
gtk_widget_set_name(trace_sep,"top-control");
- g_signal_connect (G_OBJECT (hold_display), "clicked", G_CALLBACK (holdchange), panel);
- gtk_widget_add_accelerator (hold_display, "activate", panel->group, GDK_h, 0, 0);
- g_signal_connect (G_OBJECT (wbold), "clicked", G_CALLBACK (boldchange), panel);
- gtk_widget_add_accelerator (wbold, "activate", panel->group, GDK_b, 0, 0);
- g_signal_connect (G_OBJECT (trace_sep), "clicked", G_CALLBACK (sepchange), panel);
- gtk_widget_add_accelerator (trace_sep, "activate", panel->group, GDK_s, 0, 0);
-
+ g_signal_connect (G_OBJECT (hold_display), "clicked",
+ G_CALLBACK (holdchange), NULL);
+ gtk_widget_add_accelerator (hold_display, "activate", group, GDK_h, 0, 0);
+ g_signal_connect (G_OBJECT (wbold), "clicked",
+ G_CALLBACK (boldchange), NULL);
+ gtk_widget_add_accelerator (wbold, "activate", group, GDK_b, 0, 0);
+ g_signal_connect (G_OBJECT (trace_sep), "clicked",
+ G_CALLBACK (sepchange), NULL);
+ gtk_widget_add_accelerator (trace_sep, "activate", group, GDK_s, 0, 0);
}
/* add the waveform plot box */
- panel->plot=plot_new(blocksize,inputs,channels,rate);
- gtk_table_attach_defaults (GTK_TABLE (lefttable), panel->plot,0,1,2,3);
+ plot=plot_new();
+ gtk_table_attach_defaults (GTK_TABLE (lefttable), plot,0,1,2,3);
gtk_table_set_row_spacing (GTK_TABLE (lefttable), 2, 4);
gtk_table_set_col_spacing (GTK_TABLE (lefttable), 0, 2);
@@ -533,7 +589,6 @@
gtk_container_add (GTK_CONTAINER (rightframebox),rightframe);
gtk_container_add (GTK_CONTAINER (rightframe), rightbox);
-
/* the Fucking Fish */
{
GtkWidget *toptable = gtk_table_new(2,1,0);
@@ -550,10 +605,10 @@
w/=19;
for(i=0;i<19;i++){
- panel->ff[i]=gdk_pixmap_new(tp,w,h,-1);
- panel->fb[i]=gdk_pixmap_new(tb,w,h,-1);
- gdk_draw_drawable(panel->ff[i],cgc,tp,i*w,0,0,0,w,h);
- gdk_draw_drawable(panel->fb[i],bgc,tb,i*w,0,0,0,w,h);
+ ff[i]=gdk_pixmap_new(tp,w,h,-1);
+ fb[i]=gdk_pixmap_new(tb,w,h,-1);
+ gdk_draw_drawable(ff[i],cgc,tp,i*w,0,0,0,w,h);
+ gdk_draw_drawable(fb[i],bgc,tb,i*w,0,0,0,w,h);
}
g_object_unref(cgc);
@@ -561,69 +616,24 @@
g_object_unref(tp);
g_object_unref(tb);
- panel->twirlimage=gtk_image_new_from_pixmap(panel->ff[0],panel->fb[0]);
+ twirlimage=gtk_image_new_from_pixmap(ff[0],fb[0]);
gtk_container_set_border_width (GTK_CONTAINER (toptable), 1);
gtk_box_pack_start(GTK_BOX(righttopbox),toptable,0,0,0);
gtk_container_add (GTK_CONTAINER (sepbox), topsep);
- gtk_container_add(GTK_CONTAINER(fishbox),panel->twirlimage);
+ gtk_container_add(GTK_CONTAINER(fishbox),twirlimage);
gtk_table_attach_defaults (GTK_TABLE (toptable), fishbox,0,1,0,1);
gtk_table_attach_defaults (GTK_TABLE (toptable), sepbox,0,1,0,1);
gtk_table_set_row_spacing (GTK_TABLE (toptable), 0, 6);
}
- /* rate */
- /* channels */
- /* bits */
- {
- int fi;
- int ch=0;
- char buffer[160];
- GtkWidget *label;
+ create_chbuttons(bits,rate,channels,NULL);
- panel->chbuttons = calloc(total_ch,sizeof(*panel->chbuttons));
- for(fi=0;fi<inputs;fi++){
- GtkWidget *al=gtk_alignment_new(0,0,1,0);
- GtkWidget *vbox=gtk_vbox_new(0,0);
-
- char *lastslash = strrchr(inputname[fi],'/');
- sprintf(buffer,"%s",(lastslash?lastslash+1:inputname[fi]));
- label=gtk_label_new(buffer);
- gtk_widget_set_name(label,"readout");
- gtk_box_pack_start(GTK_BOX(vbox),label,0,0,0);
-
- sprintf(buffer,"%dHz %dbit",rate[fi],bits[fi]);
- label=gtk_label_new(buffer);
- gtk_widget_set_name(label,"readout");
- gtk_box_pack_start(GTK_BOX(vbox),label,0,0,0);
-
- for(i=ch;i<ch+channels[fi];i++){
- GtkWidget *button=panel->chbuttons[i]=gtk_toggle_button_new();
-
- sprintf(buffer,"channel %d", i-ch);
- gtk_button_set_label(GTK_BUTTON(button),buffer);
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),1);
- g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (chlabels), panel);
- gtk_box_pack_start(GTK_BOX(vbox),button,0,0,0);
- }
-
- gtk_container_add(GTK_CONTAINER(al),vbox);
- gtk_alignment_set_padding(GTK_ALIGNMENT(al),0,10,0,0);
- gtk_box_pack_start(GTK_BOX(rightbox),al,0,0,0);
-
- ch+=channels[fi];
-
- }
- chlabels(NULL,panel);
- }
-
/* add the action buttons */
GtkWidget *bbox=gtk_vbox_new(0,0);
- /* add the action buttons */
- /* range */
{
+ /* range */
GtkWidget *box=gtk_hbox_new(1,1);
GtkWidget *menu=gtk_combo_box_new_text();
@@ -631,15 +641,15 @@
for(i=0;i<10;i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), entries[i]);
g_signal_connect (G_OBJECT (menu), "changed",
- G_CALLBACK (rangechange), panel);
- panel->rangemenu = menu;
+ G_CALLBACK (rangechange), NULL);
+ rangemenu = menu;
GtkWidget *menu2=gtk_combo_box_new_text();
char *entries2[]={"linear","-65dB","-96dB","-120dB","-160dB"};
for(i=0;i<5;i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu2), entries2[i]);
g_signal_connect (G_OBJECT (menu2), "changed",
- G_CALLBACK (scalechange), panel);
+ G_CALLBACK (scalechange), NULL);
gtk_box_pack_start(GTK_BOX(box),menu2,1,1,0);
gtk_box_pack_start(GTK_BOX(box),menu,1,1,0);
@@ -664,7 +674,7 @@
for(i=0;i<13;i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), entries[i]);
g_signal_connect (G_OBJECT (menu), "changed",
- G_CALLBACK (spanchange), panel);
+ G_CALLBACK (spanchange), NULL);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu),0);
@@ -683,7 +693,7 @@
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), entries[i]);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu),0);
g_signal_connect (G_OBJECT (menu), "changed",
- G_CALLBACK (triggerchange), panel);
+ G_CALLBACK (triggerchange), NULL);
/* interval */
@@ -697,7 +707,7 @@
for(i=0;i<13;i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu2), entries2[i]);
g_signal_connect (G_OBJECT (menu2), "changed",
- G_CALLBACK (intervalchange), panel);
+ G_CALLBACK (intervalchange), NULL);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu2),3);
@@ -716,7 +726,7 @@
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), entries[i]);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu),0);
g_signal_connect (G_OBJECT (menu), "changed",
- G_CALLBACK (plotchange), panel);
+ G_CALLBACK (plotchange), NULL);
gtk_box_pack_start(GTK_BOX(bbox),menu,0,0,0);
}
@@ -728,11 +738,12 @@
/* run/pause */
{
GtkWidget *button=gtk_toggle_button_new_with_mnemonic("_run");
- gtk_widget_add_accelerator (button, "activate", panel->group, GDK_space, 0, 0);
- gtk_widget_add_accelerator (button, "activate", panel->group, GDK_r, 0, 0);
- g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (runchange), panel);
+ gtk_widget_add_accelerator (button, "activate", group, GDK_space, 0, 0);
+ gtk_widget_add_accelerator (button, "activate", group, GDK_r, 0, 0);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (runchange), NULL);
gtk_box_pack_start(GTK_BOX(bbox),button,0,0,0);
- panel->run=button;
+ run=button;
}
/* loop */
@@ -740,33 +751,34 @@
{
GtkWidget *box=gtk_hbox_new(1,1);
GtkWidget *button=gtk_toggle_button_new_with_mnemonic("_loop");
- gtk_widget_add_accelerator (button, "activate", panel->group, GDK_l, 0, 0);
- g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (loopchange), panel);
+ gtk_widget_add_accelerator (button, "activate", group, GDK_l, 0, 0);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (loopchange), NULL);
gtk_widget_set_sensitive(button,global_seekable);
gtk_box_pack_start(GTK_BOX(box),button,1,1,0);
button=gtk_button_new_with_mnemonic("re_wind");
- gtk_widget_add_accelerator (button, "activate", panel->group, GDK_w, 0, 0);
- g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (rewindchange), panel);
+ gtk_widget_add_accelerator (button, "activate", group, GDK_w, 0, 0);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (rewindchange), NULL);
gtk_widget_set_sensitive(button,global_seekable);
gtk_box_pack_start(GTK_BOX(box),button,1,1,0);
gtk_box_pack_start(GTK_BOX(bbox),box,0,0,0);
}
gtk_box_pack_end(GTK_BOX(rightbox),bbox,0,0,0);
- gtk_widget_show_all(panel->toplevel);
+ gtk_widget_show_all(toplevel);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wbold),plot_bold);
- gtk_key_snooper_install(watch_keyboard,panel);
+ gtk_key_snooper_install(watch_keyboard,NULL);
- gtk_alignment_set_padding(GTK_ALIGNMENT(plot_control_al),0,0,plot_get_left_pad(PLOT(panel->plot)),0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(plot_control_al),0,0,plot_get_left_pad(PLOT(plot)),0);
}
static gboolean async_event_handle(GIOChannel *channel,
GIOCondition condition,
gpointer data){
- struct panel *panel=data;
char buf[1];
/* read all pending */
@@ -775,24 +787,20 @@
increment_fish=1;
/* check playback status and update the run button if needed */
- if(process_active && panel->run &&
- !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->run)))
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->run),1);
- if(!process_active && panel->run &&
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->run)))
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->run),0);
+ if(process_active && run &&
+ !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(run)))
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(run),1);
+ if(!process_active && run &&
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(run)))
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(run),0);
/* update the waveform display; send new data */
- pthread_mutex_lock(&feedback_mutex);
- if(plot_last_update!=feedback_increment){
- pthread_mutex_unlock(&feedback_mutex);
- replot(panel);
- plot_draw(PLOT(panel->plot));
+ if(!plot_hold)replot();
- while (gtk_events_pending())
- gtk_main_iteration();
- }else
- pthread_mutex_unlock(&feedback_mutex);
+ /* if we're near CPU limit, service the rest of Gtk over next async
+ update request */
+ while (gtk_events_pending())
+ gtk_main_iteration();
return TRUE;
}
@@ -810,7 +818,6 @@
void panel_go(int argc,char *argv[]){
char *homedir=getenv("HOME");
int found=0;
- memset(&p,0,sizeof(p));
found|=look_for_gtkrc(STR(ETCDIR)"/waveform-gtkrc");
{
@@ -837,16 +844,20 @@
if(!found){
- fprintf(stderr,"Could not find the waveform-gtkrc configuration file normally\n"
+ fprintf(stderr,
+ "Could not find the waveform-gtkrc configuration file normally\n"
"installed in one of the following places:\n"
"\t./waveform-gtkrc\n"
"\t$(SPECTRUM_RCDIR)/waveform-gtkrc\n"
"\t~/.spectrum/waveform-gtkrc\n\t"
STR(ETCDIR)"/wavegform-gtkrc\n"
- "This configuration file is used to tune the color, font and other detail aspects\n"
- "of the user interface. Although the viewer will work without it, the UI\n"
- "appearence will likely make the application harder to use due to missing visual\n"
+ "This configuration file is used to tune the color, "
+ "font and other detail aspects\n"
+ "of the user interface. Although the viewer will "
+ "work without it, the UI\n"
+ "appearence will likely make the application harder to "
+ "use due to missing visual\n"
"cues.\n");
}
@@ -862,32 +873,25 @@
gtk_rc_add_default_file("waveform-gtkrc");
gtk_init (&argc, &argv);
- panel_create(&p);
- animate_fish(&p);
+ plot_ch = total_ch; /* true now, won't necessarily be true later */
+ plot_inputs = inputs; /* true now, won't necessarily be true later */
+ memcpy(plot_rate,rate,sizeof(plot_rate));
+ panel_create();
+ animate_fish();
+
/* set up watching the event pipe */
{
GIOChannel *channel = g_io_channel_unix_new (eventpipe[0]);
- guint id;
-
g_io_channel_set_encoding (channel, NULL, NULL);
g_io_channel_set_buffered (channel, FALSE);
g_io_channel_set_close_on_unref (channel, TRUE);
-
- id = g_io_add_watch (channel, G_IO_IN, async_event_handle, &p);
-
+ g_io_add_watch (channel, G_IO_IN, async_event_handle, NULL);
g_io_channel_unref (channel);
+ }
- }
-
/* we want to be running by default */
- {
- pthread_t thread_id;
- animate_fish(&p);
- process_active=1;
- pthread_create(&thread_id,NULL,&process_thread,NULL);
- }
-
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(run),TRUE);
gtk_main ();
}
Modified: trunk/spectrum/wave_plot.c
===================================================================
--- trunk/spectrum/wave_plot.c 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/wave_plot.c 2012-06-04 03:26:48 UTC (rev 18353)
@@ -1,24 +1,24 @@
/*
*
* gtk2 waveform viewer
- *
+ *
* Copyright (C) 2004-2012 Monty
*
* This analyzer 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.
- *
+ *
* The analyzer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
- *
+ *
*/
#include "waveform.h"
@@ -31,20 +31,23 @@
static GtkDrawingAreaClass *parent_class = NULL;
-static void compute_metadata(GtkWidget *widget){
- Plot *p=PLOT(widget);
+static void compute_xgrid(Plot *p){
+ GtkWidget *widget=GTK_WIDGET(p);
int width=widget->allocation.width-p->padx;
- int i,j;
+ if(p->width != width){
+ int i,j;
- p->xgrids=11;
- p->xtics=30;
+ p->xgrids=11;
+ p->xtics=30;
- for(i=0;i<p->xgrids;i++)
- p->xgrid[i]=rint(i/(float)(p->xgrids-1) * (width-1))+p->padx;
+ for(i=0;i<p->xgrids;i++)
+ p->xgrid[i]=rintf(i/(float)(p->xgrids-1) * (width-1))+p->padx;
- for(i=0,j=0;i<p->xtics;i++,j++){
- if(j%4==0)j++;
- p->xtic[i]=rint(j/(float)((p->xgrids-1)*4) * (width-1))+p->padx;
+ for(i=0,j=0;i<p->xtics;i++,j++){
+ if(j%4==0)j++;
+ p->xtic[i]=rintf(j/(float)((p->xgrids-1)*4) * (width-1))+p->padx;
+ }
+ p->width=width;
}
}
@@ -88,38 +91,48 @@
rgb.blue=0xe000;
break;
}
-
+
return rgb;
}
-static void draw(GtkWidget *widget){
+void plot_draw(Plot *p, fetchdata *f, plotparams *pp){
int i;
- Plot *p=PLOT(widget);
+ GtkWidget *widget=GTK_WIDGET(p);
+ GtkWidget *parent=gtk_widget_get_parent(widget);
int height=widget->allocation.height;
int width=widget->allocation.width;
- GtkWidget *parent=gtk_widget_get_parent(widget);
int padx = p->padx;
int num_active=0;
+ float center = (height-p->pady)/2.;
+ if(!GDK_IS_DRAWABLE(p->backing))return;
+ if(!pp)return;
+ if(!f)return;
+
/* how many channels actually active right now? Need to know if
trace sep is enabled */
- if(p->trace_sep){
+ if(pp->trace_sep){
int fi,ch=0;
- for(fi=0;fi<p->groups;fi++){
- for(i=ch;i<ch+p->ch[fi];i++)
- if(p->ch_active[i])
+ for(fi=0;fi<f->groups;fi++){
+ for(i=ch;i<ch+f->channels[fi];i++)
+ if(f->active[i])
num_active++;
- ch+=p->ch[fi];
+ ch+=f->channels[fi];
}
}
if(!p->drawgc){
- GdkGCValues values;
p->drawgc=gdk_gc_new(p->backing);
p->twogc=gdk_gc_new(p->backing);
gdk_gc_copy(p->drawgc,widget->style->black_gc);
gdk_gc_copy(p->twogc,widget->style->black_gc);
- gdk_gc_set_line_attributes(p->twogc,p->bold+1,GDK_LINE_SOLID,
+ }
+
+ if(pp->plotchoice==2){
+ gdk_gc_set_line_attributes(p->twogc,pp->bold+1,GDK_LINE_SOLID,
+ GDK_CAP_BUTT,GDK_JOIN_MITER);
+ }else{
+ gdk_gc_set_line_attributes(p->twogc,pp->bold+1,GDK_LINE_SOLID,
GDK_CAP_PROJECTING,GDK_JOIN_MITER);
}
@@ -133,6 +146,8 @@
gdk_draw_rectangle(p->backing,gc,1,padx,0,width-padx,height-p->pady);
}
+ compute_xgrid(p);
+
/* draw the light x grid */
{
int i;
@@ -147,7 +162,7 @@
gdk_draw_line(p->backing,p->drawgc,p->xtic[i],0,p->xtic[i],height-p->pady-1);
}
- PangoLayout **proper=p->x_layout[p->spanchoice];
+ PangoLayout **proper=p->x_layout[pp->spanchoice];
for(i=0;i<p->xgrids;i++){
int px,py;
@@ -159,11 +174,9 @@
proper[i]);
}
-
/* draw the light y grid */
{
GdkColor rgb={0,0,0,0};
- int center = (height-p->pady)/2;
rgb.red=0xc000;
rgb.green=0xff00;
@@ -171,8 +184,8 @@
gdk_gc_set_rgb_fg_color(p->drawgc,&rgb);
for(i=1;i<8;i++){
- int y1=rint(center + center*i/9);
- int y2=rint(center - center*i/9);
+ int y1=rintf(center + center*i/9.);
+ int y2=rintf(center - center*i/9.);
gdk_draw_line(p->backing,p->drawgc,padx,y1,width,y1);
gdk_draw_line(p->backing,p->drawgc,padx,y2,width,y2);
}
@@ -181,11 +194,10 @@
/* dark y grid */
{
GdkColor rgb={0,0,0,0};
- int center = (height-p->pady)/2;
int px,py;
- gdk_draw_line(p->backing,p->drawgc,padx,center-1,width,center-1);
- gdk_draw_line(p->backing,p->drawgc,padx,center+1,width,center+1);
+ gdk_draw_line(p->backing,p->drawgc,padx,rintf(center-1),width,rintf(center-1));
+ gdk_draw_line(p->backing,p->drawgc,padx,rintf(center+1),width,rintf(center+1));
rgb.red=0x0000;
rgb.green=0xc000;
@@ -193,12 +205,12 @@
gdk_gc_set_rgb_fg_color(p->drawgc,&rgb);
for(i=-8;i<9;i+=4){
- int y=rint(center + center*i/9);
+ int y=rintf(center + center*i/9.);
gdk_draw_line(p->backing,p->drawgc,padx,y,width,y);
- pango_layout_get_pixel_size(p->y_layout[p->rchoice][p->schoice][i/4+2],
- &px,&py);
+ pango_layout_get_pixel_size
+ (p->y_layout[pp->rangechoice][pp->scalechoice][i/4+2],&px,&py);
if(i<=0){
rgb.red=0x0000;
@@ -214,7 +226,7 @@
gdk_draw_layout (p->backing,
p->drawgc,
padx-px-2, y-py/2,
- p->y_layout[p->rchoice][p->schoice][i/4+2]);
+ p->y_layout[pp->rangechoice][pp->scalechoice][i/4+2]);
rgb.red=0x0000;
rgb.green=0xc000;
@@ -235,226 +247,204 @@
gdk_gc_set_rgb_fg_color(p->drawgc,&rgb);
for(i=0;i<p->xgrids;i++)
- gdk_draw_line(p->backing,p->drawgc,p->xgrid[i],0,p->xgrid[i],height-p->pady-1);
+ gdk_draw_line(p->backing,p->drawgc,p->xgrid[i],0,p->xgrid[i],
+ height-p->pady-1);
}
- /* zero line */
+ /* center/zero line */
{
- int center = (height-p->pady)/2;
- gdk_draw_line(p->backing,widget->style->black_gc,padx,center,width,center);
+ gdk_draw_line(p->backing,widget->style->black_gc,padx,
+ rintf(center),width,rintf(center));
}
/* draw actual data */
- if(p->ydata){
- int ch=0,fi,i,j,k;
+ if(f->data){
+ int ch=0,ach=0,fi,i,k;
const GdkRectangle clip = {p->padx,0,width-p->padx,height-p->pady};
- const GdkRectangle noclip = {0,0,width,height};
GdkColor rgb;
- int y_sep=0;
- int cp;
gdk_gc_set_clip_rectangle (p->twogc, &clip);
- if(p->trace_sep && num_active>1){
- y_sep = (height-p->pady)/18*16/num_active;
- cp = y_sep/2+(height-p->pady)/18;
- }else{
- cp = (height-p->pady)/2;
- }
+ for(fi=0;fi<f->groups;fi++){
+ int spann = ceil(f->rate[fi]/1000000.*pp->span)+1;
- for(fi=0;fi<p->groups;fi++){
- int copies = (int)ceil(p->blockslice[fi]/p->overslice[fi]);
- int spann = ceil(p->rate[fi]/1000000.*p->span)+1;
+ for(i=ch;i<ch+f->channels[fi];i++){
- for(i=ch;i<ch+p->ch[fi];i++){
- if(p->ch_active[i]){
- int offset=0;
+ if(f->active[i]){
+ float *data=f->data[i];
+ int wp=width-p->padx;
+ float spani = 1000000./f->span/f->rate[fi]*wp;
+ int hp=height-p->pady;
+ float ym=hp*-8./18;
+ float cp = pp->trace_sep ?
+ (height-p->pady)*(16*i+8)/(float)(18*num_active)+
+ (height-p->pady)/18. : center;
+
+ ach++;
rgb = chcolor(i);
gdk_gc_set_rgb_fg_color(p->twogc,&rgb);
- for(j=0;j<copies;j++){
- float *data=p->ydata[i]+offset;
- int wp=width-p->padx;
- float spani = 1000000./p->span/p->rate[fi]*wp;
- int hp=height-p->pady;
- float ym=hp*-8./18;
+ switch(pp->plotchoice){
+ case 0: /* zero-hold */
+ {
+ int x0=-1;
+ float yH=NAN,yL=NAN,y0=NAN;
+ int acc=0;
+ for(k=0;k<spann;k++){
+ int x1 = rintf(k*spani);
+ float y1 = data[k]*ym;
- switch(p->type){
- case 0: /* zero-hold */
- {
- int x0=-1;
- float yH=NAN,yL=NAN,y0=NAN;
- int acc=0;
- for(k=0;k<spann;k++){
- int x1 = rint(k*spani);
- float y1 = data[k]*ym;
-
- if(x1>x0){
- if(acc>1){
- if(!isnan(yL)&&!isnan(yH))
- gdk_draw_line(p->backing,p->twogc,
- x0+padx,rint(yL)+cp,x0+padx,
- rint(yH)+cp);
- }
- if(!isnan(y0)){
+ if(x1>x0){
+ if(acc>1){
+ if(!isnan(yL)&&!isnan(yH))
gdk_draw_line(p->backing,p->twogc,
- x0+padx,rint(y0)+cp,x1+padx,rint(y0)+cp);
-
- if(!isnan(y1))
- gdk_draw_line(p->backing,p->twogc,
- x1+padx,rint(y0)+cp,x1+padx,rint(y1)+cp);
- }
-
- acc=1;
- yH=yL=y1;
- }else{
- acc++;
- if(!isnan(y1)){
- if(y1<yL || isnan(yL))yL=y1;
- if(y1>yH || isnan(yH))yH=y1;
- }
+ x0+padx,rintf(yL+cp),x0+padx,
+ rintf(yH+cp));
}
- x0=x1;
- y0=y1;
- }
- {
- int x1 = rint(k*spani);
+ if(!isnan(y0)){
+ gdk_draw_line(p->backing,p->twogc,
+ x0+padx,rintf(y0+cp),x1+padx,rintf(y0+cp));
- if(x1<=x0 || acc>1){
- if(!isnan(yL)&&!isnan(yH))
+ if(!isnan(y1))
gdk_draw_line(p->backing,p->twogc,
- x0+padx,rint(yL)+cp,x0+padx,rint(yH)+cp);
+ x1+padx,rintf(y0+cp),x1+padx,rintf(y1+cp));
}
+
+ acc=1;
+ yH=yL=y1;
+ }else{
+ acc++;
+ if(!isnan(y1)){
+ if(y1<yL || isnan(yL))yL=y1;
+ if(y1>yH || isnan(yH))yH=y1;
+ }
}
+ x0=x1;
+ y0=y1;
}
- break;
- case 1: /* linear interpolation */
{
- int x0=-1;
- float yH=NAN,yL=NAN,y0=NAN;
- int acc=0;
- for(k=0;k<spann;k++){
- int x1 = rint(k*spani);
- float y1 = data[k]*ym;
+ int x1 = rintf(k*spani);
- if(x1>x0){
- if(acc>1){
- if(!isnan(yL) && !isnan(yH))
- gdk_draw_line(p->backing,p->twogc,
- x0+padx,rint(yL)+cp,x0+padx,
- rint(yH)+cp);
- }
- if(!isnan(y0) && !isnan(y1)){
- gdk_draw_line(p->backing,p->twogc,
- x0+padx,rint(y0)+cp,x1+padx,rint(y1)+cp);
- }
-
- acc=1;
- yH=yL=y1;
- }else{
- acc++;
- if(!isnan(y1)){
- if(y1<yL || isnan(yL))yL=y1;
- if(y1>yH || isnan(yH))yH=y1;
- }
- }
- x0=x1;
- y0=y1;
+ if(x1<=x0 || acc>1){
+ if(!isnan(yL)&&!isnan(yH))
+ gdk_draw_line(p->backing,p->twogc,
+ x0+padx,rintf(yL+cp),x0+padx,rintf(yH+cp));
}
- {
- int x1 = rint(k*spani);
+ }
+ }
+ break;
+ case 1: /* linear interpolation (first-order hold) */
+ {
+ int x0=-1;
+ float yH=NAN,yL=NAN,y0=NAN;
+ int acc=0;
+ for(k=0;k<spann;k++){
+ int x1 = rintf(k*spani);
+ float y1 = data[k]*ym;
- if(x1<=x0 || acc>1){
+ if(x1>x0){
+ if(acc>1){
if(!isnan(yL) && !isnan(yH))
gdk_draw_line(p->backing,p->twogc,
- x0+padx,rint(yL)+cp,x0+padx,rint(yH)+cp);
+ x0+padx,rintf(yL+cp),x0+padx,
+ rintf(yH+cp));
}
+ if(!isnan(y0) && !isnan(y1)){
+ gdk_draw_line(p->backing,p->twogc,
+ x0+padx,rintf(y0+cp),x1+padx,rintf(y1+cp));
+ }
+
+ acc=1;
+ yH=yL=y1;
+ }else{
+ acc++;
+ if(!isnan(y1)){
+ if(y1<yL || isnan(yL))yL=y1;
+ if(y1>yH || isnan(yH))yH=y1;
+ }
}
+ x0=x1;
+ y0=y1;
}
- break;
- case 2: /* lollipop */
{
- int x0=-1;
- float yH=NAN,yL=NAN;
- int acc=0;
+ int x1 = rintf(k*spani);
- rgb.red=0x8000;
- rgb.green=0x8000;
- rgb.blue=0x8000;
- gdk_gc_set_rgb_fg_color(p->twogc,&rgb);
+ if(x1<=x0 || acc>1){
+ if(!isnan(yL) && !isnan(yH))
+ gdk_draw_line(p->backing,p->twogc,
+ x0+padx,rintf(yL+cp),x0+padx,rintf(yH+cp));
+ }
+ }
+ }
+ break;
+ case 2: /* lollipop */
+ {
+ int x0=-1;
+ float yH=NAN,yL=NAN;
- for(k=0;k<spann;k++){
- int x1 = rint(k*spani);
- float y1 = data[k]*ym;
+ rgb.red=0x8000;
+ rgb.green=0x8000;
+ rgb.blue=0x8000;
+ gdk_gc_set_rgb_fg_color(p->twogc,&rgb);
- if(x1>x0){
- if(!isnan(yL) || !isnan(yH)){
- if(isnan(yL) || yL>0)yL=0;
- if(isnan(yH) || yH<0)yH=0;
- gdk_draw_line(p->backing,p->twogc,
- x0+padx,rint(yL)+cp,x0+padx,
- rint(yH)+cp);
- }
- yH=yL=y1;
- }else{
- if(!isnan(y1)){
- if(y1<yL || isnan(yL))yL=y1;
- if(y1>yH || isnan(yH))yH=y1;
- }
- }
- x0=x1;
- }
- {
- int x1 = rint(k*spani);
+ for(k=0;k<spann;k++){
+ int x1 = rintf(k*spani);
+ float y1 = data[k]*ym;
+
+ if(x1>x0){
if(!isnan(yL) || !isnan(yH)){
if(isnan(yL) || yL>0)yL=0;
if(isnan(yH) || yH<0)yH=0;
gdk_draw_line(p->backing,p->twogc,
- x0+padx,rint(yL)+cp,x0+padx,
- rint(yH)+cp);
+ x0+padx,rintf(yL+cp),x0+padx,
+ rintf(yH+cp));
}
+ yH=yL=y1;
+ }else{
+ if(!isnan(y1)){
+ if(y1<yL || isnan(yL))yL=y1;
+ if(y1>yH || isnan(yH))yH=y1;
+ }
}
+ x0=x1;
+ }
+ {
+ if(!isnan(yL) || !isnan(yH)){
+ if(isnan(yL) || yL>0)yL=0;
+ if(isnan(yH) || yH<0)yH=0;
+ gdk_draw_line(p->backing,p->twogc,
+ x0+padx,rintf(yL+cp),x0+padx,
+ rintf(yH+cp));
+ }
+ }
- rgb = chcolor(i);
- gdk_gc_set_rgb_fg_color(p->twogc,&rgb);
+ rgb = chcolor(i);
+ gdk_gc_set_rgb_fg_color(p->twogc,&rgb);
- for(k=0;k<spann;k++){
- int x = rint(k*spani);
- float y = data[k]*ym;
- if(!isnan(y)){
- gdk_draw_arc(p->backing,p->twogc,
- 0,x+padx-5,rint(y)+cp-5,
- 9,9,0,23040);
- }
+ for(k=0;k<spann;k++){
+ int x = rintf(k*spani);
+ float y = data[k]*ym;
+ if(!isnan(y)){
+ gdk_draw_arc(p->backing,p->twogc,
+ 0,x+padx-5,rintf(y+cp-5),
+ 9,9,0,23040);
}
}
- break;
}
-
- offset+=spann;
+ break;
}
- cp+=y_sep;
}
}
- ch+=p->ch[fi];
+ ch+=f->channels[fi];
}
- //gdk_gc_set_clip_rectangle (p->drawgc, &noclip);
}
-}
-static void draw_and_expose(GtkWidget *widget){
- Plot *p=PLOT(widget);
- if(!GDK_IS_DRAWABLE(p->backing))return;
- draw(widget);
- if(!GTK_WIDGET_DRAWABLE(widget))return;
- if(!GDK_IS_DRAWABLE(widget->window))return;
gdk_draw_drawable(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- p->backing,
- 0, 0,
- 0, 0,
- widget->allocation.width,
- widget->allocation.height);
+ widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ p->backing,
+ 0, 0,
+ 0, 0,
+ width, height);
}
static gboolean expose( GtkWidget *widget, GdkEventExpose *event ){
@@ -473,7 +463,7 @@
Plot *p=PLOT(widget);
requisition->width = 400;
requisition->height = 200;
- int axisy=0,axisx=0,pady=0,padx=0,phax=0,px,py,i;
+ int axisy=0,axisx=0,pady=0,padx=0,px,py,i;
/* find max X layout */
{
@@ -506,12 +496,10 @@
if(requisition->height<axisy+pady)requisition->height=axisy+pady;
p->padx=padx;
p->pady=pady;
- p->phax=phax;
}
static gboolean configure(GtkWidget *widget, GdkEventConfigure *event){
Plot *p=PLOT(widget);
-
if (p->backing)
g_object_unref(p->backing);
@@ -520,13 +508,8 @@
widget->allocation.height,
-1);
- p->ydata=NULL;
p->configured=1;
-
- compute_metadata(widget);
- plot_refresh(p);
- draw_and_expose(widget);
-
+ replot();
return TRUE;
}
@@ -557,28 +540,19 @@
(GInstanceInitFunc) plot_init,
0
};
-
- m_type = g_type_register_static (GTK_TYPE_DRAWING_AREA, "Plot", &m_info, 0);
+
+ m_type = g_type_register_static (GTK_TYPE_DRAWING_AREA, "Plot",
+ &m_info, 0);
}
return m_type;
}
-GtkWidget* plot_new (int size, int groups, int *channels, int *rate){
+GtkWidget* plot_new (void){
GtkWidget *ret= GTK_WIDGET (g_object_new (plot_get_type (), NULL));
Plot *p=PLOT(ret);
- int g,i,j;
- int ch=0;
- p->groups = groups;
- for(g=0;g<groups;g++)
- ch+=channels[g];
+ int i,j;
- p->total_ch = ch;
-
- p->ch=channels;
- p->rate=rate;
- p->size=size;
-
/* generate all the text layouts we'll need */
/* linear X scale */
{
@@ -648,104 +622,9 @@
}
}
- p->ch_active=calloc(ch,sizeof(*p->ch_active));
-
- p->autoscale=1;
-
- plot_clear(p);
return ret;
}
-void plot_refresh (Plot *p){
- float ymax,pmax,pmin;
- int width=GTK_WIDGET(p)->allocation.width-p->padx;
- int height=GTK_WIDGET(p)->allocation.height-p->pady;
- float **data;
- float *floor;
-
- if(!p->configured)return;
-
- data = process_fetch(p->blockslice, p->overslice, p->span,p->scale,p->range);
- p->ydata=data;
-}
-
-void plot_clear (Plot *p){
- GtkWidget *widget=GTK_WIDGET(p);
- int width=GTK_WIDGET(p)->allocation.width-p->padx;
- int i,j;
-
- if(p->ydata)
- for(i=0;i<p->total_ch;i++)
- for(j=0;j<p->size;j++)
- p->ydata[i][j]=NAN;
- draw_and_expose(widget);
-}
-
-float **plot_get (Plot *p){
- return(p->ydata);
-}
-
-void plot_setting (Plot *p, float range, int scale, int interval, int span, int rangechoice, int scalechoice, int spanchoice,int type,
- int *blockslice, int *overslice){
- GtkWidget *widget=GTK_WIDGET(p);
- p->range=range;
- p->scale=scale;
- p->span=span;
- p->interval=interval;
- p->rchoice=rangechoice;
- p->schoice=scalechoice;
- p->spanchoice=spanchoice;
- p->type=type;
-
- if(blockslice){
- if(!p->blockslice)
- p->blockslice=calloc(p->groups,sizeof(*p->blockslice));
- memcpy(p->blockslice, blockslice, p->groups*sizeof(*p->blockslice));
- }
- if(overslice){
- if(!p->overslice)
- p->overslice=calloc(p->groups,sizeof(*p->overslice));
- memcpy(p->overslice, overslice, p->groups*sizeof(*p->blockslice));
- }
-
- compute_metadata(widget);
- plot_refresh(p);
- draw_and_expose(widget);
-}
-
-void plot_draw (Plot *p){
- GtkWidget *widget=GTK_WIDGET(p);
- draw_and_expose(widget);
-}
-
-void plot_set_active(Plot *p, int *a){
- GtkWidget *widget=GTK_WIDGET(p);
- memcpy(p->ch_active,a,p->total_ch*sizeof(*a));
- plot_refresh(p);
- draw_and_expose(widget);
-}
-
-void plot_set_autoscale(Plot *p, int a){
- GtkWidget *widget=GTK_WIDGET(p);
- p->autoscale=a;
- plot_refresh(p);
- draw_and_expose(widget);
-}
-
-void plot_set_bold(Plot *p, int b){
- GtkWidget *widget=GTK_WIDGET(p);
- p->bold=b;
- gdk_gc_set_line_attributes(p->twogc,p->bold+1,GDK_LINE_SOLID,
- GDK_CAP_PROJECTING,GDK_JOIN_MITER);
- draw_and_expose(widget);
-}
-
-void plot_set_sep(Plot *p, int b){
- GtkWidget *widget=GTK_WIDGET(p);
- p->trace_sep=b;
- draw_and_expose(widget);
-}
-
int plot_get_left_pad (Plot *m){
return m->padx;
}
Modified: trunk/spectrum/wave_plot.h
===================================================================
--- trunk/spectrum/wave_plot.h 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/wave_plot.h 2012-06-04 03:26:48 UTC (rev 18353)
@@ -1,24 +1,24 @@
/*
*
* gtk2 waveform viewer
- *
+ *
* Copyright (C) 2004-2012 Monty
*
* This analyzer 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.
- *
+ *
* The analyzer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
- *
+ *
*/
#ifndef __PLOT_H__
@@ -27,7 +27,37 @@
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
+#include "io.h"
+typedef struct {
+ int bits[MAX_FILES];
+ int channels[MAX_FILES];
+ int rate[MAX_FILES];
+ int groups;
+ int total_ch;
+ int maxrate;
+ int reload;
+
+ int span;
+ int scale;
+ int range;
+
+ float **data;
+ int *active;
+ int increment;
+} fetchdata;
+
+typedef struct {
+ int bold;
+ int trace_sep;
+ int span;
+ int plotchoice;
+ int spanchoice;
+ int rangechoice;
+ int scalechoice;
+} plotparams;
+
+
G_BEGIN_DECLS
#define PLOT_TYPE (plot_get_type ())
@@ -40,8 +70,7 @@
typedef struct _PlotClass PlotClass;
struct _Plot{
-
- GtkDrawingArea canvas;
+ GtkDrawingArea canvas;
GdkPixmap *backing;
GdkGC *drawgc;
GdkGC *twogc;
@@ -50,29 +79,10 @@
PangoLayout ****y_layout;
int configured;
- float **ydata;
- int size;
- int groups;
- int *ch;
- int *ch_active;
- int total_ch;
-
- float range;
int scale;
- int interval;
- int span;
- int type;
+ int width;
- int rchoice;
- int schoice;
- int spanchoice;
-
- int *blockslice;
- int *overslice;
-
- int *rate;
-
int xgrid[20];
int xgrids;
int xtic[200];
@@ -84,12 +94,7 @@
int ytics;
float padx;
- float phax;
float pady;
-
- int bold;
- int autoscale;
- int trace_sep;
};
struct _PlotClass{
@@ -99,23 +104,12 @@
};
GType plot_get_type (void);
-GtkWidget* plot_new (int n, int inputs, int *channels, int *rate);
-void plot_refresh (Plot *m);
-void plot_setting (Plot *p, float range, int scale, int interval, int span,
- int rangechoice, int scalechoice, int spanchoice,
- int type, int *blockslice, int *overslice);
-void plot_draw (Plot *m);
-void plot_clear (Plot *m);
-int plot_width (Plot *m);
-float** plot_get (Plot *m);
-void plot_set_active (Plot *m, int *);
-void plot_set_autoscale (Plot *m, int);
-void plot_set_bold (Plot *m, int);
-void plot_set_sep (Plot *m, int);
+GtkWidget* plot_new (void);
+void plot_draw (Plot *m, fetchdata *f, plotparams *pp);
int plot_get_left_pad (Plot *m);
GdkColor chcolor(int ch);
-
+extern void replot(void);
G_END_DECLS
#endif
Modified: trunk/spectrum/wave_process.c
===================================================================
--- trunk/spectrum/wave_process.c 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/wave_process.c 2012-06-04 03:26:48 UTC (rev 18353)
@@ -1,57 +1,45 @@
/*
*
* gtk2 waveform viewer
- *
+ *
* Copyright (C) 2004-2012 Monty
*
* This analyzer 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.
- *
+ *
* The analyzer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
- *
+ *
*/
#include "waveform.h"
#include "io.h"
-pthread_mutex_t feedback_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-int feedback_increment=0;
-float **buffercopies;
-float **plot_data=0;
+static pthread_mutex_t feedback_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+static int feedback_increment=0;
sig_atomic_t process_active=0;
sig_atomic_t process_exit=0;
-sig_atomic_t acc_clear=0;
sig_atomic_t acc_rewind=0;
sig_atomic_t acc_loop=0;
+static int metareload = 0;
+
static void init_process(void){
- int i;
- if(plot_data==NULL){
- plot_data=calloc(total_ch,sizeof(*plot_data));
- buffercopies=calloc(total_ch,sizeof(*buffercopies));
- for(i=0;i<total_ch;i++){
- plot_data[i]=calloc(blocksize,sizeof(**plot_data));
- buffercopies[i]=calloc(blocksize,sizeof(**buffercopies));
- }
- }
}
/* return 0 on EOF, 1 otherwise */
static int process(){
- int fi,ch,i;
-
if(acc_rewind)
rewind_files();
acc_rewind=0;
@@ -59,50 +47,110 @@
if(input_read(acc_loop,1))
return 0;
- pthread_mutex_lock(&feedback_mutex);
- ch=0;
- for(fi=0;fi<inputs;fi++){
- for(i=ch;i<ch+channels[fi];i++)
- memcpy(buffercopies[i],blockbuffer[i],blocksize*sizeof(**buffercopies));
- ch+=channels[fi];
- }
- pthread_mutex_unlock(&feedback_mutex);
-
feedback_increment++;
write(eventpipe[1],"",1);
return 1;
}
void *process_thread(void *dummy){
+ pthread_mutex_lock(&feedback_mutex);
init_process();
- while(!process_exit && process());
+ pthread_mutex_unlock(&feedback_mutex);
+
+ while(1){
+ while(!process_exit && process());
+ pthread_mutex_lock(&feedback_mutex);
+ if(!process_exit && pipe_reload()){
+ /* ah, at least one input was a pipe */
+ init_process();
+ metareload=1;
+ pthread_mutex_unlock(&feedback_mutex);
+ write(eventpipe[1],"",1);
+ }else{
+ pthread_mutex_unlock(&feedback_mutex);
+ break;
+ }
+ }
process_active=0;
write(eventpipe[1],"",1);
return NULL;
}
-float **process_fetch(int *blockslice,int *overslice,int span,
- int scale,float range){
- int fi,i,j,k,ch;
+static fetchdata fetch_ret;
+fetchdata *process_fetch(int span, int scale, float range,
+ int *process_in){
+ int fi,i,k,ch;
+ int process[total_ch];
+ pthread_mutex_lock(&feedback_mutex);
+ if(!blockbuffer){
+ pthread_mutex_unlock(&feedback_mutex);
+ return NULL;
+ }
+
init_process();
- if(!blockslice || !overslice || !blockbuffer)return NULL;
+ if(metareload){
+ if(fetch_ret.data){
+ for(i=0;i<fetch_ret.total_ch;i++)
+ if(fetch_ret.data[i])free(fetch_ret.data[i]);
+ free(fetch_ret.data);
+ fetch_ret.data=NULL;
+ }
+ if(fetch_ret.active){
+ free(fetch_ret.active);
+ fetch_ret.active=NULL;
+ }
+ }
+
+ if(!fetch_ret.data){
+ fetch_ret.data = calloc(total_ch,sizeof(*fetch_ret.data));
+ for(i=0;i<total_ch;i++)
+ fetch_ret.data[i]=calloc(blocksize,sizeof(**fetch_ret.data));
+ }
+
+ if(!fetch_ret.active)
+ fetch_ret.active = calloc(total_ch,sizeof(*fetch_ret.active));
+
+ /* the passed in process array doesn't necesarily match the
+ current channel structure. Copy group by group. */
+ {
+ int ch_now=0;
+ int ch_in=0;
+ for(i=0;i<inputs;i++){
+ int ci;
+ for(ci=0;ci<channels[i] && ci<fetch_ret.channels[i];ci++)
+ process[ch_now+ci] = process_in[ch_in+ci];
+ for(;ci<channels[i];ci++)
+ process[ch_now+ci] = 0;
+ ch_now+=channels[i];
+ ch_in+=fetch_ret.channels[i];
+ }
+ memcpy(fetch_ret.active,process,total_ch*sizeof(*process));
+ }
+
+ fetch_ret.groups=inputs;
+ fetch_ret.scale=scale;
+ fetch_ret.span=span;
+ fetch_ret.range=range;
+ fetch_ret.total_ch=total_ch;
+ fetch_ret.increment=feedback_increment;
+
+ memcpy(fetch_ret.bits,bits,sizeof(fetch_ret.bits));
+ memcpy(fetch_ret.channels,channels,sizeof(fetch_ret.channels));
+ memcpy(fetch_ret.rate,rate,sizeof(fetch_ret.rate));
+
+ fetch_ret.reload=metareload;
+ metareload=0;
+
/* by channel */
ch=0;
for(fi=0;fi<inputs;fi++){
- /* When the blockslice and overslice are equal, the data
- buffer contains only one copy of the span. When the
- overslice is much smaller than the blockslice, we have
- ceil(blockslice/overslice) back-to-back spans */
-
- int copies = (int)ceil(blockslice[fi]/overslice[fi]);
int spann = ceil(rate[fi]/1000000.*span)+1;
-
for(i=ch;i<ch+channels[fi];i++){
- int offset=blocksize-spann;
- float *plotdatap=plot_data[i];
- for(j=0;j<copies;j++){
+ if(process[i]){
+ int offset=blocksize-spann;
+ float *plotdatap=fetch_ret.data[i];
float *data=blockbuffer[i]+offset;
if(scale){
float drange=todB(range)-scale;
@@ -120,11 +168,11 @@
for(k=0;k<spann;k++)
*(plotdatap++)=(data[k]/range);
}
- offset-=overslice[fi];
}
}
ch+=channels[fi];
}
- return plot_data;
+ pthread_mutex_unlock(&feedback_mutex);
+ return &fetch_ret;
}
Modified: trunk/spectrum/waveform.c
===================================================================
--- trunk/spectrum/waveform.c 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/waveform.c 2012-06-04 03:26:48 UTC (rev 18353)
@@ -1,24 +1,24 @@
/*
*
* gtk2 waveform viewer
- *
+ *
* Copyright (C) 2004-2012 Monty
*
* This analyzer 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.
- *
+ *
* The analyzer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
- *
+ *
*/
#include "waveform.h"
@@ -202,6 +202,15 @@
if(sig==SIGILL)sigill=1;
}
+void blocksize_callback(void){
+ int fi;
+ /* set block size equal to maximum input rate + epsilon*/
+ /* (maximum display width: 1s, maximum update interval 1s) */
+ blocksize=0;
+ for(fi=0;fi<inputs;fi++)
+ if(rate[fi]>blocksize)blocksize=rate[fi]+16;
+}
+
int main(int argc, char **argv){
int fi;
@@ -237,7 +246,7 @@
feenableexcept(FE_INEXACT);
feenableexcept(FE_UNDERFLOW);
feenableexcept(FE_OVERFLOW);
-#endif
+#endif
/* Linux Altivec support has a very annoying problem; by default,
math on denormalized floats will simply crash the program. FFTW3
@@ -250,12 +259,12 @@
#ifdef __PPC
#include <altivec.h>
signal(SIGILL,sigill_handler);
-
+
#if (defined __GNUC__) && (__GNUC__ == 3) && ! (defined __APPLE_CC__)
- __vector unsigned short noTrap =
+ __vector unsigned short noTrap =
(__vector unsigned short){0,0,0,0,0,0,0x1,0};
#else
- vector unsigned short noTrap =
+ vector unsigned short noTrap =
(vector unsigned short)(0,0,0,0,0,0,0x1,0);
#endif
@@ -267,7 +276,7 @@
if(pipe(eventpipe)){
fprintf(stderr,"Unable to open event pipe:\n"
" %s\n",strerror(errno));
-
+
exit(1);
}
@@ -275,21 +284,15 @@
if(fcntl(eventpipe[0], F_SETFL, O_NONBLOCK)){
fprintf(stderr,"Unable to set O_NONBLOCK on event pipe:\n"
" %s\n",strerror(errno));
-
+
exit(1);
}
//signal(SIGINT,handler);
signal(SIGSEGV,handler);
- if(input_load())exit(1);
+ if(input_load(blocksize_callback))exit(1);
- /* set block size equal to maximum input rate */
- /* (maximum display width: 1s, maximum update interval 1s) */
- blocksize=0;
- for(fi=0;fi<inputs;fi++)
- if(rate[fi]>blocksize)blocksize=rate[fi];
-
/* begin with a display width of 1s */
/* begin with an update interval (blockslice) of 100ms */
for(fi=0;fi<inputs;fi++)
Modified: trunk/spectrum/waveform.h
===================================================================
--- trunk/spectrum/waveform.h 2012-06-03 04:13:23 UTC (rev 18352)
+++ trunk/spectrum/waveform.h 2012-06-04 03:26:48 UTC (rev 18353)
@@ -1,24 +1,24 @@
/*
*
* gtk2 spectrum analyzer
- *
+ *
* Copyright (C) 2004-2012 Monty
*
* This analyzer 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.
- *
+ *
* The analyzer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
- *
+ *
*/
#ifndef _WAVEFORM_H_
@@ -39,6 +39,7 @@
#include <math.h>
#include <signal.h>
#include <fcntl.h>
+#include "wave_plot.h"
extern int blocksize;
@@ -78,14 +79,11 @@
extern void panel_go(int argc,char *argv[]);
extern void *process_thread(void *dummy);
-extern float **process_fetch(int *, int *, int, int, float);
+extern fetchdata *process_fetch(int span, int scale, float range,
+ int *process);
-extern pthread_mutex_t feedback_mutex;
-extern int feedback_increment;
-extern float **feedback_instant;
extern sig_atomic_t acc_rewind;
extern sig_atomic_t acc_loop;
-
extern sig_atomic_t process_active;
extern sig_atomic_t process_exit;
More information about the commits
mailing list