[xiph-commits] r18405 - trunk/spectrum
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Thu Jun 14 00:44:56 PDT 2012
Author: xiphmont
Date: 2012-06-14 00:44:56 -0700 (Thu, 14 Jun 2012)
New Revision: 18405
Modified:
trunk/spectrum/Makefile
trunk/spectrum/analyzer.h
trunk/spectrum/io.c
trunk/spectrum/io.h
trunk/spectrum/spec_panel.c
trunk/spectrum/spec_plot.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.h
trunk/spectrum/wave_process.c
trunk/spectrum/waveform.c
Log:
Numerous fixes from previous round of conversions; several serious
plot errors in spectrum
Another round of locking changes to allow serialized access to the
blockbuffers without blocking UI thread on IO reads
Modified: trunk/spectrum/Makefile
===================================================================
--- trunk/spectrum/Makefile 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/Makefile 2012-06-14 07:44:56 UTC (rev 18405)
@@ -68,7 +68,7 @@
./touch-version
$(LD) $(WAVEFORM_OBJ) -o waveform $(LIBS) $(CFLAGS) `pkg-config --libs gtk+-2.0` -lpthread -lm
-target: spectrum waveform
+target: waveform spectrum
install: target
$(INSTALL) -d -m 0755 $(BINDIR)
Modified: trunk/spectrum/analyzer.h
===================================================================
--- trunk/spectrum/analyzer.h 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/analyzer.h 2012-06-14 07:44:56 UTC (rev 18405)
@@ -69,6 +69,42 @@
#endif
+/* atan2f approximation, max error: < +/- .0004 degrees */
+/* return value is degrees, not radians */
+#define cA 0.43157974f
+#define cB 0.67848403f
+#define cC 0.08595542f
+#define cD 57.2957795f
+#define cE 90.f
+
+static inline float fast_atan2f_deg(float y, float x) {
+ float x2 = x*x;
+ float y2 = y*y;
+ if(x2<y2){
+ return -cD * x*y*(y2 + cA*x2) / ((y2 + cB*x2) * (y2 + cC*x2)) +
+ copysignf(cE,y);
+ }else{
+ return cD * x*y*(x2 + cA*y2) / ((x2 + cB*y2) * (x2 + cC*y2)) +
+ copysignf(cE,y) - copysignf(cE,x*y);
+ }
+}
+
+
+static inline float invSqrt(float x){
+ float xhalf = 0.5f*x;
+ union
+ {
+ float x;
+ int i;
+ } u;
+ u.x = x;
+ u.i = 0x5f375a86f - (u.i >> 1);
+ u.x *= 1.5f - xhalf * u.x * u.x;
+ u.x *= 1.5f - xhalf * u.x * u.x;
+ return u.x;
+}
+
+
#ifndef max
#define max(x,y) ((x)>(y)?(x):(y))
#endif
@@ -85,13 +121,17 @@
extern void process_dump(int mode);
extern void rundata_clear();
extern fetchdata *process_fetch(int scale, int mode, int link,
- int *process, int height, int width);
+ float bw, int bwmode,
+ int *process, Plot *plot);
extern sig_atomic_t acc_rewind;
extern sig_atomic_t acc_loop;
extern sig_atomic_t process_active;
extern sig_atomic_t process_exit;
+extern char *bw_entries[];
+extern float bw_values[];
+
#define LINKS 5
#define LINK_INDEPENDENT 0
#define LINK_SUMMED 1
Modified: trunk/spectrum/io.c
===================================================================
--- trunk/spectrum/io.c 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/io.c 2012-06-14 07:44:56 UTC (rev 18405)
@@ -26,26 +26,37 @@
#include <unistd.h>
#include "io.h"
-static pthread_mutex_t ioparam_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+#define readsize 512
+
+/* locks access to file metadata and blockbuffer data */
+pthread_mutex_t blockbuffer_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};
int rate[MAX_FILES] = {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
int signedp[MAX_FILES] = {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
+int total_ch=0;
+
+float **blockbuffer=0;
+int blockbufferfill[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
+int blockbuffernew[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
+/* end list of locked buffers */
+
int bits_force[MAX_FILES] = {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
int bigendian_force[MAX_FILES] = {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
int channels_force[MAX_FILES] = {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
int rate_force[MAX_FILES] = {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
int signed_force[MAX_FILES] = {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
-extern int blocksize;
-int blockslice[MAX_FILES]= {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1};
+extern int blocksize; /* set only at startup */
+sig_atomic_t blockslice_frac;
+static int blockslice_count=0;
+static int blockslice_started=0;
+static int blockslices[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
-float **blockbuffer=0;
-int blockbufferfill[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
-
-static unsigned char readbuffer[MAX_FILES][readbuffersize];
+static unsigned char readbuffer[MAX_FILES][readsize];
static int readbufferfill[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
static int readbufferptr[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
@@ -56,10 +67,7 @@
int seekable[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
int isapipe[MAX_FILES]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
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,14 +139,13 @@
}
}
-/* used to load or reload an input */
-static int load_one_input(int fi){
+static void close_one_input(int fi){
int i;
-
if(f[fi]){
fclose(f[fi]);
f[fi]=NULL;
blockbufferfill[fi]=0;
+ blockbuffernew[fi]=0;
readbufferptr[fi]=0;
readbufferfill[fi]=0;
if(blockbuffer){
@@ -148,8 +155,14 @@
blockbuffer=NULL;
}
total_ch -= channels[fi];
+ channels[fi]=0;
}
+}
+/* used to load or reload an input */
+static int load_one_input(int fi){
+ int i;
+
if(!strcmp(inputname[fi],"/dev/stdin") && fi==0){
int newfd=dup(STDIN_FILENO);
f[fi]=fdopen(newfd,"rb");
@@ -176,7 +189,10 @@
global_seekable=1;
}
- fread(headerid,1,12,f[fi]);
+ if(fread(headerid,1,12,f[fi])==0 && feof(f[fi])){
+ close_one_input(fi);
+ return 1;
+ }
if(!strncmp(headerid,"RIFF",4) && !strncmp(headerid+8,"WAVE",4)){
unsigned int chunklen;
@@ -402,15 +418,14 @@
return 0;
}
-int input_load(void (*load_callback)(void)){
+int input_load(void){
int fi;
if(inputs==0){
/* look at stdin... is it a file, pipe, tty...? */
if(isatty(STDIN_FILENO)){
fprintf(stderr,
- "Spectrum requires either an input file on the command line\n"
- "or stream data piped|redirected to stdin. spectrum -h will\n"
- "give more details.\n");
+ "Input file on the command line or stream data\n"
+ "piped|redirected to stdin. -h will give more details.\n");
return 1;
}
inputname[0]=strdup("/dev/stdin");
@@ -427,34 +442,27 @@
exit(1);
}
- if(load_callback){
- lc = load_callback;
- load_callback();
- }
-
return 0;
}
-/* attempts to reopen any inputs that are pipes. Does not check for
- EOF, ignores non-fifo inputs. Returns nonzero if any pipes
- reopened. */
+/* attempts to reopen a pipe at EOF. Ignores non-fifo inputs.
+ Returns nonzero if a pipe reopens, 0 otherwise */
int pipe_reload(){
int fi;
int ret=0;
for(fi=0;fi<inputs;fi++)
- if(!seekable[fi] && isapipe[fi] && !load_one_input(fi)){
- fprintf(stderr,"reloading....\n");
+ if(!seekable[fi] && f[fi]==NULL && isapipe[fi] &&
+ !load_one_input(fi)){
+ fprintf(stderr,"reopened input %d\n",fi);
ret=1;
}
-
- if(ret && lc)lc();
return ret;
}
/* Convert new data from readbuffer into the blockbuffers until the
- blockbuffer is full */
-static void LBEconvert(int *localslice){
+ blockbuffer is full or the readbuffer is empty */
+static void LBEconvert(void){
float scale=1./2147483648.;
int ch=0,fi;
@@ -467,7 +475,7 @@
channels[fi]/bytes*channels[fi]*bytes+readbufferptr[fi];
int bfill = blockbufferfill[fi];
- int tosize = blocksize + localslice[fi];
+ int tosize = blocksize + blockslices[fi];
int rptr = readbufferptr[fi];
unsigned char *rbuf = readbuffer[fi];
@@ -558,30 +566,51 @@
}
}
-void set_blockslice(int slice, int fi){
- pthread_mutex_lock(&ioparam_mutex);
- blockslice[fi]=slice;
- pthread_mutex_unlock(&ioparam_mutex);
+/* blockslices are tracked/locked over a one second period */
+static void blockslice_advance(void){
+ int fi;
+ int frac = blockslice_frac;
+ int count;
+
+ /* strict determinism is nice */
+ if(!blockslice_started)blockslice_count=0;
+
+ count = blockslice_count + (1000000/frac);
+ for(fi=0;fi<inputs;fi++){
+ int prevsample = rint((double)rate[fi]*blockslice_count/1000000);
+ int thissample = rint((double)rate[fi]*count/1000000);
+
+ blockslices[fi] = thissample - prevsample;
+ if(blockslices[fi]<1)blockslices[fi]=1;
+ if(blockslices[fi]>blocksize)blockslices[fi]=blocksize;
+
+ }
+
+ blockslice_count = count;
+ if(blockslice_count>=1000000)blockslice_count-=1000000;
+ blockslice_started = 1;
}
-/* when we return, the blockbuffer is full or we're at EOF */
-/* EOF cases:
- loop set: return EOF if all seekable streams have hit EOF
- loop unset: return EOF if all streams have hit EOF
- pad individual EOF streams out with zeroes until global EOF is hit */
+/* input_read returns:
+ -1 if a pipe hits EOF
+ 0 if all at EOF and nothing to process
+ 1 if new data ready to process
+ All access to blockbuffer[0,blocksize) is locked, as is the
+ blockbuffer metadata
+*/
+
int input_read(int loop, int partialok){
- int i,j,fi,ch=0;
- int eof=1;
+ int i,j,fi,ch;
int notdone=1;
+ int ret=0;
int rewound[total_ch];
- int localslice[MAX_FILES];
memset(rewound,0,sizeof(rewound));
- pthread_mutex_lock(&ioparam_mutex);
- memcpy(localslice,blockslice,sizeof(localslice));
- pthread_mutex_unlock(&ioparam_mutex);
+ /* also handles initialization */
+ if(!blockslice_started)blockslice_advance();
+ pthread_mutex_lock(&blockbuffer_mutex);
if(blockbuffer==0){
blockbuffer=malloc(total_ch*sizeof(*blockbuffer));
@@ -592,7 +621,8 @@
/* if this is first frame, do we allow a single slice or fully
fill the buffer */
- for(fi=0;fi<inputs;fi++){
+ ch=0;
+ for(fi=0,ch=0;fi<inputs;fi++){
if(blockbufferfill[fi]==0){
for(i=ch;i<channels[fi]+ch;i++)
for(j=0;j<blocksize;j++)
@@ -600,107 +630,111 @@
if(partialok){
blockbufferfill[fi]=blocksize;
}else{
- blockbufferfill[fi]=localslice[fi];
+ blockbufferfill[fi]=blockslices[fi];
}
}
}
+ pthread_mutex_unlock(&blockbuffer_mutex);
- /* try to fill buffer to blocksize+slice before performing shift */
-
while(notdone){
notdone=0;
- /* if there's data left to be pulled out of a readbuffer, do that */
- LBEconvert(localslice);
+ /* if there's data left to be pulled out of a readbuffer, do
+ that */
+ /* not locked: new data is either fed into a yet-inactive
+ buffer or to the end (past the blocksize) of an active
+ buffer */
+ LBEconvert();
- ch=0;
+ /* fill readbuffers */
for(fi=0;fi<inputs;fi++){
- if(blockbufferfill[fi]!=blocksize+localslice[fi]){
- /* shift the read buffer before fill if there's a fractional
- frame in it */
- if(readbufferptr[fi]!=readbufferfill[fi] && readbufferptr[fi]>0){
- memmove(readbuffer[fi],readbuffer[fi]+readbufferptr[fi],
- (readbufferfill[fi]-readbufferptr[fi])*sizeof(**readbuffer));
- readbufferfill[fi]-=readbufferptr[fi];
- readbufferptr[fi]=0;
- }else{
- readbufferfill[fi]=0;
- readbufferptr[fi]=0;
- }
+ /* drain what's already been processed before fill */
+ if(readbufferptr[fi]>0){
+ if(readbufferptr[fi]!=readbufferfill[fi]){
+ /* partial frame; shift it */
+ memmove(readbuffer[fi],readbuffer[fi]+readbufferptr[fi],
+ (readbufferfill[fi]-readbufferptr[fi]));
+ readbufferfill[fi]-=readbufferptr[fi];
+ readbufferptr[fi]=0;
+ }else{
+ /* all processed, just empty */
+ readbufferfill[fi]=0;
+ readbufferptr[fi]=0;
+ }
+ }
- /* attempt to top off the readbuffer */
- {
- long actually_readbytes=0,readbytes=readbuffersize-readbufferfill[fi];
+ /* attempt to top off the readbuffer if the given blockbuffer
+ isn't full */
+ if(readbufferfill[fi]<readsize &&
+ blockbufferfill[fi]<blocksize+blockslices[fi]){
+ int readbytes=readsize-readbufferfill[fi];
+ int actually_readbytes =
+ fread(readbuffer[fi]+readbufferfill[fi],1,readbytes,f[fi]);
- if(readbytes>0)
- actually_readbytes=fread(readbuffer[fi]+readbufferfill[fi],1,readbytes,f[fi]);
-
- if(actually_readbytes<=0 && ferror(f[fi])){
- fprintf(stderr,"Input read error from %s: %s\n",
- inputname[fi],strerror(ferror(f[fi])));
- }else if (actually_readbytes==0){
+ if(actually_readbytes<=0 && ferror(f[fi])){
+ fprintf(stderr,"Input read error from %s: %s\n",
+ inputname[fi],strerror(ferror(f[fi])));
+ }else if (actually_readbytes==0){
+ if(isapipe[fi] && !seekable[fi]){
+ /* attempt to reopen a pipe immediately; kick out */
+ close_one_input(fi);
+ return -1;
+ }
+ if(loop && seekable[fi] && (!rewound[fi] || readbufferfill[fi])){
/* real, hard EOF/error in a partially filled block */
- if(!partialok){
- /* partial frame is *not* ok. zero it out. */
- memset(readbuffer[fi],0,readbuffersize);
- bytesleft[fi]=0;
- readbufferfill[fi]=0;
- readbufferptr[fi]=0;
- blockbufferfill[fi]=0;
- }
- if(loop && seekable[fi] && (!rewound[fi] || (partialok && blockbufferfill[fi]))){
- /* rewind this file and continue */
- fseek(f[fi],offset[fi],SEEK_SET);
- if(length[fi]!=-1)
- bytesleft[fi]=length[fi]*channels[fi]*((bits[fi]+7)/8);
- notdone=1;
- rewound[fi]=1;
- }
- }else{
- /* got a read */
- bytesleft[fi]-=actually_readbytes;
- readbufferfill[fi]+=actually_readbytes;
+ /* rewind this file and continue */
+ fseek(f[fi],offset[fi],SEEK_SET);
+ if(length[fi]!=-1)
+ bytesleft[fi]=length[fi]*channels[fi]*((bits[fi]+7)/8);
notdone=1;
- }
- }
- }else{
- eof=0;
+ rewound[fi]=1;
+ }
+ }else{
+ /* got a read */
+ bytesleft[fi]-=actually_readbytes;
+ readbufferfill[fi]+=actually_readbytes;
+ notdone=1;
+ }
}
- ch += channels[fi];
}
}
- /* shift */
+ /* at this point, all buffers are fully topped off or at eof */
+ pthread_mutex_lock(&blockbuffer_mutex);
+
+ /* shift any updated blockbuffers and mark them new */
for(fi=0,ch=0;fi<inputs;fi++){
- if(blockbufferfill[fi]>blocksize){
+ if(blockbufferfill[fi]>=blocksize+(partialok?1:blockslices[fi])){
for(i=ch;i<channels[fi]+ch;i++)
- memmove(blockbuffer[i],blockbuffer[i]+(blockbufferfill[fi]-blocksize),
+ memmove(blockbuffer[i],blockbuffer[i]+
+ (blockbufferfill[fi]-blocksize),
blocksize*sizeof(**blockbuffer));
blockbufferfill[fi]=blocksize;
+ blockbuffernew[fi]=1;
+ ret=1;
}
- for(i=ch;i<channels[fi]+ch;i++)
- for(j=blockbufferfill[fi];j<blocksize;j++)
- blockbuffer[i][j]=NAN;
- ch+=channels[fi];
}
+ blockslice_advance();
+ pthread_mutex_unlock(&blockbuffer_mutex);
- return eof;
+ return ret;
}
int rewind_files(){
int fi;
+
for(fi=0;fi<inputs;fi++){
- if(!seekable[fi])
- return 1;
+ if(seekable[fi]){
+ blockbufferfill[fi]=0;
+ blockbuffernew[fi]=0;
+ readbufferptr[fi]=0;
+ readbufferfill[fi]=0;
+ fseek(f[fi],offset[fi],SEEK_SET);
+ if(length[fi]!=-1)bytesleft[fi]=length[fi]*channels[fi]*((bits[fi]+7)/8);
+ }
}
- for(fi=0;fi<inputs;fi++){
- blockbufferfill[fi]=0;
- readbufferptr[fi]=0;
- readbufferfill[fi]=0;
- fseek(f[fi],offset[fi],SEEK_SET);
- if(length[fi]!=-1)bytesleft[fi]=length[fi]*channels[fi]*((bits[fi]+7)/8);
- }
+ blockslice_started=0;
return 0;
}
Modified: trunk/spectrum/io.h
===================================================================
--- trunk/spectrum/io.h 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/io.h 2012-06-14 07:44:56 UTC (rev 18405)
@@ -44,10 +44,9 @@
#include <fcntl.h>
#define MAX_FILES 16
-#define readbuffersize 512
+extern pthread_mutex_t blockbuffer_mutex;
-extern int input_load(void (*load_callback)(void));
-extern void set_blockslice(int slice, int fi);
+extern int input_load(void);
extern int pipe_reload(void);
extern int input_read(int loop_p, int partial_p);
extern int rewind_files(void);
@@ -70,8 +69,9 @@
extern int seekable[MAX_FILES];
extern int global_seekable;
-extern int blockslice[MAX_FILES];
+extern sig_atomic_t blockslice_frac;
extern int blockbufferfill[MAX_FILES];
+extern int blockbuffernew[MAX_FILES];
extern float **blockbuffer;
#endif
Modified: trunk/spectrum/spec_panel.c
===================================================================
--- trunk/spectrum/spec_panel.c 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/spec_panel.c 2012-06-14 07:44:56 UTC (rev 18405)
@@ -58,7 +58,7 @@
int plot_lock_y=0;
int plot_depth=90;
int plot_noise=0;
-int plot_bw=0;
+int plot_bwchoice=0;
int plot_bwmode=0;
int plot_bold=0;
@@ -192,7 +192,7 @@
pmax+=10;
pmin-=10;
- if(pmax<5)pmax=5;
+ if(pmax<10)pmax=10;
if(pmax>190)pmax=190;
if(pmin>-20)pmin=-20;
if(pmin<-190)pmin=-190;
@@ -505,10 +505,7 @@
static void linkchange(GtkWidget *widget,gpointer in){
plot_link=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
- chlabels(NULL,NULL);
- gtk_alignment_set_padding(GTK_ALIGNMENT(plot_label_al),
- 0,0,0,plot_get_right_pad(PLOT(plot)));
- replot(0,1,0);
+ chlabels(widget,NULL);
}
static void runchange(GtkWidget *widget,gpointer in){
@@ -557,8 +554,8 @@
}
static void bwchange(GtkWidget *widget,gpointer in){
- plot_bw=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
- if(plot_bw==0){
+ plot_bwchoice=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+ if(plot_bwchoice==0){
gtk_widget_set_sensitive(GTK_WIDGET(bwmodebutton),0);
}else{
gtk_widget_set_sensitive(GTK_WIDGET(bwmodebutton),1);
@@ -650,8 +647,11 @@
/* update the spectral display; send new data */
fetchdata *f = process_fetch
(plot_scale, plot_mode, plot_link,
- process, plot_height(PLOT(plot)), plot_width(PLOT(plot)));
+ bw_values[plot_bwchoice],plot_bwmode,
+ process, PLOT(plot));
+ if(!f)return;
+
/* the fetched data may indicate the underlying file data has
changed... */
if(f->reload){
@@ -716,6 +716,7 @@
GdkWindow *root=gdk_get_default_root_window();
GtkWidget *topbox=gtk_hbox_new(0,0);
GtkWidget *rightframe=gtk_frame_new (NULL);
+ GtkWidget *righttopal=gtk_alignment_new(.5,.5,1.,1.);
GtkWidget *righttopbox=gtk_vbox_new(0,0);
GtkWidget *rightframebox=gtk_event_box_new();
GtkWidget *lefttable=gtk_table_new(4,2,0);
@@ -738,7 +739,8 @@
/* underlying boxes/frames */
gtk_box_pack_start(GTK_BOX(topbox),lefttable,1,1,0);
- gtk_box_pack_start(GTK_BOX(topbox),righttopbox,0,0,0);
+ gtk_box_pack_start(GTK_BOX(topbox),righttopal,0,0,0);
+ gtk_container_add(GTK_CONTAINER(righttopal),righttopbox);
/* plot control checkboxes */
{
@@ -804,10 +806,11 @@
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);
+ //gtk_table_set_col_spacing (GTK_TABLE (lefttable), 0, 2);
/* right control frame */
- gtk_container_set_border_width (GTK_CONTAINER (righttopbox), 6);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(righttopal),6,6,2,6);
+ //gtk_container_set_border_width (GTK_CONTAINER (righttopbox), 6);
gtk_container_set_border_width (GTK_CONTAINER (rightbox), 6);
gtk_frame_set_shadow_type(GTK_FRAME(rightframe),GTK_SHADOW_ETCHED_IN);
gtk_widget_set_name(rightframebox,"controlpanel");
@@ -863,25 +866,22 @@
GtkWidget *tbox=bwtable=gtk_table_new(2,2,0);
GtkWidget *menu=bwbutton=gtk_combo_box_new_text();
- char *entries[]={"native","display"};
- //"1Hz","3Hz","10Hz","30Hz","100Hz","300Hz","1kHz",
- //"1/24oct","1/12oct","1/6oct","1/3oct"};
+ for(i=0;bw_entries[i];i++)
+ gtk_combo_box_append_text (GTK_COMBO_BOX (menu), bw_entries[i]);
- for(i=0;i<2;i++)
- 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 (bwchange), NULL);
GtkWidget *menu2=bwmodebutton=gtk_combo_box_new_text();
- char *entries2[]={"RBW","VBW"};
- for(i=0;i<2;i++)
+ char *entries2[]={"ampl","power","psd","video",NULL};
+ for(i=0;entries2[i];i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu2), entries2[i]);
-
+
g_signal_connect (G_OBJECT (menu2), "changed",
G_CALLBACK (bwmodechange), NULL);
+
gtk_combo_box_set_active(GTK_COMBO_BOX(menu2),0);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(menu),0);
gtk_table_attach_defaults(GTK_TABLE(tbox),menu,0,1,0,1);
gtk_table_attach_defaults(GTK_TABLE(tbox),menu2,1,2,0,1);
@@ -894,7 +894,7 @@
for(i=0;i<3;i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu3), entries3[i]);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu3),plot_scale);
-
+
g_signal_connect (G_OBJECT (menu3), "changed",
G_CALLBACK (scalechange), NULL);
@@ -902,7 +902,7 @@
char *entries4[]={"1dB","10dB","20dB","45dB","90dB","140dB","190dB"};
for(i=0;i<7;i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu4), entries4[i]);
-
+
g_signal_connect (G_OBJECT (menu4), "changed",
G_CALLBACK (depthchange), NULL);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu4),4);
@@ -913,39 +913,40 @@
gtk_box_pack_start(GTK_BOX(bbox),tbox,0,0,0);
}
-
+
/* mode */
{
GtkWidget *menu=gtk_combo_box_new_text();
- char *entries[]={"current frame","maximum","accumulate","average"};
- for(i=0;i<4;i++)
+ char *entries[]={"instantaneous","maximum","accumulate","average",NULL};
+ for(i=0;entries[i];i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), entries[i]);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu),plot_mode);
gtk_box_pack_start(GTK_BOX(bbox),menu,0,0,0);
-
+
g_signal_connect (G_OBJECT (menu), "changed",
G_CALLBACK (modechange), NULL);
}
-
+
/* link */
{
GtkWidget *menu=gtk_combo_box_new_text();
- char *entries[LINKS]={"independent",
- "sum",
- "subtract ref",
- "subtract from",
- "response/phase"};
+ char *entries[]={"independent",
+ "sum",
+ "subtract ref",
+ "subtract from",
+ "response/phase",
+ NULL};
- for(i=0;i<LINKS;i++)
+ for(i=0;entries[i];i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), entries[i]);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu),0);
gtk_box_pack_start(GTK_BOX(bbox),menu,0,0,0);
-
+
g_signal_connect (G_OBJECT (menu), "changed",
G_CALLBACK (linkchange), NULL);
}
-
+
{
GtkWidget *sep=gtk_hseparator_new();
gtk_box_pack_start(GTK_BOX(bbox),sep,0,0,4);
@@ -960,7 +961,7 @@
gtk_box_pack_start(GTK_BOX(bbox),button,0,0,0);
run=button;
}
-
+
/* loop */
/* rewind */
{
@@ -970,17 +971,17 @@
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (loopchange), NULL);
gtk_box_pack_start(GTK_BOX(box),button,1,1,0);
gtk_widget_set_sensitive(button,global_seekable);
-
+
button=gtk_button_new_with_mnemonic("re_wind");
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);
}
-
+
/* clear */
/* dump */
{
@@ -989,8 +990,8 @@
gtk_widget_add_accelerator (button, "activate", group, GDK_c, 0, 0);
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (clearchange), NULL);
gtk_box_pack_start(GTK_BOX(box),button,1,1,0);
-
+
button=gtk_button_new_with_mnemonic("_dump data");
gtk_widget_add_accelerator (button, "activate", group, GDK_d, 0, 0);
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (dump), NULL);
@@ -1143,4 +1144,3 @@
gtk_main ();
}
-
Modified: trunk/spectrum/spec_plot.c
===================================================================
--- trunk/spectrum/spec_plot.c 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/spec_plot.c 2012-06-14 07:44:56 UTC (rev 18405)
@@ -45,10 +45,15 @@
static GtkDrawingAreaClass *parent_class = NULL;
+#define PHAX_MIN 6
+
static void compute_xgrid(Plot *p, fetchdata *f){
- if(p->maxrate!=f->maxrate || p->scale!=f->scale || p->width != f->width){
+ if(p->maxrate!=f->maxrate ||
+ p->scale!=f->scale ||
+ p->width != f->width){
GtkWidget *widget=GTK_WIDGET(p);
- int width = widget->allocation.width-p->padx-(f->phase_active?p->phax:0);
+ int width = widget->allocation.width-p->padx-
+ (f->phase_active?p->phax:PHAX_MIN);
int nyq=f->maxrate/2.;
int i,j;
@@ -204,7 +209,7 @@
int phase = f->phase_active;
int padx = p->padx;
- int phax = phase ? p->phax : 0;
+ int phax = phase ? p->phax : PHAX_MIN;
int pwidth = width - padx - phax;
/* lazy GC init */
@@ -253,8 +258,7 @@
GdkGC *gc=parent->style->bg_gc[0];
gdk_draw_rectangle(p->backing,gc,1,0,0,padx,height);
gdk_draw_rectangle(p->backing,gc,1,0,height-p->pady,width,p->pady);
- if(phase)
- gdk_draw_rectangle(p->backing,gc,1,width-phax,0,phax,height);
+ gdk_draw_rectangle(p->backing,gc,1,width-phax,0,phax,height);
gc=parent->style->white_gc;
gdk_draw_rectangle(p->backing,gc,1,padx,0,pwidth,height-p->pady);
@@ -263,8 +267,8 @@
compute_xgrid(p,f);
p->maxrate=f->maxrate;
p->scale=f->scale;
+ p->width=f->width;
p->phase_active=f->phase_active;
- p->width=f->width;
/* draw the light x grid */
{
@@ -569,11 +573,11 @@
int pv = rint((pp->pmax - ymid/(float)(height-p->pady) *
(pp->pmax - pp->pmin))/10);
if(ymid>=height-p->pady)break;
- if(ymid>=0 && pv>=-18 && pv<=18 && (pv&1)==0){
+ if(ymid>=0 && pv>=-18 && pv<=18 && ((pv&1)==0 || del>2)){
int px,py;
pango_layout_get_pixel_size(p->phase_layout[pv+18],&px,&py);
gdk_draw_layout (p->backing,p->phasegc,
- width-p->phax+2, ymid-py/2,
+ width-phax+2, ymid-py/2,
p->phase_layout[pv+18]);
}
}
@@ -585,8 +589,8 @@
(pp->pmax - pp->pmin));
if(ymid>=height-p->pady)break;
if(ymid>=0 && pv>=-180 && pv<=180)
- gdk_draw_line(p->backing,p->phasegc,width-p->phax-(i%5==0?15:10),
- ymid,width-p->phax-(i%5==0?5:7),ymid);
+ gdk_draw_line(p->backing,p->phasegc,width-phax-(i%5==0?15:10),
+ ymid,width-phax-(i%5==0?5:7),ymid);
}
}else if(del>5){
for(i=0;;i++){
@@ -595,8 +599,8 @@
(pp->pmax - pp->pmin));
if(ymid>=height-p->pady)break;
if(ymid>=0 && pv>=-180 && pv<=180)
- gdk_draw_line(p->backing,p->phasegc,width-p->phax-12,ymid,
- width-p->phax-7,ymid);
+ gdk_draw_line(p->backing,p->phasegc,width-phax-12,ymid,
+ width-phax-7,ymid);
}
} else if(del>2){
for(i=0;;i++){
@@ -605,8 +609,8 @@
(pp->pmax - pp->pmin));
if(ymid>=height-p->pady)break;
if(ymid>=0 && pv>=-180 && pv<=180)
- gdk_draw_line(p->backing,p->phasegc,width-p->phax-15,ymid,
- width-p->phax-5,ymid);
+ gdk_draw_line(p->backing,p->phasegc,width-phax-15,ymid,
+ width-phax-5,ymid);
}
}
@@ -617,12 +621,12 @@
(pp->pmax - pp->pmin));
if(ymid>=height-p->pady)break;
if(ymid>=0 && pv>=-180 && pv<=180){
- gdk_draw_line(p->backing,p->phasegc,width-p->phax-5,ymid-1,
- width-p->phax-1,ymid-1);
- gdk_draw_line(p->backing,p->phasegc,width-p->phax-25,ymid,
- width-p->phax-1,ymid);
- gdk_draw_line(p->backing,p->phasegc,width-p->phax-5,ymid+1,
- width-p->phax-1,ymid+1);
+ gdk_draw_line(p->backing,p->phasegc,width-phax-5,ymid-1,
+ width-phax-1,ymid-1);
+ gdk_draw_line(p->backing,p->phasegc,width-phax-25,ymid,
+ width-phax-1,ymid);
+ gdk_draw_line(p->backing,p->phasegc,width-phax-5,ymid+1,
+ width-phax-1,ymid+1);
}
}
}else{
@@ -633,8 +637,8 @@
(pp->pmax - pp->pmin));
if(ymid>=height-p->pady)break;
if(ymid>=0 && pv>=-180 && pv<=180)
- gdk_draw_line(p->backing,p->phasegc,width-p->phax-15,ymid,
- width-p->phax-5,ymid);
+ gdk_draw_line(p->backing,p->phasegc,width-phax-15,ymid,
+ width-phax-5,ymid);
}
for(i=0;;i++){
@@ -643,12 +647,12 @@
(pp->pmax - pp->pmin))/10);
if(ymid>=height-p->pady)break;
if(ymid>=0 && pv>=-18 && pv<=18 && (pv&1)==0){
- gdk_draw_line(p->backing,p->phasegc,width-p->phax-5,ymid-1,
- width-p->phax-1,ymid-1);
- gdk_draw_line(p->backing,p->phasegc,width-p->phax-25,ymid,
- width-p->phax-1,ymid);
- gdk_draw_line(p->backing,p->phasegc,width-p->phax-5,ymid+1,
- width-p->phax-1,ymid+1);
+ gdk_draw_line(p->backing,p->phasegc,width-phax-5,ymid-1,
+ width-phax-1,ymid-1);
+ gdk_draw_line(p->backing,p->phasegc,width-phax-25,ymid,
+ width-phax-1,ymid);
+ gdk_draw_line(p->backing,p->phasegc,width-phax-5,ymid+1,
+ width-phax-1,ymid+1);
}
}
}
@@ -761,8 +765,13 @@
widget->allocation.width,
widget->allocation.height,
-1);
- p->configured=1;
- replot(0,0,0);
+
+ if(!p->configured){
+ p->configured=1;
+ replot(1,0,0);
+ }else{
+ replot(0,0,0);
+ }
return TRUE;
}
@@ -832,9 +841,9 @@
/* log X scale */
{
- char *labels[16]={"10Hz","20","30","50","100Hz",
+ char *labels[16]={"10","20","30","50","100",
"200","300","500","1kHz",
- "2k","3k","5k","10kHz",
+ "2kHz","3kHz","5k","10kHz",
"20k","30k","50k"};
p->log_layout=calloc(17,sizeof(*p->log_layout));
for(i=0;i<16;i++)
@@ -843,7 +852,7 @@
/* ISO log X scale */
{
- char *labels[12]={"31Hz","63Hz","125Hz","250Hz","500Hz","1kHz","2kHz",
+ char *labels[12]={"31","63","125","250","500","1kHz","2kHz",
"4kHz","8kHz","16kHz","32kHz","64kHz"};
p->iso_layout=calloc(13,sizeof(*p->iso_layout));
for(i=0;i<12;i++)
@@ -896,7 +905,6 @@
/* dB Y scale (-) */
p->db_layoutN=gtk_widget_create_pango_layout(ret,"-");
- p->phase_active=0;
return ret;
}
@@ -905,13 +913,13 @@
}
int plot_get_right_pad (Plot *m){
- return (m->phase_active ? m->phax : 0);
+ return (m->phase_active ? m->phax : PHAX_MIN);
}
-int plot_width (Plot *m){
- return GTK_WIDGET(m)->allocation.width;
+int plot_width (Plot *m,int ph){
+ return GTK_WIDGET(m)->allocation.width-m->padx-(ph?m->phax:PHAX_MIN);
}
int plot_height (Plot *m){
- return GTK_WIDGET(m)->allocation.height;
+ return GTK_WIDGET(m)->allocation.height-m->pady;
}
Modified: trunk/spectrum/spec_plot.h
===================================================================
--- trunk/spectrum/spec_plot.h 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/spec_plot.h 2012-06-14 07:44:56 UTC (rev 18405)
@@ -49,7 +49,6 @@
float pmin;
int height;
int width;
- int increment;
} fetchdata;
typedef struct {
@@ -133,7 +132,7 @@
int plot_get_left_pad (Plot *m);
int plot_get_right_pad (Plot *m);
int plot_height (Plot *m);
-int plot_width (Plot *m);
+int plot_width (Plot *m,int ph);
GdkColor chcolor(int ch);
extern void replot(int scale_reset, int inactive_reset, int scale_damp);
Modified: trunk/spectrum/spec_process.c
===================================================================
--- trunk/spectrum/spec_process.c 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/spec_process.c 2012-06-14 07:44:56 UTC (rev 18405)
@@ -30,18 +30,21 @@
static int prev_total_ch=-1;
static pthread_mutex_t feedback_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-static int feedback_increment=0;
+static pthread_mutex_t bw_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static float *feedback_count=NULL;
static float *process_work=NULL;
-static float **feedback_acc=NULL;
-static float **feedback_max=NULL;
-static float **feedback_instant=NULL;
+static float **mag_acc=NULL;
+static float **mag_max=NULL;
+static float **mag_instant=NULL;
-static float **ph_acc=NULL;
-static float **ph_max=NULL;
-static float **ph_instant=NULL;
+static float **phI_acc=NULL;
+static float **phQ_acc=NULL;
+static float **phI_max=NULL;
+static float **phQ_max=NULL;
+static float **phI_instant=NULL;
+static float **phQ_instant=NULL;
static float **xmappingL=NULL;
static float **xmappingM=NULL;
@@ -63,36 +66,52 @@
if(plan)fftwf_destroy_plan(plan);
- if(feedback_acc){
+ if(mag_acc){
for(i=0;i<prev_total_ch;i++)
- if(feedback_acc[i])free(feedback_acc[i]);
- free(feedback_acc);
+ if(mag_acc[i])free(mag_acc[i]);
+ free(mag_acc);
}
- if(feedback_max){
+ if(mag_max){
for(i=0;i<prev_total_ch;i++)
- if(feedback_max[i])free(feedback_max[i]);
- free(feedback_max);
+ if(mag_max[i])free(mag_max[i]);
+ free(mag_max);
}
- if(feedback_instant){
+ if(mag_instant){
for(i=0;i<prev_total_ch;i++)
- if(feedback_instant[i])free(feedback_instant[i]);
- free(feedback_instant);
+ if(mag_instant[i])free(mag_instant[i]);
+ free(mag_instant);
}
- if(ph_acc){
+
+ if(phI_acc){
for(i=0;i<prev_total_ch;i++)
- if(ph_acc[i])free(ph_acc[i]);
- free(ph_acc);
+ if(phI_acc[i])free(phI_acc[i]);
+ free(phI_acc);
}
- if(ph_max){
+ if(phQ_acc){
for(i=0;i<prev_total_ch;i++)
- if(ph_max[i])free(ph_max[i]);
- free(ph_max);
+ if(phQ_acc[i])free(phQ_acc[i]);
+ free(phQ_acc);
}
- if(ph_instant){
+ if(phI_max){
for(i=0;i<prev_total_ch;i++)
- if(ph_instant[i])free(ph_instant[i]);
- free(ph_instant);
+ if(phI_max[i])free(phI_max[i]);
+ free(phI_max);
}
+ if(phQ_max){
+ for(i=0;i<prev_total_ch;i++)
+ if(phQ_max[i])free(phQ_max[i]);
+ free(phQ_max);
+ }
+ if(phI_instant){
+ for(i=0;i<prev_total_ch;i++)
+ if(phI_instant[i])free(phI_instant[i]);
+ free(phI_instant);
+ }
+ if(phQ_instant){
+ for(i=0;i<prev_total_ch;i++)
+ if(phQ_instant[i])free(phQ_instant[i]);
+ free(phQ_instant);
+ }
if(process_work)free(process_work);
if(feedback_count)free(feedback_count);
@@ -103,24 +122,32 @@
process_work=calloc(blocksize+2,sizeof(*process_work));
feedback_count=calloc(total_ch,sizeof(*feedback_count));
- feedback_acc=malloc(total_ch*sizeof(*feedback_acc));
- feedback_max=malloc(total_ch*sizeof(*feedback_max));
- feedback_instant=malloc(total_ch*sizeof(*feedback_instant));
+ mag_acc=calloc(total_ch,sizeof(*mag_acc));
+ mag_max=calloc(total_ch,sizeof(*mag_max));
+ mag_instant=calloc(total_ch,sizeof(*mag_instant));
- ph_acc=malloc(total_ch*sizeof(*ph_acc));
- ph_max=malloc(total_ch*sizeof(*ph_max));
- ph_instant=malloc(total_ch*sizeof(*ph_instant));
+ phI_acc=calloc(total_ch,sizeof(*phI_acc));
+ phQ_acc=calloc(total_ch,sizeof(*phQ_acc));
+ phI_max=calloc(total_ch,sizeof(*phI_max));
+ phQ_max=calloc(total_ch,sizeof(*phQ_max));
+ phI_instant=calloc(total_ch,sizeof(*phI_instant));
+ phQ_instant=calloc(total_ch,sizeof(*phQ_instant));
freqbuffer=fftwf_malloc((blocksize+2)*sizeof(*freqbuffer));
for(i=0;i<total_ch;i++){
- 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));
+ mag_acc[i]=calloc(blocksize/2+1,sizeof(**mag_acc));
+ mag_max[i]=calloc(blocksize/2+1,sizeof(**mag_max));
+ mag_instant[i]=calloc(blocksize/2+1,sizeof(**mag_instant));
- ph_acc[i]=calloc(blocksize+2,sizeof(**ph_acc));
- ph_max[i]=calloc(blocksize+2,sizeof(**ph_max));
- ph_instant[i]=calloc(blocksize+2,sizeof(**ph_instant));
+ if(i>0){
+ phI_acc[i]=calloc(blocksize/2+1,sizeof(**phI_acc));
+ phI_max[i]=calloc(blocksize/2+1,sizeof(**phI_max));
+ phI_instant[i]=calloc(blocksize/2+1,sizeof(**phI_instant));
+ phQ_acc[i]=calloc(blocksize/2+1,sizeof(**phQ_acc));
+ phQ_max[i]=calloc(blocksize/2+1,sizeof(**phQ_max));
+ phQ_instant[i]=calloc(blocksize/2+1,sizeof(**phQ_instant));
+ }
}
prev_total_ch = total_ch;
@@ -139,50 +166,73 @@
}
void rundata_clear(){
- int i,j;
+ int i;
pthread_mutex_lock(&feedback_mutex);
for(i=0;i<total_ch;i++){
feedback_count[i]=0;
- memset(feedback_acc[i],0,(blocksize/2+1)*sizeof(**feedback_acc));
- memset(feedback_max[i],0,(blocksize/2+1)*sizeof(**feedback_max));
- memset(feedback_instant[i],0,(blocksize/2+1)*sizeof(**feedback_instant));
+ memset(mag_acc[i],0,(blocksize/2+1)*sizeof(**mag_acc));
+ memset(mag_max[i],0,(blocksize/2+1)*sizeof(**mag_max));
+ memset(mag_instant[i],0,(blocksize/2+1)*sizeof(**mag_instant));
- for(j=0;j<blocksize+2;j++){
- ph_acc[i][j]=0;
- ph_max[i][j]=0;
- ph_instant[i][j]=0;
+ if(i>0){
+ memset(phI_acc[i],0,(blocksize/2+1)*sizeof(**phI_acc));
+ memset(phQ_acc[i],0,(blocksize/2+1)*sizeof(**phQ_acc));
+ memset(phI_max[i],0,(blocksize/2+1)*sizeof(**phI_max));
+ memset(phQ_max[i],0,(blocksize/2+1)*sizeof(**phQ_max));
+ memset(phI_instant[i],0,(blocksize/2+1)*sizeof(**phI_instant));
+ memset(phQ_instant[i],0,(blocksize/2+1)*sizeof(**phQ_instant));
}
}
pthread_mutex_unlock(&feedback_mutex);
}
-/* return 0 on EOF, 1 otherwise */
-static int process(){
- int fi,i,j,ch;
+char *bw_entries[]=
+ {"native","display",
+ ".1Hz",".3Hz","1Hz","3Hz","10Hz","30Hz","100Hz",NULL};
+float bw_values[]=
+ {0., 0., .1, .3, 1, 3, 10, 30, 100};
- if(acc_rewind)
- rewind_files();
- acc_rewind=0;
+//static int bandwidth_choice=0;
+//static float bandwidth=-1;
+//static int detector_mode=0;
- if(input_read(acc_loop,0))
- return 0;
+void set_bandwidth_detector(int bw, int det){
+#if 0
+ pthread_mutex_lock(&bw_mutex);
+ bandwidth_choice=bw;
+ detector_mode=det;
+ compute_bandwidth();
+ pthread_mutex_unlock(&bw_mutex);
+ pthread_mutex_lock(&feedback_mutex);
+ rundata_clear();
+ accumulate_feedback();
+ pthread_mutex_unlock(&feedback_mutex);
+#endif
+}
+
+static void process(void){
/* by channel */
- ch=0;
+ int i,j,fi,ch=0;
for(fi=0;fi<inputs;fi++){
- if(blockbufferfill[fi]){
+ if(blockbuffernew[fi]){
+ blockbuffernew[fi]=0;
for(i=ch;i<ch+channels[fi];i++){
+ pthread_mutex_lock(&bw_mutex);
float *data=blockbuffer[i];
- /* window the blockbuffer into the FFT buffer */
+ /* window the blockbuffer into the FFT buffer, save a copy of
+ current frame for BW changes */
for(j=0;j<blocksize;j++){
- freqbuffer[j]=data[j]*window[j];
+ freqbuffer[j]=window[j]*data[j];
}
/* transform */
fftwf_execute(plan);
+ pthread_mutex_unlock(&bw_mutex);
+
pthread_mutex_lock(&feedback_mutex);
/* perform desired accumulations */
@@ -192,6 +242,7 @@
float sqR = R*R;
float sqI = I*I;
float sqM = sqR+sqI;
+ //float M = sqrtf(sqM);
/* deal with phase accumulate/rotate */
if(i==ch){
@@ -208,23 +259,23 @@
pR = (rR*R - rI*I);
pI = (rR*I + rI*R);
- ph_instant[i][j]=pR;
- ph_instant[i][j+1]=pI;
+ phI_instant[i][j>>1]=pR;
+ phQ_instant[i][j>>1]=pI;
- ph_acc[i][j]+=pR;
- ph_acc[i][j+1]+=pI;
+ phI_acc[i][j>>1]+=pR;
+ phQ_acc[i][j>>1]+=pI;
- if(feedback_max[i][j>>1]<sqM){
- ph_max[i][j]=pR;
- ph_max[i][j+1]=pI;
+ if(mag_max[i][j>>1]<sqM){
+ phI_max[i][j>>1]=pR;
+ phQ_max[i][j>>1]=pI;
}
}
- feedback_instant[i][j>>1]=sqM;
- feedback_acc[i][j>>1]+=sqM;
+ mag_instant[i][j>>1]=sqM;
+ mag_acc[i][j>>1]+=sqM;
- if(feedback_max[i][j>>1]<sqM)
- feedback_max[i][j>>1]=sqM;
+ if(mag_max[i][j>>1]<sqM)
+ mag_max[i][j>>1]=sqM;
}
feedback_count[i]++;
@@ -234,32 +285,42 @@
}
ch+=channels[fi];
}
-
- feedback_increment++;
- write(eventpipe[1],"",1);
- return 1;
}
void *process_thread(void *dummy){
+ int ret;
pthread_mutex_lock(&feedback_mutex);
init_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();
- rundata_clear();
- metareload=1;
- pthread_mutex_unlock(&feedback_mutex);
- write(eventpipe[1],"",1);
- }else{
- pthread_mutex_unlock(&feedback_mutex);
- break;
+ while(!process_exit){
+
+ if(acc_rewind) rewind_files();
+ acc_rewind=0;
+
+ ret=input_read(acc_loop,0);
+ if(ret==0) break;
+ if(ret==-1){
+ /* a pipe returned EOF; attempt reopen */
+ pthread_mutex_lock(&feedback_mutex);
+ if(pipe_reload()){
+ init_process();
+ rundata_clear();
+ metareload=1;
+ pthread_mutex_unlock(&feedback_mutex);
+ write(eventpipe[1],"",1);
+ continue;
+ }else{
+ pthread_mutex_unlock(&feedback_mutex);
+ break;
+ }
}
+
+ process();
+ write(eventpipe[1],"",1);
}
+
+ /* eof on all inputs */
process_active=0;
write(eventpipe[1],"",1);
return NULL;
@@ -278,7 +339,7 @@
fprintf(out,"%f ",(double)i*rate[fi]/blocksize);
for(j=ch;j<ch+channels[fi];j++)
- fprintf(out,"%f ",todB(feedback_acc[j][i])*.5);
+ fprintf(out,"%f ",todB(mag_acc[j][i])*.5);
fprintf(out,"\n");
}
fprintf(out,"\n");
@@ -293,7 +354,7 @@
fprintf(out,"%f ",(double)i*rate[fi]/blocksize);
for(j=ch;j<ch+channels[fi];j++)
- fprintf(out,"%f ",todB(feedback_max[j][i])*.5);
+ fprintf(out,"%f ",todB(mag_max[j][i])*.5);
fprintf(out,"\n");
}
fprintf(out,"\n");
@@ -308,7 +369,7 @@
fprintf(out,"%f ",(double)i*rate[fi]/blocksize);
for(j=ch;j<ch+channels[fi];j++)
- fprintf(out,"%f ",todB(feedback_instant[j][i])*.5);
+ fprintf(out,"%f ",todB(mag_instant[j][i])*.5);
fprintf(out,"\n");
}
fprintf(out,"\n");
@@ -323,7 +384,7 @@
/* phase */
for(i=0;i<blocksize+2;i+=2){
fprintf(out,"%f ",(double)i*.5*rate[fi]/blocksize);
- fprintf(out,"%f ",atan2(ph_acc[ch+1][i+1],ph_acc[ch+1][i])*57.29);
+ fprintf(out,"%f ",atan2(phQ_acc[ch+1][i>>1],phI_acc[ch+1][i>>1])*57.29);
fprintf(out,"\n");
}
fprintf(out,"\n");
@@ -343,17 +404,21 @@
/* 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 height, int width){
+ float bw, int bwmode,
+ int *process_in, Plot *plot){
int ch,ci,i,j,fi;
float **data;
- float **ph;
+ float **phI;
+ float **phQ;
float *normptr;
float maxrate=-1.;
float nyq;
- int process[total_ch];
+ int *process;
+ int width=-1;
pthread_mutex_lock(&feedback_mutex);
init_process();
+ process = alloca(total_ch*sizeof(*process));
if(total_ch!=fetch_ret.total_ch){
if(fetch_ret.data){
@@ -388,18 +453,29 @@
ch_now+=channels[i];
ch_in+=fetch_ret.channels[i];
}
+
memcpy(fetch_ret.active,process,total_ch*sizeof(*process));
}
+ fetch_ret.phase_active=0;
+ if(link == LINK_PHASE){
+ int cho=0;
+ int gi;
+ for(gi=0;gi<inputs;gi++)
+ if(channels[gi]>1 && fetch_ret.active[cho+1]){
+ fetch_ret.phase_active=1;
+ break;
+ }
+ }
+
fetch_ret.groups=inputs;
fetch_ret.scale=scale;
fetch_ret.mode=mode;
fetch_ret.link=link;
- fetch_ret.height=height;
- fetch_ret.width=width;
+ fetch_ret.height=plot_height(plot);
+ fetch_ret.width=width=plot_width(plot,fetch_ret.phase_active);
fetch_ret.total_ch=total_ch;
- fetch_ret.increment=feedback_increment;
for(fi=0;fi<inputs;fi++)
if(rate[fi]>maxrate)maxrate=rate[fi];
@@ -413,17 +489,6 @@
fetch_ret.reload=metareload;
metareload=0;
- if(link == LINK_PHASE){
- int cho=0;
- int gi;
- fetch_ret.phase_active=0;
- for(gi=0;gi<inputs;gi++)
- if(channels[gi]>1 && fetch_ret.active[cho+1]){
- fetch_ret.phase_active=1;
- break;
- }
- }
-
/* are our scale mappings up to date? */
if(scale != metascale || width != metawidth || fetch_ret.reload){
if(!xmappingL) xmappingL = calloc(inputs, sizeof(*xmappingL));
@@ -459,7 +524,6 @@
float hoff=1.;
float lfreq,mfreq,hfreq;
- /* awaiting new RBW/ VBW code */
off=.5;
switch(scale){
@@ -522,20 +586,24 @@
normptr=NULL;
switch(mode){
case 0: /* independent / instant */
- data=feedback_instant;
- ph=ph_instant;
+ data=mag_instant;
+ phI=phI_instant;
+ phQ=phQ_instant;
break;
case 1: /* independent / max */
- data=feedback_max;
- ph=ph_max;
+ data=mag_max;
+ phI=phI_max;
+ phQ=phQ_max;
break;
case 2: /* independent / accumulate */
- data=feedback_acc;
- ph=ph_acc;
+ data=mag_acc;
+ phI=phI_acc;
+ phQ=phQ_acc;
break;
case 3: /* independent / average */
- data=feedback_acc;
- ph=ph_acc;
+ data=mag_acc;
+ phI=phI_acc;
+ phQ=phQ_acc;
normptr=feedback_count;
break;
}
@@ -544,6 +612,7 @@
fetch_ret.ymax = -210.;
fetch_ret.pmax = -180.;
fetch_ret.pmin = 180.;
+
for(fi=0;fi<inputs;fi++){
float *L = xmappingL[fi];
float *M = xmappingM[fi];
@@ -555,6 +624,7 @@
for(ci=0;ci<channels[fi];ci++){
if(process[ch+ci]){
+
float *y = fetch_ret.data[ci+ch];
float *m = data[ci+ch];
int prevbin;
@@ -866,7 +936,8 @@
float *r = data[ch];
float *m = data[ch+1];
- float *p = ph[ch+1];
+ float *pI = phI[ch+1];
+ float *pQ = phQ[ch+1];
if(feedback_count[ch]==0){
memset(om,0,width*2*sizeof(*om));
@@ -898,22 +969,22 @@
firsty=lasty=min=max=(a+(b-a)*del);
if(process[ch+1]){
- float aP = (isnan(a) ? NAN : atan2f(p[mid*2+1],p[mid*2]));
- float bP = (isnan(b) ? NAN : atan2f(p[mid*2+3],p[mid*2+2]));
+ float aP = (isnan(a) ? NAN : atan2f(pQ[mid],pI[mid]));
+ float bP = (isnan(b) ? NAN : atan2f(pQ[mid+1],pI[mid+1]));
P=(aP+(bP-aP)*del)*57.29;
}
}else{
firsty=min=max=m[first]/r[first];
- R = p[first*2];
- I = p[first*2+1];
+ R = pI[first];
+ I = pQ[first];
for(j=first+1;j<last;j++){
float a = m[j]/r[j];
if(a<min)min=a;
if(a>max)max=a;
- R += p[j*2];
- I += p[j*2+1];
+ R += pI[j];
+ I += pQ[j];
}
lasty=todB(m[j-1]/r[j-1]);
Modified: trunk/spectrum/spectrum.c
===================================================================
--- trunk/spectrum/spectrum.c 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/spectrum.c 2012-06-14 07:44:56 UTC (rev 18405)
@@ -214,15 +214,6 @@
if(sig==SIGILL)sigill=1;
}
-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");
@@ -302,7 +293,8 @@
//signal(SIGINT,handler);
signal(SIGSEGV,handler);
- if(input_load(blockslice_callback))exit(1);
+ blockslice_frac=10;
+ if(input_load())exit(1);
/* go */
panel_go(argc,argv);
Modified: trunk/spectrum/version.h
===================================================================
--- trunk/spectrum/version.h 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/version.h 2012-06-14 07:44:56 UTC (rev 18405)
@@ -1,2 +1,2 @@
#define VERSION "$Id$ "
-/* DO NOT EDIT: Automated versioning hack [Sun Jun 3 23:19:05 EDT 2012] */
+/* DO NOT EDIT: Automated versioning hack [Thu Jun 14 03:43:07 EDT 2012] */
Modified: trunk/spectrum/wave_panel.c
===================================================================
--- trunk/spectrum/wave_panel.c 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/wave_panel.c 2012-06-14 07:44:56 UTC (rev 18405)
@@ -60,7 +60,6 @@
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};
/* first up... the Fucking Fish */
sig_atomic_t increment_fish=0;
@@ -121,14 +120,6 @@
}
}
-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);
-}
-
static void override_base(GtkWidget *w, int active){
gtk_widget_modify_base
(w, GTK_STATE_NORMAL,
@@ -287,7 +278,6 @@
break;
}
- set_slices(plot_interval,plot_span);
replot();
}
@@ -295,48 +285,48 @@
int choice=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
switch(choice){
case 0:
- plot_interval=1000000;
+ plot_interval=1;
break;
case 1:
- plot_interval=500000;
+ plot_interval=2;
break;
case 2:
- plot_interval=200000;
+ plot_interval=5;
break;
case 3:
- plot_interval=100000;
+ plot_interval=10;
break;
case 4:
- plot_interval=50000; // 20/sec
+ plot_interval=20;
break;
case 5:
- plot_interval=20000; // 50/sec
+ plot_interval=50;
break;
case 6:
- plot_interval=10000;
+ plot_interval=100;
break;
case 7:
- plot_interval=5000;
+ plot_interval=200;
break;
case 8:
- plot_interval=2000;
+ plot_interval=500;
break;
case 9:
plot_interval=1000;
break;
case 10:
- plot_interval=500;
+ plot_interval=2000;
break;
case 11:
- plot_interval=200;
+ plot_interval=5000;
break;
case 12:
- plot_interval=100;
+ plot_interval=10000;
break;
}
- set_slices(plot_interval,plot_span);
- replot();
+ blockslice_frac = plot_interval;
+ //replot();
}
static void triggerchange(GtkWidget *widget,gpointer in){
@@ -466,10 +456,6 @@
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();
@@ -875,7 +861,6 @@
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();
Modified: trunk/spectrum/wave_plot.h
===================================================================
--- trunk/spectrum/wave_plot.h 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/wave_plot.h 2012-06-14 07:44:56 UTC (rev 18405)
@@ -44,7 +44,6 @@
float **data;
int *active;
- int increment;
} fetchdata;
typedef struct {
Modified: trunk/spectrum/wave_process.c
===================================================================
--- trunk/spectrum/wave_process.c 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/wave_process.c 2012-06-14 07:44:56 UTC (rev 18405)
@@ -24,9 +24,6 @@
#include "waveform.h"
#include "io.h"
-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;
@@ -35,42 +32,49 @@
static int metareload = 0;
-static void init_process(void){
+static void process_init(){
+ if(blocksize==0){
+ int fi;
+ /* set block size equal to maximum input rate + epsilon */
+ /* (maximum display width: 1s, maximum update interval 1s) */
+ for(fi=0;fi<inputs;fi++)
+ if(rate[fi]>blocksize)blocksize=rate[fi]+16;
+ }
}
/* return 0 on EOF, 1 otherwise */
-static int process(){
- if(acc_rewind)
- rewind_files();
- acc_rewind=0;
+void *process_thread(void *dummy){
+ int ret;
- if(input_read(acc_loop,1))
- return 0;
+ while(!process_exit){
- feedback_increment++;
- write(eventpipe[1],"",1);
- return 1;
-}
+ process_init();
-void *process_thread(void *dummy){
- pthread_mutex_lock(&feedback_mutex);
- init_process();
- pthread_mutex_unlock(&feedback_mutex);
+ if(acc_rewind) rewind_files();
+ acc_rewind=0;
- 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;
+ ret=input_read(acc_loop,1);
+ if(ret==0) break;
+ if(ret==-1){
+ /* a pipe returned EOF; attempt reopen */
+ pthread_mutex_lock(&blockbuffer_mutex);
+ if(pipe_reload()){
+ blocksize=0;
+ metareload=1;
+ pthread_mutex_unlock(&blockbuffer_mutex);
+ write(eventpipe[1],"",1);
+ continue;
+ }else{
+ pthread_mutex_unlock(&blockbuffer_mutex);
+ break;
+ }
}
+
+ write(eventpipe[1],"",1);
+
}
+
+ /* eof on all inputs */
process_active=0;
write(eventpipe[1],"",1);
return NULL;
@@ -82,14 +86,12 @@
int fi,i,k,ch;
int process[total_ch];
- pthread_mutex_lock(&feedback_mutex);
+ pthread_mutex_lock(&blockbuffer_mutex);
if(!blockbuffer){
- pthread_mutex_unlock(&feedback_mutex);
+ pthread_mutex_unlock(&blockbuffer_mutex);
return NULL;
}
- init_process();
-
if(metareload){
if(fetch_ret.data){
for(i=0;i<fetch_ret.total_ch;i++)
@@ -134,7 +136,6 @@
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));
@@ -173,6 +174,6 @@
ch+=channels[fi];
}
- pthread_mutex_unlock(&feedback_mutex);
+ pthread_mutex_unlock(&blockbuffer_mutex);
return &fetch_ret;
}
Modified: trunk/spectrum/waveform.c
===================================================================
--- trunk/spectrum/waveform.c 2012-06-14 03:25:10 UTC (rev 18404)
+++ trunk/spectrum/waveform.c 2012-06-14 07:44:56 UTC (rev 18405)
@@ -33,7 +33,7 @@
char *version;
char *inputname[MAX_FILES];
int inputs=0;
-int blocksize = 131072; /* starting default */
+int blocksize=0;
extern int plot_bold;
void handler(int sig){
@@ -202,15 +202,6 @@
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;
@@ -291,12 +282,17 @@
//signal(SIGINT,handler);
signal(SIGSEGV,handler);
- if(input_load(blocksize_callback))exit(1);
+ if(input_load())exit(1);
+ /* 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;
+
/* begin with a display width of 1s */
/* begin with an update interval (blockslice) of 100ms */
- for(fi=0;fi<inputs;fi++)
- blockslice[fi]=rate[fi]/10;
+ blockslice_frac = 10;
panel_go(argc,argv);
More information about the commits
mailing list