[xiph-commits] r14589 - trunk/spectrum
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Sat Mar 15 06:43:56 PDT 2008
Author: xiphmont
Date: 2008-03-15 06:43:55 -0700 (Sat, 15 Mar 2008)
New Revision: 14589
Modified:
trunk/spectrum/analyzer.h
trunk/spectrum/panel.c
trunk/spectrum/plot.c
trunk/spectrum/plot.h
trunk/spectrum/process.c
trunk/spectrum/version.h
Log:
More minor refinement of scales, phase/imp calc, etc.
Modified: trunk/spectrum/analyzer.h
===================================================================
--- trunk/spectrum/analyzer.h 2008-03-15 06:08:09 UTC (rev 14588)
+++ trunk/spectrum/analyzer.h 2008-03-15 13:43:55 UTC (rev 14589)
@@ -113,9 +113,9 @@
extern sig_atomic_t process_active;
extern sig_atomic_t process_exit;
-#define LINKS 8
+#define LINKS 10
static char *link_entries[LINKS]={"independent","summed",".1\xCE\xA9 shunt","1\xCE\xA9 shunt","10\xCE\xA9 shunt",
- "resp/phase","THD","THD+N"};
+ "resp/phase","THD","THD-2","THD+N","THD-2+N"};
#define LINK_INDEPENDENT 0
#define LINK_SUMMED 1
#define LINK_IMPEDENCE_p1 2
@@ -123,7 +123,9 @@
#define LINK_IMPEDENCE_10 4
#define LINK_PHASE 5
#define LINK_THD 6
-#define LINK_THDN 7
+#define LINK_THD2 7
+#define LINK_THDN 8
+#define LINK_THDN2 9
#endif
Modified: trunk/spectrum/panel.c
===================================================================
--- trunk/spectrum/panel.c 2008-03-15 06:08:09 UTC (rev 14588)
+++ trunk/spectrum/panel.c 2008-03-15 13:43:55 UTC (rev 14589)
@@ -53,7 +53,7 @@
int plot_mode=0;
int plot_link=0;
int plot_hold=0;
-int plot_depth=45;
+int plot_depth=90;
int plot_last_update=0;
int *active;
@@ -139,16 +139,19 @@
static void depthchange(GtkWidget *widget,struct panel *p){
int choice=gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
switch(choice){
- case 0: /* 20dB */
+ case 0: /* 10dB */
+ plot_depth=10;
+ break;
+ case 1: /* 20dB */
plot_depth=20;
break;
- case 1: /* 45dB */
+ case 2: /* 45dB */
plot_depth=45;
break;
- case 2: /* 90dB */
+ case 3: /* 90dB */
plot_depth=90;
break;
- case 3: /*140dB */
+ case 4: /*140dB */
plot_depth=140;
break;
}
@@ -526,7 +529,7 @@
/* scale */
{
GtkWidget *menu=gtk_combo_box_new_text();
- char *entries[]={"screen resolution","1/24th octave","1/12th octave","1/3 octave"};
+ char *entries[]={"single-pixel","1/24th octave","1/12th octave","1/3 octave"};
for(i=0;i<4;i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), entries[i]);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu),plot_res);
@@ -551,10 +554,10 @@
/* depth */
{
GtkWidget *menu=gtk_combo_box_new_text();
- char *entries[]={"20dB","45dB","90dB","140dB"};
- for(i=0;i<4;i++)
+ char *entries[]={"10dB","20dB","45dB","90dB","140dB"};
+ for(i=0;i<5;i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), entries[i]);
- gtk_combo_box_set_active(GTK_COMBO_BOX(menu),1);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(menu),3);
gtk_box_pack_start(GTK_BOX(bbox),menu,0,0,0);
g_signal_connect (G_OBJECT (menu), "changed",
@@ -564,8 +567,8 @@
/* mode */
{
GtkWidget *menu=gtk_combo_box_new_text();
- char *entries[]={"instant","slowav","maximum","accumulate"};
- for(i=0;i<4;i++)
+ char *entries[]={"realtime","maximum","accumulate"};
+ for(i=0;i<3;i++)
gtk_combo_box_append_text (GTK_COMBO_BOX (menu), entries[i]);
gtk_combo_box_set_active(GTK_COMBO_BOX(menu),plot_mode);
gtk_box_pack_start(GTK_BOX(bbox),menu,0,0,0);
@@ -679,6 +682,9 @@
pthread_mutex_unlock(&feedback_mutex);
replot(panel);
plot_draw(PLOT(panel->plot));
+
+ while (gtk_events_pending())
+ gtk_main_iteration();
}else
pthread_mutex_unlock(&feedback_mutex);
Modified: trunk/spectrum/plot.c
===================================================================
--- trunk/spectrum/plot.c 2008-03-15 06:08:09 UTC (rev 14588)
+++ trunk/spectrum/plot.c 2008-03-15 13:43:55 UTC (rev 14589)
@@ -53,9 +53,9 @@
.5,.4,.3,.2};
for(i=0;i<9;i++)
- p->ygrid[i]=rint( (log10(p->ymax)-log10(lfreqs[i]))/(log10(p->ymax)-log10(.1)) * (height-1));
+ p->ygrid[i]=rint( (log10(p->disp_ymax)-log10(lfreqs[i]))/(log10(p->disp_ymax)-log10(.1)) * (height-1));
for(i=0;i<64;i++)
- p->ytic[i]=rint( (log10(p->ymax)-log10(tfreqs[i]))/(log10(p->ymax)-log10(.1)) * (height-1));
+ p->ytic[i]=rint( (log10(p->disp_ymax)-log10(tfreqs[i]))/(log10(p->disp_ymax)-log10(.1)) * (height-1));
p->ygrids=9;
p->ytics=64;
@@ -264,7 +264,7 @@
gdk_draw_line(p->backing,p->drawgc,padx,p->ytic[i],width,p->ytic[i]);
}else{
- float del=(height-p->pady-1)/(float)p->depth,off;
+ float del=(height-p->pady-1)/(float)p->disp_depth,off;
int i,half=0;
int max,mul;
GdkColor rgb={0,0,0,0};
@@ -274,20 +274,20 @@
half=1;
max=303;
mul=1;
- off=(p->ymax-ceil(p->ymax))*2;
+ off=(p->disp_ymax-ceil(p->disp_ymax))*2;
del*=.5;
}else if(del>8){
max=151;
mul=1;
- off=p->ymax-ceil(p->ymax);
+ off=p->disp_ymax-ceil(p->disp_ymax);
}else if(del*2>8){
max=76;
mul=2;
- off=p->ymax-ceil(p->ymax*.5)*2;
+ off=p->disp_ymax-ceil(p->disp_ymax*.5)*2;
}else{
max=31;
mul=5;
- off=p->ymax-ceil(p->ymax*.2)*5;
+ off=p->disp_ymax-ceil(p->disp_ymax*.2)*5;
}
rgb.red=0xc000;
@@ -347,9 +347,9 @@
}else{
GdkColor rgb={0,0,0,0};
- int label=ceil(p->ymax/5+28),i;
- float del=(height-p->pady-1)/(float)p->depth,step;
- float off=p->ymax-ceil(p->ymax*.2)*5;
+ int label=ceil(p->disp_ymax/5+28),i;
+ float del=(height-p->pady-1)/(float)p->disp_depth,step;
+ float off=p->disp_ymax-ceil(p->disp_ymax*.2)*5;
step=2;
if(del>8)step=1;
@@ -384,16 +384,15 @@
/* phase? draw in phase and tics on right axis */
if(phase){
- GdkColor rgb={0,0,0,0};
- float depth = p->pmax-p->pmin;
- int label=ceil(p->pmax/10+18),i;
+ GdkColor rgb={0,0xd000,0x0000,0x0000};
+ float depth = p->disp_pmax-p->disp_pmin;
+ int label=ceil(p->disp_pmax/10+18),i;
float del=(height-p->pady-1)/depth,step;
- float off=p->pmax-ceil(p->pmax*.1)*10;
+ float off=p->disp_pmax-ceil(p->disp_pmax*.1)*10;
step=2;
if(del>8)step=1;
gdk_gc_set_rgb_fg_color(p->drawgc,&rgb);
- gdk_gc_set_rgb_fg_color(p->dashes,&rgb);
for(i=0;i<37;i++){
if(((label-i)&1)==0 || step==1){
int ymid=rint(del * (i*10+off));
@@ -402,8 +401,7 @@
if(label-i>=0 && label-i<37 && ymid>=0 && ymid<height-p->pady){
pango_layout_get_pixel_size(p->phase_layout[label-i],&px,&py);
- gdk_draw_layout (p->backing,
- widget->style->black_gc,
+ gdk_draw_layout (p->backing,p->drawgc,
width-p->phax, ymid-py/2,
p->phase_layout[label-i]);
}
@@ -455,7 +453,8 @@
for(ch=cho;ch<cho+p->ch[gi];ch++){
if(p->ch_active[ch]){
- int prev;
+ int prev;
+ int first=0;
float yprev=NAN;
rgb = chcolor(ch);
@@ -465,21 +464,21 @@
float val=p->ydata[ch][i];
int y;
- if(impedence){ /* log scale for impedence */
- y =rint( (log10(p->ymax)-log10(val))/(log10(p->ymax)-log10(.1)) *
- (height-p->pady-1));
- }else if(phase && ch==cho+1){
- y= rint((height-p->pady-1)/(p->pmax-p->pmin)*(p->pmax-val));
- }else{
- y= rint((height-p->pady-1)/p->depth*(p->ymax-val));
- }
-
if(isnan(yprev) || isnan(val)){
yprev = val;
}else{
yprev = val;
- if(y<height-p->pady || prev<height-p->pady){
+ if(impedence){ /* log scale for impedence */
+ y =rint( (log10(p->disp_ymax)-log10(val))/(log10(p->disp_ymax)-log10(.1)) *
+ (height-p->pady-1));
+ }else if(phase && ch==cho+1){
+ y= rint((height-p->pady-1)/(p->disp_pmax-p->disp_pmin)*(p->disp_pmax-val));
+ }else{
+ y= rint((height-p->pady-1)/p->disp_depth*(p->disp_ymax-val));
+ }
+
+ if(first && (y<height-p->pady || prev<height-p->pady)){
int ly = y;
int lp = prev;
@@ -496,8 +495,10 @@
gdk_draw_line(p->backing,p->drawgc,padx+i-1,lp,padx+i,ly);
}
+ first=1;
+ prev=y;
}
- prev=y;
+
}
}
@@ -782,8 +783,10 @@
memcpy(p->ydata[i],data[i],width*sizeof(**p->ydata));
/* graph limit updates are conditional depending on mode/link */
- if(pmax<12)pmax=12;
- if(pmin>-12)pmin=-12;
+ pmax+=5;
+ pmin-=5;
+ if(pmax<5)pmax=5;
+ if(pmin>-30)pmin=-30;
switch(p->link){
case LINK_INDEPENDENT:
@@ -812,64 +815,82 @@
than 50px. If any peaks occur above, reset timer. Once timer
runs out, drop 5px per frame */
#define PXTHRESH 25
-#define PXDEL 10
+#define PXDEL 10.
#define TIMERFRAMES 20
if(p->ymax>ymax){
float oldzero = (height-1)/p->depth*p->ymax;
float newzero = (height-1)/p->depth*ymax;
- fprintf(stderr,"old=%f, new=%f, timer=%d\n",oldzero,newzero,p->scaletimer);
if(newzero+PXTHRESH<oldzero){
- if(p->scaletimer){
- p->scaletimer--;
+ if(p->ymaxtimer){
+ p->ymaxtimer--;
}else{
p->ymax = (oldzero-PXDEL)*p->depth/(height-1);
}
}else{
- p->scaletimer = TIMERFRAMES;
+ p->ymaxtimer = TIMERFRAMES;
}
}else
- p->scaletimer = TIMERFRAMES;
+ p->ymaxtimer = TIMERFRAMES;
- /* finally, align phase/response zeros on phase graphs */
- if(ymax>-140){
- if(p->link == LINK_PHASE){
- /* align the phase and response zeros by shifting phase */
- float mzero = (height-1)/p->depth*ymax;
- float pzero = (height-1)/(pmax-pmin)*pmax;
-
- if(mzero<pzero){
- pmin = pmax-(height-1)/mzero*pmax;
- pzero = (height-1)/(pmax-pmin)*pmax;
+ if(p->pmax>pmax || p->pmin<pmin){
+ float newmax = (height-1)/(p->pmax-p->pmin)*(p->pmax-pmax);
+ float newmin = (height-1)/(p->pmax-p->pmin)*(pmin-p->pmin);
+
+ if(newmax>PXTHRESH || newmin>PXTHRESH){
+ if(p->phtimer){
+ p->phtimer--;
}else{
- pmax = pmin/(1-(height-1)/mzero);
- pzero = (height-1)/(pmax-pmin)*pmax;
+ if(newmax>PXTHRESH)
+ p->pmax -= PXDEL/(height-1)*(p->pmax-p->pmin);
+ if(newmin>PXTHRESH)
+ p->pmin += PXDEL/(height-1)*(p->pmax-p->pmin);
}
-
- /* If phase shifts beyond +/- 180, shift main scale. */
-
- if(pmin<-180.){
- /* increase ymax, shift main scale zero down */
- pmin = -180.;
- pzero = (height-1)/(pmax-pmin)*pmax;
- ymax = pzero*p->depth/(height-1);
- }else if(pmax>180.){
- /* only way to reconcile this one is to increase the pdepth */
- pmax = 180.;
- pzero = (height-1)/(pmax-pmin)*pmax;
- p->depth = (height-1)/pzero*ymax;
- }
+ }else{
+ p->phtimer = TIMERFRAMES;
}
- }
+ }else
+ p->phtimer = TIMERFRAMES;
if(ymax<p->depth-140.)ymax=p->depth-140.;
if(ymax>140.)ymax=140.;
if(pmax>180)pmax=180;
- if(pmin<-180)pmin=-180;
-
+ if(pmin<-180)pmin=-180;
if(ymax>p->ymax)p->ymax=ymax;
- p->pmax=pmax;
- p->pmin=pmin;
+ if(pmax>p->pmax)p->pmax=pmax;
+ if(pmin<p->pmin)p->pmin=pmin;
+
+ p->disp_depth = p->depth;
+ p->disp_ymax = p->ymax;
+ p->disp_pmax = p->pmax;
+ p->disp_pmin = p->pmin;
+
+ /* finally, align phase/response zeros on phase graphs */
+ if(p->disp_ymax>-140){
+ if(p->link == LINK_PHASE){
+ /* In a phase/response graph, 0dB/0degrees are bound and always on-screen. */
+ float mzero = (height-1)/p->disp_depth*p->disp_ymax;
+ float pzero = (height-1)/(p->disp_pmax-p->disp_pmin)*p->disp_pmax;
+
+ if(mzero<pzero){
+ /* straightforward; move the dB range down */
+ p->disp_ymax = pzero*p->disp_depth/(height-1);
+ }else{
+ /* a little harder as phase has a min and a max.
+ First increase the pmax to match the dB zero. */
+ p->disp_pmax = p->disp_pmin/(1-(height-1)/mzero);
+ pzero = (height-1)/(p->disp_pmax-p->disp_pmin)*p->disp_pmax;
+
+ /* That worked, but might have run p->max overrange */
+ if(p->disp_pmax>180.){
+ /* only way to reconcile this one is to increase the pdepth */
+ p->disp_pmax = 180.;
+ pzero = (height-1)/(p->disp_pmax-p->disp_pmin)*p->disp_pmax;
+ p->disp_depth = (height-1)/pzero*p->disp_ymax;
+ }
+ }
+ }
+ }
}
void plot_clear (Plot *p){
@@ -882,8 +903,8 @@
for(j=0;j<width;j++)
p->ydata[i][j]=NAN;
p->ymax=p->depth-140;
- p->pmax=12.;
- p->pmin=-12.;
+ p->pmax=0;
+ p->pmin=0;
draw_and_expose(widget);
}
@@ -900,8 +921,8 @@
p->link=link;
p->ymax=-140;
- p->pmax=12.;
- p->pmin=-12.;
+ p->pmax=0;
+ p->pmin=0;
compute_metadata(widget);
plot_refresh(p,NULL);
Modified: trunk/spectrum/plot.h
===================================================================
--- trunk/spectrum/plot.h 2008-03-15 06:08:09 UTC (rev 14588)
+++ trunk/spectrum/plot.h 2008-03-15 13:43:55 UTC (rev 14589)
@@ -84,11 +84,17 @@
float pmax;
float pmin;
+ float disp_depth;
+ float disp_ymax;
+ float disp_pmax;
+ float disp_pmin;
+
float padx;
float phax;
float pady;
- int scaletimer;
+ int ymaxtimer;
+ int phtimer;
};
struct _PlotClass{
Modified: trunk/spectrum/process.c
===================================================================
--- trunk/spectrum/process.c 2008-03-15 06:08:09 UTC (rev 14588)
+++ trunk/spectrum/process.c 2008-03-15 13:43:55 UTC (rev 14589)
@@ -50,12 +50,10 @@
float *process_work;
float **feedback_acc;
-float **feedback_av;
float **feedback_max;
float **feedback_instant;
float **ph_acc;
-float **ph_av;
float **ph_max;
float **ph_instant;
@@ -414,12 +412,10 @@
feedback_work=calloc(total_ch,sizeof(*feedback_work));
feedback_acc=malloc(total_ch*sizeof(*feedback_acc));
- feedback_av=malloc(total_ch*sizeof(*feedback_av));
feedback_max=malloc(total_ch*sizeof(*feedback_max));
feedback_instant=malloc(total_ch*sizeof(*feedback_instant));
ph_acc=malloc(total_ch*sizeof(*ph_acc));
- ph_av=malloc(total_ch*sizeof(*ph_av));
ph_max=malloc(total_ch*sizeof(*ph_max));
ph_instant=malloc(total_ch*sizeof(*ph_instant));
@@ -428,12 +424,10 @@
blockbuffer[i]=calloc(blocksize,sizeof(**blockbuffer));
feedback_acc[i]=calloc(blocksize/2+1,sizeof(**feedback_acc));
- feedback_av[i]=calloc(blocksize/2+1,sizeof(**feedback_av));
feedback_max[i]=calloc(blocksize/2+1,sizeof(**feedback_max));
feedback_instant[i]=calloc(blocksize/2+1,sizeof(**feedback_instant));
ph_acc[i]=calloc(blocksize+2,sizeof(**ph_acc));
- ph_av[i]=calloc(blocksize+2,sizeof(**ph_av));
ph_max[i]=calloc(blocksize+2,sizeof(**ph_max));
ph_instant[i]=calloc(blocksize+2,sizeof(**ph_instant));
}
@@ -650,13 +644,11 @@
for(i=0;i<total_ch;i++){
feedback_count[i]=0;
memset(feedback_acc[i],0,(blocksize/2+1)*sizeof(**feedback_acc));
- memset(feedback_av[i],0,(blocksize/2+1)*sizeof(**feedback_av));
memset(feedback_max[i],0,(blocksize/2+1)*sizeof(**feedback_max));
memset(feedback_instant[i],0,(blocksize/2+1)*sizeof(**feedback_instant));
for(j=0;j<blocksize+2;j++){
ph_acc[i][j]=0;
- ph_av[i][j]=0;
ph_max[i][j]=0;
ph_instant[i][j]=0;
}
@@ -748,22 +740,10 @@
ph_max[i][j]=pR;
ph_max[i][j+1]=pI;
}
-
- if(feedback_count[i]>=100){
- ph_av[i][j]*=.99;
- ph_av[i][j+1]*=.99;
- }
-
- ph_av[i][j]+=.1*pR;
- ph_av[i][j+1]+=.1*pI;
-
}
feedback_instant[i][j>>1]=sqM;
feedback_acc[i][j>>1]+=sqM;
- if(feedback_count[i]>=100)
- feedback_av[i][j>>1]*=.99;
- feedback_av[i][j>>1]+=.1*sqM;
if(feedback_max[i][j>>1]<sqM)
feedback_max[i][j>>1]=sqM;
@@ -968,15 +948,11 @@
data=feedback_instant;
ph=ph_instant;
break;
- case 1: /* independent / average */
- data=feedback_av;
- ph=ph_av;
- break;
- case 2: /* independent / max */
+ case 1: /* independent / max */
data=feedback_max;
ph=ph_max;
break;
- case 3:
+ case 2:
data=feedback_acc;
ph=ph_acc;
break;
@@ -1123,6 +1099,7 @@
float *r = data[ch];
float *m = data[ch+1];
float *p = ph[ch+1];
+ float mag[width];
if(feedback_count[ch]==0){
memset(om,0,width*sizeof(*om));
@@ -1130,7 +1107,7 @@
}else{
/* two vectors only; response and phase */
/* response */
- if(active[ch]){
+ if(active[ch] || active[ch+1]){
for(i=0;i<width;i++){
int first=floor(L[i]);
int last=floor(H[i]);
@@ -1155,10 +1132,10 @@
sumM+=m[last]*del;
}
- if(sumR > 1e-8){
+ mag[i] = todB_a(&sumR)*.5;
+ if(active[ch] && sumR > 1e-8){
sumM /= sumR;
om[i] = todB_a(&sumM)*.5;
- if(om[i]>*ymax)*ymax = om[i];
}else{
om[i] = NAN;
}
@@ -1193,13 +1170,50 @@
if(sumR*sumR+sumI*sumI > 1e-16){
op[i] = atan2(sumI,sumR)*57.29;
- if(op[i]>*pmax)*pmax=op[i];
- if(op[i]<*pmin)*pmin=op[i];
}else{
op[i]=NAN;
}
}
}
+
+ /* scan the resulting buffers for marginal data that would
+ produce spurious output. Specifically we look for sharp
+ falloffs of > 30dB or an original test magnitude under
+ -40dB. */
+#define binspan 5
+ if(active[ch] || active[ch+1]){
+ int max = -140;
+ for(i=0;i<width;i++)
+ if(!isnan(mag[i]) && mag[i]>max)max=mag[i];
+
+ for(i=0;i<width;i++){
+ if(!isnan(mag[i])){
+ if(mag[i]<max-40 || mag[i]<-70){
+ int j=i-binspan;
+ if(j<0)j=0;
+ for(;j<i;j++){
+ om[j]=NAN;
+ op[j]=NAN;
+ }
+ for(;j<width;j++){
+ if(mag[j]>max-40 && mag[j]>-70)break;
+ om[j]=NAN;
+ op[j]=NAN;
+ }
+ i=j+3;
+ for(;j<i && j<width;j++){
+ om[j]=NAN;
+ op[j]=NAN;
+ }
+ }
+ if(om[i]>*ymax)*ymax = om[i];
+ if(!isnan(op[i])){
+ if(op[i]>*pmax)*pmax = op[i];
+ if(op[i]<*pmin)*pmin = op[i];
+ }
+ }
+ }
+ }
}
}
break;
Modified: trunk/spectrum/version.h
===================================================================
--- trunk/spectrum/version.h 2008-03-15 06:08:09 UTC (rev 14588)
+++ trunk/spectrum/version.h 2008-03-15 13:43:55 UTC (rev 14589)
@@ -1,2 +1,2 @@
#define VERSION "$Id: version.h 6914 2004-06-29 03:05:41Z xiphmont $ "
-/* DO NOT EDIT: Automated versioning hack [Sat Mar 15 03:13:41 EDT 2008] */
+/* DO NOT EDIT: Automated versioning hack [Sat Mar 15 10:48:15 EDT 2008] */
More information about the commits
mailing list