1 // Copyright (c) <2012> <Leif Asbrink>
2 //
3 // Permission is hereby granted, free of charge, to any person
4 // obtaining a copy of this software and associated documentation
5 // files (the "Software"), to deal in the Software without restriction,
6 // including without limitation the rights to use, copy, modify,
7 // merge, publish, distribute, sublicense, and/or sell copies of
8 // the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
22 
23 
24 #define YBO 8
25 #define YWF 4
26 
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include "globdef.h"
30 #include "uidef.h"
31 #include "fft1def.h"
32 #include "fft2def.h"
33 #include "fft3def.h"
34 #include "seldef.h"
35 #include "graphcal.h"
36 #include "screendef.h"
37 #include "sigdef.h"
38 #include "rusage.h"
39 #include "thrdef.h"
40 #include "options.h"
41 
update_meter_graph(void)42 void update_meter_graph(void)
43 {
44 int i, j, k, m, n, pa, local_mg_pa;
45 int ya, yb;
46 int old_bar_y;
47 // mgw_p points to the screen position corresponding to mg_px
48 // in the mg_ arrays.
49 // Move the data backwards on screen if necessary and adjust
50 // mgw_p accordingly.
51 hide_mouse(mg.xleft,mg.xright,mg.ytop,mg.ybottom);
52 local_mg_pa=mg_pa;
53 if(mg_bar)
54   {
55   old_bar_y=mg_bar_y;
56   mg_bar_y=mg_y0;
57   if(sw_onechan)
58     {
59     while(mg_px != local_mg_pa)
60       {
61       i=mg_ymin-(mg.yzero+mg.ygain*mg_peak_meter[mg_px]);
62       if(i<mg_ymax)i=mg_ymax;
63       if(i<mg_bar_y)mg_bar_y=i;
64       mg_px=(mg_px+1)&mg_mask;
65       }
66     }
67   else
68     {
69     while(mg_px != local_mg_pa)
70       {
71       i=mg_ymin-(mg.yzero+mg.ygain*mg_peak_meter[2*mg_px]);
72       if(i<mg_ymax)i=mg_ymax;
73       if(i<mg_bar_y)mg_bar_y=i;
74       mg_px=(mg_px+1)&mg_mask;
75       }
76     }
77   update_bar(mg_bar_x1,mg_bar_x2,mg_y0,mg_bar_y,old_bar_y,
78                                                  MG_BAR_COLOR,mg_barbuf);
79   }
80 else
81   {
82   n=(local_mg_pa-mg_px+mg_size)&mg_mask;
83   n+=mgw_p-mg_last_xpixel;
84   yb=0;
85   if(n > 0)
86     {
87     pa=mg_px;
88     m=(mg_px+mg_mask)&mg_mask;
89     if(sw_onechan)
90       {
91       for(j=mgw_p; j>=mg_first_xpixel; j--)
92         {
93         ya=-1;
94         if( (mg.tracks&1)==0)
95           {
96           i=mg_rms_ypix[pa];
97           ya=i;
98           yb=i;
99           k=mg_rms_ypix[m];
100           if(k>ya)ya=k;
101           if(k<yb)yb=k;
102           lir_line(j-1,k,j,i,0);
103           }
104         if( (mg.tracks&2)==0)
105           {
106           i=mg_peak_ypix[pa];
107           if(i<mg_ymax)i=mg_ymax;
108           if(ya < 0)
109             {
110             ya=i;
111             yb=i;
112             }
113           else
114             {
115             if(i>ya)ya=i;
116             if(i<yb)yb=i;
117             }
118           k=mg_peak_ypix[m];
119           if(k>ya)ya=k;
120           if(k<yb)yb=k;
121           lir_line(j-1,k,j,i,0);
122           }
123         i=yb;
124         while(i <= ya)
125           {
126           if( mg_behind_meter[i] != 0)lir_setpixel(j,i,mg_behind_meter[i]);
127           i++;
128           }
129         pa=m;
130         m=(m+mg_mask)&mg_mask;
131         }
132       }
133     else
134       {
135       for(j=mgw_p; j>=mg_first_xpixel; j--)
136         {
137         ya=-1;
138         if( (mg.tracks&1)==0)
139           {
140           i=mg_rms_ypix[2*pa];
141           ya=i;
142           yb=i;
143           k=mg_rms_ypix[2*m];
144           if(k>ya)ya=k;
145           if(k<yb)yb=k;
146           lir_line(j-1,k,j,i,0);
147           i=mg_rms_ypix[2*pa+1];
148           if(i>ya)ya=i;
149           if(i<yb)yb=i;
150           k=mg_rms_ypix[2*m+1];
151           if(k>ya)ya=k;
152           if(k<yb)yb=k;
153           lir_line(j-1,k,j,i,0);
154           }
155         if( (mg.tracks&2)==0)
156           {
157           i=mg_peak_ypix[2*pa];
158           if(ya < 0)
159             {
160             ya=i;
161             yb=i;
162             }
163           else
164             {
165             if(i>ya)ya=i;
166             if(i<yb)yb=i;
167             }
168           k=mg_peak_ypix[2*m];
169           if(k>ya)ya=k;
170           if(k<yb)yb=k;
171           lir_line(j-1,k,j,i,0);
172           i=mg_peak_ypix[2*pa+1];
173           if(i>ya)ya=i;
174           if(i<yb)yb=i;
175           k=mg_peak_ypix[2*m+1];
176           if(k<mg_ymax)k=mg_ymax;
177           if(k>ya)ya=k;
178           if(k<yb)yb=k;
179           lir_line(j-1,k,j,i,0);
180           }
181         i=yb;
182         while(i <= ya)
183           {
184           if( mg_behind_meter[i] != 0)lir_setpixel(j,i,mg_behind_meter[i]);
185           i++;
186           }
187         pa=m;
188         m=(m+mg_mask)&mg_mask;
189         }
190       }
191 // We want to place the last point at mg_last_xpixel-n in the graph.
192 // The number of points is thus mg_last_xpixel-n-mg_first_xpixel.
193 // Set mg_px and mgw_p accordingly.
194     if(n < 0.2*(mg_last_xpixel-mg_first_xpixel) )
195       {
196 //  n=(local_mg_pa-mg_px+mg_size)&mg_mask;
197 //  n+=mgw_p-mg_last_xpixel;
198       n=0.2*(mg_last_xpixel-mg_first_xpixel);
199       }
200     if(n >=mg_last_xpixel-mg_first_xpixel)
201       {
202       n=0.8*(mg_last_xpixel-mg_first_xpixel);
203       }
204     mgw_p=mg_first_xpixel;
205     mg_px=(local_mg_pa-(mg_last_xpixel-n-mg_first_xpixel)+mg_size)&mg_mask;
206     }
207   m=(mg_px+mg_mask)&mg_mask;
208   if(sw_onechan)
209     {
210     i=mg_ymin-(mg.yzero+mg.ygain*mg_rms_meter[m]);
211     if(i<mg_ymax)i=mg_ymax;
212     if(i>mg_ymin)i=mg_ymin;
213     mg_rms_ypix[m]=i;
214     i=mg_ymin-(mg.yzero+mg.ygain*mg_peak_meter[m]);
215     if(i<mg_ymax)i=mg_ymax;
216     if(i>mg_ymin)i=mg_ymin;
217     mg_peak_ypix[m]=i;
218     }
219   else
220     {
221     i=mg_ymin-(mg.yzero+mg.ygain*mg_rms_meter[2*m]);
222     if(i<mg_ymax)i=mg_ymax;
223     if(i>mg_ymin)i=mg_ymin;
224     mg_rms_ypix[2*m]=i;
225     i=mg_ymin-(mg.yzero+mg.ygain*mg_peak_meter[2*m]);
226     if(i<mg_ymax)i=mg_ymax;
227     if(i>mg_ymin)i=mg_ymin;
228     mg_peak_ypix[2*m]=i;
229     i=mg_ymin-(mg.yzero+mg.ygain*mg_rms_meter[2*m+1]);
230     if(i<mg_ymax)i=mg_ymax;
231     if(i>mg_ymin)i=mg_ymin;
232     mg_rms_ypix[2*m+1]=i;
233     i=mg_ymin-(mg.yzero+mg.ygain*mg_peak_meter[2*m+1]);
234     if(i<mg_ymax)i=mg_ymax;
235     if(i>mg_ymin)i=mg_ymin;
236     mg_peak_ypix[2*m+1]=i;
237     }
238   if(sw_onechan)
239     {
240     while(mg_px != local_mg_pa)
241       {
242       if( (mg.tracks&1)==0)
243         {
244         i=mg_ymin-(mg.yzero+mg.ygain*mg_rms_meter[mg_px]);
245         if(i<mg_ymax)i=mg_ymax;
246         if(i>mg_ymin)i=mg_ymin;
247         mg_rms_ypix[mg_px]=i;
248         k=mg_rms_ypix[m];
249         lir_line(mgw_p-1,k,mgw_p,i,14);
250         }
251       if( (mg.tracks&2)==0)
252         {
253         i=mg_ymin-(mg.yzero+mg.ygain*mg_peak_meter[mg_px]);
254         if(i<mg_ymax)i=mg_ymax;
255         if(i>mg_ymin)i=mg_ymin;
256         mg_peak_ypix[mg_px]=i;
257         k=mg_peak_ypix[m];
258         lir_line(mgw_p-1,k,mgw_p,i,15);
259         }
260       m=mg_px;
261       mg_px=(mg_px+1)&mg_mask;
262       mgw_p++;
263       }
264     }
265   else
266     {
267     while(mg_px != local_mg_pa)
268       {
269       if( (mg.tracks&1)==0)
270         {
271         i=mg_ymin-(mg.yzero+mg.ygain*mg_rms_meter[2*mg_px]);
272         if(i<mg_ymax)i=mg_ymax;
273         if(i>mg_ymin)i=mg_ymin;
274         mg_rms_ypix[2*mg_px]=i;
275         k=mg_rms_ypix[2*m];
276         lir_line(mgw_p-1,k,mgw_p,i,11);
277         i=mg_ymin-(mg.yzero+mg.ygain*mg_rms_meter[2*mg_px+1]);
278         if(i<mg_ymax)i=mg_ymax;
279         if(i>mg_ymin)i=mg_ymin;
280         mg_rms_ypix[2*mg_px+1]=i;
281         k=mg_rms_ypix[2*m+1];
282         lir_line(mgw_p-1,k,mgw_p,i,12);
283         }
284       if( (mg.tracks&2)==0)
285         {
286         i=mg_ymin-(mg.yzero+mg.ygain*mg_peak_meter[2*mg_px]);
287         if(i<mg_ymax)i=mg_ymax;
288         if(i>mg_ymin)i=mg_ymin;
289         mg_peak_ypix[2*mg_px]=i;
290         k=mg_peak_ypix[2*m];
291         lir_line(mgw_p-1,k,mgw_p,i,10);
292         i=mg_ymin-(mg.yzero+mg.ygain*mg_peak_meter[2*mg_px+1]);
293         if(i<mg_ymax)i=mg_ymax;
294         if(i>mg_ymin)i=mg_ymin;
295         mg_peak_ypix[2*mg_px+1]=i;
296         k=mg_peak_ypix[2*m+1];
297         lir_line(mgw_p-1,k,mgw_p,i,13);
298         }
299       m=mg_px;
300       mg_px=(mg_px+1)&mg_mask;
301       mgw_p++;
302       }
303     }
304   }
305 }
306 
afc_cursor(void)307 void afc_cursor(void)
308 {
309 int i, j;
310 if(mix1_fq_mid[fftx_nx] < 0)return;
311 j=0.5+hg_first_xpixel+(mix1_fq_mid[fftx_nx]-hg_first_fq)/hg_hz_per_pixel;
312 if(j < hg_first_xpixel)j = hg_first_xpixel;
313 if(j > hg_last_xpixel)j = hg_last_xpixel;
314 if(afc_curx != j || afc_old_cursor_color != afc_cursor_color)
315   {
316   hide_mouse(j,j,hg_cury0,hg_cury2);
317   if(afc_curx > 0)
318     {
319     hide_mouse(afc_curx,afc_curx,hg_cury0,hg_cury2);
320     if(afc_curx == hg_center)
321       {
322       for(i=hg_cury0; i<hg_cury2; i++)
323         {
324         lir_setpixel(afc_curx,i,8);
325         lir_setpixel(j,i,afc_cursor_color);
326         }
327       }
328     else
329       {
330       for(i=hg_cury0; i<hg_cury2; i++)
331         {
332         lir_setpixel(afc_curx,i,hg_background[i]);
333         lir_setpixel(j,i,afc_cursor_color);
334         }
335       }
336     }
337   else
338     {
339     for(i=hg_cury0; i<hg_cury2; i++)
340       {
341       lir_setpixel(j,i,afc_cursor_color);
342       }
343     }
344   }
345 afc_curx=j;
346 afc_old_cursor_color = afc_cursor_color;
347 }
348 
349 
show_coherent(void)350 void show_coherent(void)
351 {
352 char s[80];
353 int i, ia, ix, iy, n;
354 float t2, t4;
355 float sellim_correction;
356 sellim_correction=1;
357 if(genparm[SECOND_FFT_ENABLE] != 0)
358   {
359   if(!swfloat)
360     {
361     ia=mix1_selfreq[0]*fftx_points_per_hz;
362     if(ia > 0)
363       {
364       ia/=fft2_to_fft1_ratio;
365       if(liminfo[ia]>0)
366         {
367         sellim_correction=1/pow(liminfo[ia],2.0);
368         }
369       }
370     }
371   }
372 hide_mouse(cg_old_x1, cg_old_x2, cg_old_y1, cg_old_y2);
373 for(iy=0; iy<cg_size; iy++)
374   {
375   n=iy*cg_size;
376   for(ix=0; ix<cg_size; ix++)
377     {
378     i=1+cg_map[n+ix];
379     cg_map[n+ix]*=0.8;
380     if(i >= MAX_COLOR_SCALE)i=MAX_COLOR_SCALE-1;
381     lir_fillbox(cg_old_x1+1+3*ix,cg_old_y1+1+3*iy,3,3,color_scale[i]);
382     }
383   }
384 lir_line(cg_x0,cg_old_y1,cg_x0,cg_y1,8);
385 if(kill_all_flag) return;
386 lir_hline(cg_old_x1+1,cg_y0,cg_old_x2-1,8);
387 if(kill_all_flag) return;
388 lir_line(cg_x0,cg_y0,cg_chirpx,cg_chirpy,14);
389 if(kill_all_flag) return;
390 t2=0;
391 t4=0;
392 ia=basblock_pa;
393 for(i=0; i<basblock_hold_points; i++)
394   {
395   t4+=basblock_avgpower[ia];
396   if(t2<basblock_maxpower[ia])t2=basblock_maxpower[ia];
397   ia=(ia+basblock_mask)&basblock_mask;
398   }
399 t4/=basblock_hold_points;
400 s_meter_average_power=10*log10(t4*baseband_pwrfac*sellim_correction);
401 t2*=baseband_pwrfac;
402 sprintf(s,"%f  ",s_meter_average_power);
403 // Make sure we do not write outside our screen area.
404 s[COH_SIDE-2]=0;
405 lir_pixwrite(cg_old_x1+2*text_width,cg_old_y2-text_height,s);
406 if(s_meter_avgnum >=0)
407   {
408   s_meter_avg_filled_flag=TRUE;
409   s_meter_avgnum++;
410   s_meter_avg+=t4;
411   t4=s_meter_avg/s_meter_avgnum;
412   sprintf(s,"%f",10*log10(t4*baseband_pwrfac));
413   s[COH_SIDE]=0;
414   lir_pixwrite(cg_old_x1+1,cg_old_y2-4*text_height,s);
415   sprintf(s,"%3d ",s_meter_avgnum);
416   s[COH_SIDE]=0;
417   lir_pixwrite(cg_old_x1+1,cg_old_y2-5*text_height,s);
418   }
419 else
420   {
421   if(s_meter_avg_filled_flag==TRUE)
422     {
423     lir_fillbox(cg_old_x1+1,cg_old_y2-5*text_height,3*cg_size,2*text_height,0);
424     s_meter_avg_filled_flag=FALSE;
425     }
426   }
427 s_meter_fast_attack_slow_decay=10*log10(t2*sellim_correction);
428 sprintf(s,"%.2f  ",s_meter_fast_attack_slow_decay);
429 s[COH_SIDE-2]=0;
430 lir_pixwrite(cg_old_x1+2*text_width,cg_old_y2-2*text_height,s);
431 t2*=sellim_correction;
432 if(s_meter_peak_hold < t2)
433   {
434   s_meter_peak_hold=t2;
435   lir_pixwrite(cg_old_x1+2*text_width,cg_old_y2-3*text_height,s);
436   }
437 }
438 
update_txtest(int xpix,int new_y2)439 void update_txtest(int xpix,int new_y2 )
440 {
441 int new_y1, old_y1, old_y2;
442 int ia, ib;
443 char bkg_color;
444 old_y2=fft1_spectrum[xpix];
445 fft1_old_spectrum[xpix]=old_y2;
446 if(new_y2 < 0)new_y2=0;
447 new_y2=wg.ybottom-1-new_y2;
448 if(new_y2 < wg.yborder+1)new_y2=wg.yborder+1;
449 if(xpix != wg_first_xpixel)
450   {
451   new_y1=fft1_spectrum[xpix-1];
452   old_y1=fft1_old_spectrum[xpix-1];
453   }
454 else
455   {
456   new_y1=new_y2;
457   old_y1=new_y2;
458   }
459 if( new_y2 != old_y2 || new_y1 != old_y1)
460   {
461   if(old_y1 > old_y2)
462     {
463     ia=old_y2;
464     ib=old_y1;
465     }
466   else
467     {
468     ib=old_y2;
469     ia=old_y1;
470     }
471   while(ia <= ib)
472     {
473     bkg_color=wg_background[ia];
474     lir_setpixel(xpix,ia,bkg_color);
475     ia++;
476     }
477   if(new_y1 > new_y2)
478     {
479     ia=new_y2;
480     ib=new_y1;
481     }
482   else
483     {
484     ib=new_y2;
485     ia=new_y1;
486     }
487   while(ia <= ib)
488     {
489     lir_setpixel(xpix,ia,TXTEST_NARROW_COLOR);
490     ia++;
491     }
492   fft1_spectrum[xpix]=new_y2;
493   }
494 }
495 
update_txpeak(int xpix,int new_y2)496 void update_txpeak(int xpix,int new_y2 )
497 {
498 int new_y1, old_y1, old_y2;
499 int ia, ib;
500 char bkg_color;
501 old_y2=txtest_ypeak[xpix];
502 txtest_old_ypeak[xpix]=old_y2;
503 if(new_y2 < 0)new_y2=0;
504 new_y2=wg.ybottom-1-new_y2;
505 if(new_y2 < wg.yborder+1)new_y2=wg.yborder+1;
506 if(old_y2 < new_y2)new_y2=old_y2;
507 if(xpix == txtest_first_xpix)
508   {
509   bkg_color=wg_background[old_y2];
510   if(old_y2 == txtest_ypeak_decay[xpix])bkg_color=TXTEST_PEAK_DECAY_COLOR;
511   lir_setpixel(xpix,old_y2,bkg_color);
512   txtest_ypeak[xpix]=new_y2;
513   lir_setpixel(xpix,new_y2,TXTEST_PEAK_POWER_COLOR);
514   return;
515   }
516 new_y1=txtest_ypeak[xpix-1];
517 old_y1=txtest_old_ypeak[xpix-1];
518 if( new_y2 != old_y2 || new_y1 != old_y1 || txtest_peak_redraw ==0)
519   {
520   if(old_y1 > old_y2)
521     {
522     ia=old_y2;
523     ib=old_y1;
524     }
525   else
526     {
527     ib=old_y2;
528     ia=old_y1;
529     }
530   while(ia <= ib)
531     {
532     bkg_color=wg_background[ia];
533     if(ia == txtest_ypeak_decay[xpix])bkg_color=TXTEST_PEAK_DECAY_COLOR;
534     lir_setpixel(xpix,ia,bkg_color);
535     ia++;
536     }
537   if(new_y1 > new_y2)
538     {
539     ia=new_y2;
540     ib=new_y1;
541     }
542   else
543     {
544     ib=new_y2;
545     ia=new_y1;
546     }
547   while(ia <= ib)
548     {
549     lir_setpixel(xpix,ia,TXTEST_PEAK_POWER_COLOR);
550     ia++;
551     }
552   txtest_ypeak[xpix]=new_y2;
553   }
554 txtest_peak_redraw++;
555 if(txtest_peak_redraw > TXTEST_PEAK_REDRAW_COUNT)
556   {
557   txtest_peak_redraw=0;
558   }
559 }
560 
update_txpeak_decay(int xpix,int new_y2)561 void update_txpeak_decay(int xpix,int new_y2 )
562 {
563 int new_y1, old_y1, old_y2;
564 int ia, ib;
565 char bkg_color;
566 old_y2=txtest_ypeak_decay[xpix];
567 txtest_old_ypeak_decay[xpix]=old_y2;
568 if(new_y2 < 0)new_y2=0;
569 new_y2=wg.ybottom-1-new_y2;
570 if(new_y2 < wg.yborder+1)new_y2=wg.yborder+1;
571 if(xpix != txtest_first_xpix)
572   {
573   new_y1=txtest_ypeak_decay[xpix-1];
574   old_y1=txtest_old_ypeak_decay[xpix-1];
575   }
576 else
577   {
578   new_y1=new_y2;
579   old_y1=new_y2;
580   }
581 if( new_y2 != old_y2 || new_y1 != old_y1)
582   {
583   if(old_y1 > old_y2)
584     {
585     ia=old_y2;
586     ib=old_y1;
587     }
588   else
589     {
590     ib=old_y2;
591     ia=old_y1;
592     }
593   while(ia <= ib)
594     {
595     bkg_color=wg_background[ia];
596     if(ia == txtest_ypeak[xpix])bkg_color=TXTEST_PEAK_POWER_COLOR;
597     lir_setpixel(xpix,ia,bkg_color);
598     ia++;
599     }
600   if(new_y1 > new_y2)
601     {
602     ia=new_y2;
603     ib=new_y1;
604     }
605   else
606     {
607     ib=new_y2;
608     ia=new_y1;
609     }
610   while(ia <= ib)
611     {
612     lir_setpixel(xpix,ia,TXTEST_PEAK_DECAY_COLOR);
613     ia++;
614     }
615   txtest_ypeak_decay[xpix]=new_y2;
616   }
617 }
618 
update_txavg(int xpix,int new_y2)619 void update_txavg(int xpix,int new_y2 )
620 {
621 int new_y1, old_y1, old_y2;
622 int ia, ib;
623 char bkg_color;
624 old_y2=txtest_yavg[xpix];
625 txtest_old_yavg[xpix]=old_y2;
626 if(new_y2 < 0)new_y2=0;
627 new_y2=wg.ybottom-1-new_y2;
628 if(new_y2 < wg.yborder+1)new_y2=wg.yborder+1;
629 if(xpix != txtest_first_xpix)
630   {
631   new_y1=txtest_yavg[xpix-1];
632   old_y1=txtest_old_yavg[xpix-1];
633   }
634 else
635   {
636   new_y1=new_y2;
637   old_y1=new_y2;
638   }
639 if( new_y2 != old_y2 || new_y1 != old_y1)
640   {
641   if(old_y1 > old_y2)
642     {
643     ia=old_y2;
644     ib=old_y1;
645     }
646   else
647     {
648     ib=old_y2;
649     ia=old_y1;
650     }
651   while(ia <= ib)
652     {
653     bkg_color=wg_background[ia];
654     if(ia == txtest_ypeak_decay[xpix])bkg_color=TXTEST_PEAK_DECAY_COLOR;
655     if(ia == txtest_ypeak[xpix])bkg_color=TXTEST_PEAK_POWER_COLOR;
656     lir_setpixel(xpix,ia,bkg_color);
657     ia++;
658     }
659   if(new_y1 > new_y2)
660     {
661     ia=new_y2;
662     ib=new_y1;
663     }
664   else
665     {
666     ib=new_y2;
667     ia=new_y1;
668     }
669   while(ia <= ib)
670     {
671     lir_setpixel(xpix,ia,TXTEST_WIDE_AVERAGE_COLOR);
672     ia++;
673     }
674   txtest_yavg[xpix]=new_y2;
675   }
676 }
677 
show_txtest_spectrum(void)678 void show_txtest_spectrum(void)
679 {
680 int j, ia;
681 float fxpix;
682 float yval_avg, der_avg, next_y, next_y_avg;
683 float yval_decay, der_decay, next_y_decay;
684 int i,k,m,mm, new_y, xpix;
685 float yval,der,t1;
686 // Draw the normal fft1 spectrumn with  lines.
687 hide_mouse(wg_first_xpixel, wg_last_xpixel, wg.yborder, wg.ybottom);
688 if(wg.xpoints_per_pixel == 1 || wg.pixels_per_xpoint == 1)
689   {
690   i=wg.first_xpoint+wg_first_xpixel-wg_first_xpixel;
691   for(xpix=wg_first_xpixel; xpix < wg_last_xpixel; xpix++)
692     {
693     if(fft1_slowsum[i] > 0.5)
694       {
695       update_txtest(xpix,(int)(wg_yfac_log*log10(fft1_slowsum[i]*wg_yfac_power)));
696       }
697     i++;
698     }
699   }
700 else
701   {
702   if(wg.xpoints_per_pixel == 0)
703     {
704 // There are more pixels than data points so we must interpolate.
705     i=wg.first_xpoint+(wg_first_xpixel-wg_first_xpixel)/wg.pixels_per_xpoint;
706     if(fft1_slowsum[i] > 0.5)
707       {
708       new_y=wg_yfac_log*log10(fft1_slowsum[i]*wg_yfac_power);
709       if(i == wg.first_xpoint)
710         {
711         update_txtest(wg_first_xpixel,new_y);
712         }
713       }
714     else
715       {
716       new_y=0;
717       }
718     yval=new_y;
719     i++;
720     for(xpix=wg_first_xpixel;
721         xpix<wg_last_xpixel; xpix+=wg.pixels_per_xpoint)
722       {
723       m=xpix+wg.pixels_per_xpoint/2;
724       if(fft1_slowsum[i] > 0.5)
725         {
726         t1=wg_yfac_log*log10(fft1_slowsum[i]*wg_yfac_power);
727         der=(t1-yval)/wg.pixels_per_xpoint;
728         for(k=xpix+1; k<=m; k++)
729           {
730           yval=yval+der;
731           new_y=yval;
732           update_txtest(k,new_y);
733           }
734         }
735       else
736         {
737         t1=0;
738         yval=0;
739         der=0;
740         }
741       mm=xpix+wg.pixels_per_xpoint;
742       for(k=m+1; k<=mm; k++)
743         {
744         yval=yval+der;
745         new_y=yval;
746         update_txtest(k,new_y);
747         }
748       i++;
749       yval=t1;
750       }
751     }
752   else
753     {
754 // There is more than one data point for each pixel.
755 // Slide a triangular filter across the spectrum to make it
756 // smoother before resampling.
757     i=wg.first_xpoint+(wg_first_xpixel-wg_first_xpixel)*wg.xpoints_per_pixel;
758     for(xpix=wg_first_xpixel; xpix<wg_last_xpixel; xpix++)
759       {
760       t1=fft1_slowsum[i]*wg.xpoints_per_pixel;
761       for(k=1; k<wg.xpoints_per_pixel; k++)
762         {
763         t1+=(fft1_slowsum[i+k]+fft1_slowsum[i-k])*(wg.xpoints_per_pixel-k);
764         }
765       if(t1 > 0.5)
766         {
767         new_y=wg_yfac_log*log10(t1*wg_yfac_power);
768         update_txtest(xpix,new_y);
769         }
770       i+=wg.xpoints_per_pixel;
771       }
772     }
773   }
774 // Make the average spectrum.
775 if(txtest_no_of_segs==0 || txtest_pixinc==0)return;
776 txtest_last_xpix=txtest_first_xpix+(txtest_no_of_segs-1)*txtest_pixinc;
777 xpix=txtest_first_xpix;
778 fxpix=xpix;
779 // There are typically more pixels than data points so we must interpolate.
780 ia=0;
781 if(txtest_peak_power[0] > 0.5)
782   {
783   yval=wg_yfac_log*log10(txtest_peak_power[0]);
784   }
785 else
786   {
787   yval=0;
788   }
789 if(txtest_peak_power_decay[0] > 0.5)
790   {
791   yval_decay=wg_yfac_log*log10(txtest_peak_power_decay[0]);
792   }
793 else
794   {
795   yval_decay=0;
796   }
797 if(txtest_powersum[0] > 0.5)
798   {
799   yval_avg=wg_yfac_log*log10(txtest_powersum[0]);
800   }
801 else
802   {
803   yval_avg=0;
804   }
805 if(txtest_decayfac1 < 0.5)
806   {
807   update_txpeak_decay(xpix,yval_decay);
808   }
809 update_txavg(xpix,yval_avg);
810 update_txpeak(xpix,yval);
811 while( xpix < txtest_last_xpix)
812   {
813   ia++;
814   m=fxpix+txtest_pixinc/2;
815   fxpix+=txtest_pixinc;
816   j=fxpix;
817   if(txtest_peak_power[ia] > 0.5)
818     {
819     next_y=wg_yfac_log*log10(txtest_peak_power[ia]);
820     }
821   else
822     {
823     next_y=0;
824     }
825   der=(next_y-yval)/(j-xpix);
826   if(txtest_peak_power_decay[ia] > 0.5)
827     {
828     next_y_decay=wg_yfac_log*log10(txtest_peak_power_decay[ia]);
829     }
830   else
831     {
832     next_y_decay=0;
833     }
834   der_decay=(next_y_decay-yval_decay)/(j-xpix);
835   if(txtest_powersum[ia] > 0.5)
836     {
837     next_y_avg=wg_yfac_log*log10(txtest_powersum[ia]);
838     }
839   else
840     {
841     next_y_avg=0;
842     }
843   der_avg=(next_y_avg-yval_avg)/(j-xpix);
844   for(k=xpix; k<m; k++)
845     {
846     yval=yval+der;
847     yval_avg=yval_avg+der_avg;
848     update_txavg(k,yval_avg);
849     if(txtest_decayfac1 < 0.5)
850       {
851       yval_decay=yval_decay+der_decay;
852       update_txpeak_decay(k,yval_decay);
853       }
854     update_txpeak(k,yval);
855     }
856   xpix=fxpix;
857   yval=next_y-der*(xpix-m);
858   yval_avg=next_y_avg-der_avg*(xpix-m);
859   yval_decay=next_y_decay-der_decay*(xpix-m);
860   for(k=m; k<xpix; k++)
861     {
862     yval=yval+der;
863     yval_avg=yval_avg+der_avg;
864     update_txavg(k,yval_avg);
865     if(txtest_decayfac1 < 0.5)
866       {
867       yval_decay=yval_decay+der_decay;
868       update_txpeak_decay(k,yval_decay);
869       }
870     update_txpeak(k,yval);
871     }
872   yval=next_y;
873   yval_avg=next_y_avg;
874   yval_decay=next_y_decay;
875   }
876 }
877 
update_wg(int xpix,int new_y,char spk_color)878 void update_wg(int xpix,int new_y, char spk_color )
879 {
880 int i, old_y, sw;
881 char bkg_color;
882 old_y=fft1_spectrum[xpix];
883 if(new_y < 0)new_y=0;
884 new_y=wg.ybottom-1-new_y;
885 if(new_y < wg.yborder+1)new_y=wg.yborder+1;
886 sw=0;
887 if(old_y > 0)
888   {
889   if(spk_color !=15)sw=1;
890   }
891 else
892   {
893   old_y=-old_y;
894   if(spk_color !=12)sw=1;
895   }
896 if(new_y!=old_y || sw!=0)
897   {
898   bkg_color=wg_background[old_y];
899   if( (ui.network_flag&NET_RX_OUTPUT) != 0)
900     {
901     for(i=0; i<MAX_FREQLIST; i++)
902       {
903       if(xpix == netfreq_curx[i])
904         {
905         bkg_color=MIX1_NETCUR_COLOR;
906         }
907       }
908     }
909   if(xpix == mix1_curx[0])
910     {
911     bkg_color=MIX1_MAINCUR_COLOR;
912     }
913   else
914     {
915     for(i=1; i<genparm[MIX1_NO_OF_CHANNELS]; i++)
916       {
917       if(xpix == mix1_curx[i])
918         {
919         bkg_color=MIX1_SUBCUR_COLOR;
920         }
921       }
922     }
923   lir_setpixel(xpix,old_y,bkg_color);
924   lir_setpixel(xpix,new_y,spk_color);
925   if(spk_color != 15)new_y=-new_y;
926   fft1_spectrum[xpix]=new_y;
927   }
928 }
929 
update_corr_wg(int xpix,int new_y)930 void update_corr_wg(int xpix,int new_y)
931 {
932 int i, old_y;
933 char bkg_color;
934 old_y=fft1_corr_spectrum[xpix];
935 if(new_y < 0)new_y=0;
936 new_y=wg.ybottom-1-new_y;
937 if(new_y < wg.yborder+1)new_y=wg.yborder+1;
938 if(new_y!=old_y)
939   {
940   bkg_color=wg_background[old_y];
941   if( (ui.network_flag&NET_RX_OUTPUT) != 0)
942     {
943     for(i=0; i<MAX_FREQLIST; i++)
944       {
945       if(xpix == netfreq_curx[i])
946         {
947         bkg_color=MIX1_NETCUR_COLOR;
948         }
949       }
950     }
951   if(xpix == mix1_curx[0])
952     {
953     bkg_color=MIX1_MAINCUR_COLOR;
954     }
955   else
956     {
957     for(i=1; i<genparm[MIX1_NO_OF_CHANNELS]; i++)
958       {
959       if(xpix == mix1_curx[i])
960         {
961         bkg_color=MIX1_SUBCUR_COLOR;
962         }
963       }
964     }
965   lir_setpixel(xpix,old_y,bkg_color);
966   lir_setpixel(xpix,new_y,14);
967   fft1_corr_spectrum[xpix]=new_y;
968   }
969 }
970 
update_wg_spectrum(void)971 void update_wg_spectrum(void)
972 {
973 int i,m,mm, new_y, xpix;
974 int k, num, xpos, color;
975 float yval,der,t1,t2;
976 char cl;
977 // fft1_spectrum is the y-value currently on screen.
978 // Calculate updated values and move the corresponding bright
979 // pixel in case the value has changed
980 hide_mouse(wg_first_xpixel, wg_last_xpixel, wg.yborder, wg.ybottom);
981 if(rx_mode == MODE_TXTEST)
982   {
983   show_txtest_spectrum();
984   return;
985   }
986 for(num=0; num<genparm[MIX1_NO_OF_CHANNELS]; num++)
987   {
988   if(new_mix1_curx[num]!=mix1_curx[num])
989     {
990     xpos=new_mix1_curx[num];
991     if(xpos!=-1)
992       {
993       if(num==0)
994         {
995         color=MIX1_MAINCUR_COLOR;
996         }
997       else
998         {
999         color=MIX1_SUBCUR_COLOR;
1000         }
1001       lir_line(xpos,wg.ybottom-1,xpos,wg.yborder+1,color);
1002       if(kill_all_flag) return;
1003       }
1004     xpos=mix1_curx[num];
1005     if(xpos!=-1)
1006       {
1007       for(i=wg.yborder+1; i<wg.ybottom; i++)
1008         {
1009         lir_setpixel(xpos,i, wg_background[i]);
1010         }
1011       }
1012     mix1_curx[num]=new_mix1_curx[num];
1013     }
1014   }
1015 if( (ui.network_flag&NET_RX_OUTPUT) != 0)
1016   {
1017   for(num=0; num<MAX_FREQLIST; num++)
1018     {
1019     if(new_netfreq_curx[num]!=netfreq_curx[num])
1020       {
1021       xpos=new_netfreq_curx[num];
1022       if(xpos!=-1)
1023         {
1024         lir_line(xpos,wg.ybottom-1,xpos,wg.yborder+1,MIX1_NETCUR_COLOR);
1025         if(kill_all_flag) return;
1026         }
1027      xpos=netfreq_curx[num];
1028      if(xpos!=-1)
1029         {
1030         for(i=wg.yborder+1; i<wg.ybottom; i++)
1031           {
1032           lir_setpixel(xpos,i, wg_background[i]);
1033           }
1034         }
1035       netfreq_curx[num]=new_netfreq_curx[num];
1036       }
1037     }
1038   }
1039 if(wg.xpoints_per_pixel == 1 || wg.pixels_per_xpoint == 1)
1040   {
1041   i=wg.first_xpoint+wg_first_xpixel-wg_first_xpixel;
1042   for(xpix=wg_first_xpixel; xpix<=wg_last_xpixel; xpix++)
1043     {
1044     if(liminfo[i]==0)
1045       {
1046       cl=15;
1047       }
1048     else
1049       {
1050       cl=12;
1051       }
1052     if(fft1_slowsum[i] > 0.5)
1053       {
1054       update_wg(xpix,(int)(wg_yfac_log*log10(fft1_slowsum[i]*wg_yfac_power)),cl);
1055       }
1056     i++;
1057     }
1058   }
1059 else
1060   {
1061   if(wg.xpoints_per_pixel == 0)
1062     {
1063 // There are more pixels than data points so we must interpolate.
1064     i=wg.first_xpoint+(wg_first_xpixel-wg_first_xpixel)/wg.pixels_per_xpoint;
1065     if(fft1_slowsum[i] > 0.5)
1066       {
1067       new_y=wg_yfac_log*log10(fft1_slowsum[i]*wg_yfac_power);
1068       }
1069     else
1070       {
1071       new_y=0;
1072       }
1073     yval=new_y;
1074     if(liminfo[i]==0)
1075       {
1076       cl=15;
1077       }
1078     else
1079       {
1080       cl=12;
1081       }
1082     i++;
1083     update_wg(wg_first_xpixel,new_y,cl);
1084     for(xpix=wg_first_xpixel;
1085         xpix<wg_last_xpixel; xpix+=wg.pixels_per_xpoint)
1086       {
1087       if(fft1_slowsum[i] > 0.5)
1088         {
1089         t1=wg_yfac_log*log10(fft1_slowsum[i]*wg_yfac_power);
1090         }
1091       else
1092         {
1093         t1=0;
1094         }
1095       der=(t1-yval)/wg.pixels_per_xpoint;
1096       m=xpix+wg.pixels_per_xpoint/2;
1097       if(m>wg_last_xpixel)m=wg_last_xpixel;
1098       for(k=xpix+1; k<=m; k++)
1099         {
1100         yval=yval+der;
1101         new_y=yval;
1102         update_wg(k,new_y,cl);
1103         }
1104       if(liminfo[i]==0)
1105         {
1106         cl=15;
1107         }
1108       else
1109         {
1110         cl=12;
1111         }
1112       mm=xpix+wg.pixels_per_xpoint;
1113       if(mm>wg_last_xpixel)mm=wg_last_xpixel;
1114       for(k=m+1; k<=mm; k++)
1115         {
1116         yval=yval+der;
1117         new_y=yval;
1118         update_wg(k,new_y,cl);
1119         }
1120       i++;
1121       yval=t1;
1122       }
1123     }
1124   else
1125     {
1126 // There is more than one data point for each pixel.
1127 // Slide a triangular filter across the spectrum to make it
1128 // smoother before resampling.
1129     i=wg.first_xpoint+(wg_first_xpixel-wg_first_xpixel)*wg.xpoints_per_pixel;
1130     for(xpix=wg_first_xpixel; xpix<wg_last_xpixel; xpix++)
1131       {
1132       if(liminfo[i]==0)
1133         {
1134         cl=15;
1135         }
1136       else
1137         {
1138         cl=12;
1139         }
1140       t1=fft1_slowsum[i]*wg.xpoints_per_pixel;
1141       for(k=1; k<wg.xpoints_per_pixel; k++)
1142         {
1143         t1+=(fft1_slowsum[i+k]+fft1_slowsum[i-k])*(wg.xpoints_per_pixel-k);
1144         if(liminfo[i+k]!=0||liminfo[i-k]!=0)cl=12;
1145         }
1146       if(t1 > 0.5)
1147         {
1148         new_y=wg_yfac_log*log10(t1*wg_yfac_power);
1149         update_wg(xpix,new_y,cl);
1150         }
1151       i+=wg.xpoints_per_pixel;
1152       }
1153     }
1154   }
1155 if(fft1_correlation_flag)
1156   {
1157 // fft1_corr_spectrum is the y-value currently on screen.
1158 // Calculate updated values and move the corresponding bright
1159 // pixel in case the value has changed
1160 if(wg.xpoints_per_pixel == 1 || wg.pixels_per_xpoint == 1)
1161   {
1162   i=wg.first_xpoint+wg_first_xpixel-wg_first_xpixel;
1163   for(xpix=wg_first_xpixel; xpix<=wg_last_xpixel; xpix++)
1164     {
1165     t1=sqrt(fft1_slowcorr[2*i]*fft1_slowcorr[2*i]+
1166        fft1_slowcorr[2*i+1]*fft1_slowcorr[2*i+1]);
1167     if(t1 > 0.5)
1168       {
1169       update_corr_wg(xpix,(int)(wg_yfac_log*log10(t1*wg_yfac_power)));
1170       }
1171     i++;
1172     }
1173   }
1174 else
1175   {
1176   if(wg.xpoints_per_pixel == 0)
1177     {
1178 // There are more pixels than data points so we must interpolate.
1179     i=wg.first_xpoint+(wg_first_xpixel-wg_first_xpixel)/wg.pixels_per_xpoint;
1180     t1=sqrt(fft1_slowcorr[2*i]*fft1_slowcorr[2*i]+
1181             fft1_slowcorr[2*i+1]*fft1_slowcorr[2*i+1]);
1182     if(t1 > 0.5)
1183       {
1184       new_y=wg_yfac_log*log10(t1*wg_yfac_power);
1185       }
1186     else
1187       {
1188       new_y=0;
1189       }
1190     yval=new_y;
1191     i++;
1192     update_corr_wg(wg_first_xpixel,new_y);
1193     for(xpix=wg_first_xpixel;
1194         xpix<wg_last_xpixel; xpix+=wg.pixels_per_xpoint)
1195       {
1196       t1=sqrt(fft1_slowcorr[2*i]*fft1_slowcorr[2*i]+
1197               fft1_slowcorr[2*i+1]*fft1_slowcorr[2*i+1]);
1198       if(t1 > 0.5)
1199         {
1200         t1=wg_yfac_log*log10(t1*wg_yfac_power);
1201         }
1202       else
1203         {
1204         t1=0;
1205         }
1206       der=(t1-yval)/wg.pixels_per_xpoint;
1207       m=xpix+wg.pixels_per_xpoint/2;
1208       if(m>wg_last_xpixel)m=wg_last_xpixel;
1209       for(k=xpix+1; k<=m; k++)
1210         {
1211         yval=yval+der;
1212         new_y=yval;
1213         update_corr_wg(k,new_y);
1214         }
1215       mm=xpix+wg.pixels_per_xpoint;
1216       if(mm>wg_last_xpixel)mm=wg_last_xpixel;
1217       for(k=m+1; k<=mm; k++)
1218         {
1219         yval=yval+der;
1220         new_y=yval;
1221         update_corr_wg(k,new_y);
1222         }
1223       i++;
1224       yval=t1;
1225       }
1226     }
1227   else
1228     {
1229 // There is more than one data point for each pixel.
1230 // Form the average correlation.
1231     i=wg.first_xpoint+(wg_first_xpixel-wg_first_xpixel)*wg.xpoints_per_pixel;
1232     for(xpix=wg_first_xpixel; xpix<wg_last_xpixel; xpix++)
1233       {
1234       t1=0;
1235       t2=0;
1236       for(k=0; k<wg.xpoints_per_pixel; k++)
1237         {
1238         t1+=fft1_slowcorr[2*(i+k)  ];
1239         t2+=fft1_slowcorr[2*(i+k)+1];
1240         }
1241       t1=sqrt(t1*t1+t2*t2)*((float)wg.xpoints_per_pixel);
1242       if(t1 > 0.5)
1243         {
1244         update_corr_wg(xpix,(int)(wg_yfac_log*log10(t1*wg_yfac_power)));
1245         }
1246       i+=wg.xpoints_per_pixel;
1247       }
1248     }
1249   }
1250 
1251   }
1252 }
1253 
timf3_oscilloscope(void)1254 void timf3_oscilloscope(void)
1255 {
1256 int i,j,k,m,mm,pa,pb,mask;
1257 float t1,t2;
1258 hide_mouse(0,screen_width>>1,0,screen_height);
1259 mm=twice_rxchan;
1260 mask=timf3_mask;
1261 pa=timf3_ps;
1262 pb=(pa+timf3_osc_interval)&mask;
1263 t1=0;
1264 m=-1;
1265 while(pa != pb)
1266   {
1267   t2=timf3_float[pa  ]*timf3_float[pa  ];
1268   for(j=1;j<mm; j++)
1269     {
1270     t2+=timf3_float[pa+j]*timf3_float[pa+j];
1271     }
1272   if(t1<t2)
1273     {
1274     t1=t2;
1275     m=pa;
1276     }
1277   pa=(pa+mm)&mask;
1278   }
1279 if(m >= 0)
1280   {
1281   pa=(m-ui.rx_rf_channels*screen_width/4)&timf3_mask;
1282   pa&=-mm;
1283   for(j=0; j<mm; j++)
1284     {
1285     for(i=1; i<screen_width/2; i++)
1286       {
1287       lir_line(i-1,timf3_graph[mm*(i-1)+j],i,timf3_graph[mm*i+j],0);
1288       if(kill_all_flag) return;
1289       }
1290     }
1291   for(i=0; i<screen_width/2; i++)
1292     {
1293     for(j=0; j<mm; j++)
1294       {
1295       k=timf3_y0[mm-j]-timf3_float[pa+j]*bg.oscill_gain;
1296       if(k<0)k=0;
1297       if(k>=screen_height)k=screen_height-1;
1298       timf3_graph[mm*i+j]=k;
1299       }
1300     pa=(pa+mm)&timf3_mask;
1301     }
1302   for(j=0; j<mm; j++)
1303     {
1304     if(  (j&1)==0 )k=10; else k=13;
1305     for(i=1; i<screen_width/2; i++)
1306       {
1307       lir_line(i-1,timf3_graph[mm*(i-1)+j],i,timf3_graph[mm*i+j],k);
1308       if(kill_all_flag) return;
1309       }
1310     }
1311   }
1312 timf3_ps=(timf3_ps+timf3_osc_interval)&timf3_mask;
1313 }
1314 
hg_cursor(void)1315 void hg_cursor(void)
1316 {
1317 int i;
1318 float mfq;
1319 mfq=mix1_selfreq[0];
1320 if(mfq < 0)return;
1321 hg_center=0.5+hg_first_xpixel+(mfq-hg_first_fq)/hg_hz_per_pixel;
1322 for(i=hg_cury1; i<hg_cury2; i++)
1323   {
1324   if(hg_curx > 0)lir_setpixel(hg_curx,i,hg_background[i]);
1325   lir_setpixel(hg_center,i,8);
1326   }
1327 hg_curx=hg_center;
1328 }
1329 
1330 
fq_scale(int x1,int x2,int y,int first_xpixel,double first_frequency,float hz_per_pixel)1331 void fq_scale(int x1, int x2, int y, int first_xpixel,
1332              double first_frequency, float hz_per_pixel)
1333 {
1334 int i, j, k, m, numchar, unit_len;
1335 int xa,xb,xc,xd,ya,yb;
1336 char s[80];
1337 char *fmt={"%.1f"};
1338 float fq_xstep, fq_x;
1339 double fact, t1, fq_value, fq_valstep, fq_offset;
1340 // Try to get at least 3 frequency values on the scale.
1341 numchar=(x2-x1)/3-3;
1342 //Get the frequency of the first bin and the last bin.
1343 fq_offset=frequency_scale_offset_hz+first_frequency;
1344 t1=fq_offset+(x2-x1)*hz_per_pixel;
1345 // The maximum frequency is 10GHz that needs 11+2 characters for
1346 // a resolution of 1 Hz
1347 if(numchar > 13)numchar=13;
1348 if(t1 < 1000000000 && numchar > 12)numchar=12;
1349 if(t1 < 10000000 && numchar > 11)numchar=11;
1350 if(t1 < 1000000 && numchar > 10)numchar=10;
1351 if(numchar < 7)numchar=7;
1352 fq_valstep=numchar*hz_per_pixel*text_width;
1353 j=adjust_scale(&fq_valstep);
1354 fact=1;
1355 i=0;
1356 if(fq_valstep > 1)
1357   {
1358   i=1;
1359   fmt="%.3f";
1360   fact=0.001;;
1361   }
1362 if(fq_valstep >= 1000)
1363   {
1364   i=2;
1365   fmt="%.3f";
1366   fact=0.000001;
1367   }
1368 if(fq_valstep >= 100000)
1369   {
1370   i=2;
1371   fmt="%.1f";
1372   fact=0.000001;
1373   }
1374 k=3+x1;
1375 unit_len=2;
1376 hide_mouse(x1 ,x2, y+1, y+text_height+3);
1377 lir_fillbox(x1+2, y+1, x2-x1-4,text_height+2,0);
1378 lir_hline(x1,y+text_height+3,x2,7);
1379 if(i == 0)
1380   {
1381   lir_pixwrite(k, y+3,"Hz");
1382   unit_len+=2*text_width;
1383   }
1384 if(i == 1)
1385   {
1386   lir_pixwrite(k, y+3,"kHz");
1387   unit_len+=3*text_width;
1388   }
1389 if(i == 2)
1390   {
1391   lir_pixwrite(k, y+3,"MHz");
1392   unit_len+=3*text_width;
1393   }
1394 t1=(fq_offset/fq_valstep-(long int)(fq_offset/fq_valstep))*fq_valstep;
1395 // Get the decimal fraction and convert it to Hz
1396 fq_value=fq_valstep-t1;
1397 fq_x=first_xpixel+fq_value/hz_per_pixel;
1398 fq_xstep=fq_valstep/hz_per_pixel;
1399 fq_value+=fq_offset;
1400 xb=-1;
1401 ya=y+text_height;
1402 yb=y+text_height+2;
1403 xd=fq_x;
1404 while( xd < x2)
1405   {
1406   sprintf(s,fmt,fact*fq_value);
1407   k=0;
1408   while(s[k]!=0)k++;
1409   xc=fq_x-k*text_width/2;
1410   xd=xc+k*text_width+2;
1411   if(xc > x1+unit_len && xd < x2)
1412     {
1413     if(k<numchar)
1414       {
1415       m=0;
1416       }
1417     else
1418       {
1419       m=k-numchar;
1420       }
1421     lir_pixwrite(xc, y+2,&s[m]);
1422     if(xb > 0)
1423       {
1424       if(j <= 2 )
1425         {
1426         xa=(fq_x+xb)/2;
1427         lir_line(xa,ya,xa,yb,14);
1428         if(kill_all_flag) return;
1429         }
1430       else
1431         {
1432         t1=0.2*(fq_x-xb)+0.5;
1433         xa=t1;
1434         lir_line(xb+xa,ya,xb+xa,yb,15);
1435         if(kill_all_flag) return;
1436         lir_line(fq_x-xa,ya,fq_x-xa,yb,15);
1437         if(kill_all_flag) return;
1438         t1=0.4*(fq_x-xb)+0.5;
1439         xa=t1;
1440         lir_line(xb+xa,ya,xb+xa,yb,15);
1441         if(kill_all_flag) return;
1442         lir_line(fq_x-xa,ya,fq_x-xa,yb,15);
1443         if(kill_all_flag) return;
1444         }
1445       }
1446     xb=fq_x;
1447     lir_line(fq_x,ya,fq_x,yb,15);
1448     if(kill_all_flag) return;
1449     lir_line(fq_x+1,ya,fq_x+1,yb,15);
1450     if(kill_all_flag) return;
1451     lir_line(fq_x-1,ya,fq_x-1,yb,15);
1452     if(kill_all_flag) return;
1453     }
1454   fq_x+=fq_xstep;
1455   fq_value+=fq_valstep;
1456   }
1457 }
1458 
1459 
hires_fq_scale(void)1460 void hires_fq_scale(void)
1461 {
1462 int x1, x2, y;
1463 float mfq;
1464 double first_frequency;
1465 char s[80];
1466 hide_mouse(hg.xleft,hg.xright, hg.ytop, hg.ytop+1.5*text_height);
1467 sprintf(s,"%4d",hg.spek_avgnum);
1468 show_button(&hgbutt[HG_FFT2_AVGNUM],s);
1469 mfq=mix1_selfreq[0];
1470 if(mfq < 0)return;
1471 // Make a frequency scale on top of the high resolution spectrum.
1472 // We will show mix1_selfreq[0] in this graph (if it exists)
1473 hg_first_fq=mfq-hg_hz_per_pixel*hg_size/2;
1474 hg_first_point=hg_first_fq/hg_hz_per_pixel;
1475 if(hg_first_point<0)hg_first_point=0;
1476 hg_last_point=hg_first_point+hg_size;
1477 if(hg_last_point > fft2_size)hg_last_point=fft2_size;
1478 hg_first_point=hg_last_point-hg_size;
1479 if(hg_first_point<0)
1480   {
1481   lirerr(9998888);
1482   return;
1483   }
1484 hg_recalc_pointer=hg_first_point;
1485 hg_first_fq=hg_first_point*hg_hz_per_pixel;
1486 hg_first_fq+=1;
1487 first_frequency=hg_first_fq;
1488 y=hg.ytop;
1489 x1=hgbutt[HG_FFT2_AVGNUM].x2;
1490 x2=hg.xright;
1491 fq_scale(x1, x2, y, hg_first_xpixel, first_frequency, hg_hz_per_pixel);
1492 hg_cursor();
1493 }
1494 
hg_stonbars_redraw(void)1495 void hg_stonbars_redraw(void)
1496 {
1497 update_bar(hg_ston1_x1,hg_ston1_x2,hg_ston_y0,hg_ston1_y,hg_ston1_yold,
1498                                             HG_STON1_RANGE_COLOR,hg_stonbuf);
1499 hg_ston1_yold=hg_ston1_y;
1500 update_bar(hg_ston2_x1,hg_ston2_x2,hg_ston_y0,hg_ston2_y,hg_ston2_yold,
1501                                             HG_STON2_RANGE_COLOR,hg_stonbuf);
1502 hg_ston2_yold=hg_ston2_y;
1503 }
1504 
show_map65_buttons(void)1505 void show_map65_buttons(void)
1506 {
1507 char s[40];
1508 sprintf(s,"%2d",hg.map65_gain_db);
1509 show_button(&hgbutt[HG_MAP65_GAIN],s);
1510 sprintf(s,"%d",hg.map65_strong);
1511 show_button(&hgbutt[HG_MAP65_STRONG],s);
1512 }
1513 
make_hg_yscale(void)1514 void make_hg_yscale(void)
1515 {
1516 char s[80];
1517 int i,k;
1518 float t1;
1519 int ypixels, scale_y;
1520 double db_scalestep;
1521 float scale_value, yrange,db_ref;
1522 hide_mouse(hg.xleft,hg.xright, hg.ytop, hg_y0);
1523 lir_fillbox(hg.xleft+1,hg.ytop+4+text_height,hg.xright-hg.xleft-2,
1524                                         hg_y0-hg.ytop-5-text_height,0);
1525 for(i=0; i<screen_height; i++)hg_background[i]=0;
1526 k=500-hg.spek_gain;
1527 if(k>=0)k++;
1528 t1=((float)(abs(k)));
1529 if(k<0)t1=1/t1;
1530 hg_db_per_pixel=sqrt(t1)*HG_GAIN/wg.waterfall_db_gain;
1531 db_scalestep=1.3*hg_db_per_pixel*text_height;
1532 adjust_scale(&db_scalestep);
1533 ypixels=hg_y0-hg.ytop;
1534 yrange=ypixels*hg_db_per_pixel;
1535 // Make db_ref a dB value to put at the bottom of our graph.
1536 // Select it for waterfall_db_zero to be at 8% of the y axis.
1537 db_ref=(wg.waterfall_db_zero-0.08*yrange);
1538 // Make db_ref a multiple of db_scalestep + 0.00001
1539 i=0.5+db_ref/db_scalestep-hg.spek_zero+500;
1540 db_ref=i*db_scalestep+0.00001;
1541 scale_value=db_ref-db_scalestep;
1542 scale_y=hg_y0+db_scalestep/hg_db_per_pixel;
1543 while( scale_y-2.5*text_height > hg.ytop+db_scalestep/hg_db_per_pixel)
1544   {
1545   scale_y-=db_scalestep/hg_db_per_pixel;
1546   scale_value+=db_scalestep;
1547   if(scale_y+2*text_height-1 < hg.ybottom)
1548     {
1549     if(scale_value < 0)
1550       {
1551       t1=scale_value-0.001;
1552       }
1553     else
1554       {
1555       t1=scale_value+0.001;
1556       }
1557     i=t1;
1558     if(i>=-9 && i<100 && scale_value-i < db_scalestep/2)
1559       {
1560       sprintf(s,"%2d",i);
1561       lir_pixwrite(hg.xleft+2,scale_y-text_height/2+2,s);
1562       }
1563     }
1564   if(scale_y+2+text_height < hg.ybottom)
1565     {
1566     hg_background[scale_y]=HG_DBSCALE_COLOR;
1567     lir_hline(hg_first_xpixel,scale_y,hg_last_xpixel,HG_DBSCALE_COLOR);
1568     if(kill_all_flag) return;
1569     }
1570   }
1571 hg_yfac_power=(float)(fft1_new_points)/fft1_size;
1572 hg_yfac_power=(HG_ZERO*hg_yfac_power)/fft1_size;
1573 hg_yfac_power/=(fft2_size*hg.spek_avgnum*pow(10.,0.1*db_ref));
1574 if(fft_cntrl[FFT2_CURMODE].mmx != 0)
1575   {
1576   hg_yfac_power*=1<<(2*genparm[SECOND_FFT_ATT_N]);
1577   }
1578 hg_yfac_power*=1<<(2*genparm[FIRST_BCKFFT_ATT_N]);
1579 hg_yfac_log=10./hg_db_per_pixel;
1580 // Place a colour scale at the right hand side
1581 for(i=hg_y0; i>hg_ymax+text_height; i--)
1582   {
1583   scale_value=db_ref+(hg_y0-i)*hg_db_per_pixel;
1584   k=wg_waterf_cfac*((scale_value-wg.waterfall_db_zero)*100);
1585   if(k<0)k=0;
1586   if(k>=MAX_COLOR_SCALE)k=MAX_COLOR_SCALE-1;
1587   lir_hline(hg_last_xpixel+1,i,hg.xright-1,color_scale[k]);
1588   if(kill_all_flag) return;
1589   }
1590 make_wg_yfac();
1591 hg_stonbars_redraw();
1592 sprintf(s,"%3d",hg.spek_gain);
1593 show_button(&hgbutt[HG_SPECTRUM_GAIN],s);
1594 sprintf(s,"%3d",hg.spek_zero);
1595 show_button(&hgbutt[HG_SPECTRUM_ZERO],s);
1596 hg_cursor();
1597 afc_curx=-1;
1598 if(show_map65)
1599   {
1600   show_map65_buttons();
1601   }
1602 }
1603 
show_wtrfbutton(BUTTONS * butt,char * s)1604 void show_wtrfbutton(BUTTONS *butt, char *s)
1605 {
1606 int ix1, ix2, iy1, iy2;
1607 ix1=butt[0].x1;
1608 ix2=butt[0].x2;
1609 iy1=butt[0].y1;
1610 iy2=butt[0].y2;
1611 if( ix1 < 0 ||
1612     ix1 >= screen_width ||
1613     iy1 < 0 ||
1614     iy2 >= screen_height )
1615   {
1616   return;
1617   }
1618 hide_mouse(ix1-1,ix2+1,iy1-1,iy2+1);
1619 lir_fillbox(ix1-1,iy1-1,ix2-ix1+2,iy2-iy1+2,0);
1620 if(kill_all_flag) return;
1621 lir_hline(ix1,iy1,ix2,button_color);
1622 if(kill_all_flag) return;
1623 lir_hline(ix1,iy2,ix2,button_color);
1624 if(kill_all_flag) return;
1625 lir_line(ix1,iy1,ix1,iy2,button_color);
1626 if(kill_all_flag) return;
1627 lir_line(ix2,iy1,ix2,iy2,button_color);
1628 if(kill_all_flag) return;
1629 lir_pixwrite(ix1+text_width/2-1,iy1+2,s);
1630 }
1631 
1632 
1633 
baseband_fq_scale(void)1634 void baseband_fq_scale(void)
1635 {
1636 int y, x1, x2;
1637 float mfq;
1638 double first_frequency;
1639 mfq=mix1_selfreq[0];
1640 if(mfq < 0)return;
1641 // Make a frequency scale on top of the baseband spectrum.
1642 // We will show mix1_selfreq[0] in this graph (if it exists)
1643 first_frequency=bg_hz_per_pixel*(bg_first_xpoint -fft3_size/2)+mfq;
1644 y=bg.ytop;
1645 x1=bgbutt[BG_PIX_PER_PNT_INC].x2;
1646 x2=bgbutt[BG_RESOLUTION_DECREASE].x1;
1647 fq_scale(x1, x2, y, bg_first_xpixel, first_frequency,
1648 bg_hz_per_pixel/bg.pixels_per_point);
1649 }
1650 
wide_fq_scale(void)1651 void wide_fq_scale(void)
1652 {
1653 int ya;
1654 double first_frequency;
1655 if(lir_status == LIR_POWTIM)return;
1656 first_frequency=wg_first_frequency;
1657 ya=wg.ytop;
1658 if(wg_freq_x1 <0)return;
1659 fq_scale(wg_freq_x1, wg_freq_x2, ya,
1660                           wg_first_xpixel, first_frequency, wg_hz_per_pixel);
1661 }
1662 
show_pol(void)1663 void show_pol(void)
1664 {
1665 char s[80];
1666 int angstep,i,x1,x2,y9,y2;
1667 float major,minor,z1,z2,a1,a2,c1;
1668 float pol_a,sina,pol_b;
1669 hide_mouse(pg.xleft,pg.xright,pg.ytop,pg.ybottom);
1670 // Make an ellipse to describe circular polarization
1671 i=pgbutt[PG_ANGLE].x2-pgbutt[PG_ANGLE].x1;
1672 lir_fillbox(pgbutt[PG_ANGLE].x1,pgbutt[PG_ANGLE].y1,i,i,PG_BACKGROUND_COLOR);
1673 major=0.45*i;
1674 // The complex amplitudes in our two channels are:
1675 // re_x=cos(z)*cos(a)
1676 // im_x=sin(z)*cos(a)
1677 // re_y=sin(a)*(cos(z)*cos(w)-sin(z)*sin(w))
1678 // im_y=sin(a)*(sin(z)*cos(w)+cos(z)*sin(w))
1679 // z is the time function and a is the angle between main axis of
1680 // the incoming wave and the x channel.
1681 // If the antenna was twisted by the angle a, the signals would become:
1682 // re_a=cos(a)*re_x+sin(a)*re_y
1683 // im_a=cos(a)*im_x+sin(a)*im_y
1684 // re_b=cos(a)*re_y-sin(a)*re_x
1685 // im_b=cos(a)*im_y-sin(a)*im_x
1686 // This would maximise the a signal and minimise the b signal.
1687 // The power in the b channel is re_*re_b+im_b*im_b, and that is the
1688 // function we want the minimum for over one cycle of z.
1689 // re_b=cos(a)*sin(a)*(cos(z)*cos(w)-sin(z)*sin(w))-sin(a)*cos(z)*cos(a)
1690 // im_b=cos(a)*sin(a)*(sin(z)*cos(w)+cos(z)*sin(w))-sin(a)*sin(z)*cos(a)
1691 // re_b=sin(2*a)*(cos(z)*cos(w)-sin(z)*sin(w)-cos(z))/2
1692 // im_b=sin(2*a)*(sin(z)*cos(w)+cos(z)*sin(w)-sin(z))/2
1693 // The power in the b channel at minimum is:
1694 // B=sin(2*a)^2*( [cos(z)*cos(w)-sin(z)*sin(w)-cos(z)]^2 +
1695 //                [sin(z)*cos(w)+cos(z)*sin(w)-sin(z)]^2   )/4
1696 // B=0.5*sin(2*a)^2*(1-cos(2*w) )
1697 // For linear polarization B=0 and for circular B=0.5
1698 // Illustrate the polarization with an ellipse.
1699 // the axis power lengths are B and (1-B)
1700 pol_a=acos(pg.c1);
1701 if(pg.c3 == 0)
1702   {
1703   pg_b=0;
1704   }
1705 else
1706   {
1707   pg_b=atan2(pg.c3,pg.c2);
1708   }
1709 if(fabs(1-pg.c1*pg.c1-pg.c2*pg.c2-pg.c3*pg.c3) >0.01)
1710   {
1711 // Something went wrong.
1712 DEB"pol error c1 %f  c2 %f  c3 %f",pg.c1, pg.c2, pg.c3);
1713   lirerr(887999);
1714   return;
1715   }
1716 // Rotate the coordinate system by pg.angle
1717 pol_b=pol_a-pg.angle*PI_L/180;
1718 if(pol_b > PI_L)pol_b-=PI_L;
1719 if(pol_b <0)pol_b+=PI_L;
1720 c1=cos(pol_b);
1721 z1=pow(sin(2*pol_a),2.)*0.5*(1-cos(2*pg_b));
1722 minor=major*z1;
1723 angstep=2*major/PI_L;
1724 angstep*=sqrt(fabs(minor/major));
1725 angstep++;
1726 angstep&=0xfffffffe;
1727 if(angstep < 2)angstep=2;
1728 z2=2*PI_L/angstep;
1729 z1=pol_a;
1730 angstep++;
1731 sina=sin(pol_b);
1732 x1=pg_x0+major*c1;
1733 y9=pg_y0-major*sina;
1734 for(i=0; i<angstep; i++)
1735   {
1736   a1=major*cos(z1-pol_a);
1737   a2=minor*sin(z1-pol_a);
1738   x2=pg_x0+(a1*c1+a2*sina);
1739   y2=pg_y0+(a2*c1-a1*sina);
1740   lir_line(x1,y9,x2,y2,7);
1741   if(kill_all_flag) return;
1742   x1=x2;
1743   y9=y2;
1744   z1+=z2;
1745   }
1746 a2=y2=x2=0;
1747 pg_pol_angle=180*pol_b/PI_L;
1748 sprintf(s,"%3d",(int)(pg_pol_angle));
1749 lir_pixwrite(pgbutt[PG_CIRC].x1+text_width/2,pgbutt[PG_CIRC].y2+1,s);
1750 lir_fillbox(pgbutt[PG_CIRC].x1,pgbutt[PG_CIRC].y1,
1751            pgbutt[PG_CIRC].x2-pgbutt[PG_CIRC].x1,
1752            pgbutt[PG_CIRC].y2-pgbutt[PG_CIRC].y1,PC_CONTROL_COLOR);
1753 if(pol_a < 0.5*PI_L)
1754   {
1755   a1=1;
1756   }
1757 else
1758   {
1759   a1=-1;
1760   }
1761 if(a1*pg_b > 0)
1762   {
1763   s[0]='R';
1764   }
1765 else
1766   {
1767   s[0]='L';
1768   }
1769 s[1]=0;
1770 lir_pixwrite(pg_x0-text_width/4,pg_y0-text_height/3,s);
1771 i=0.88*pg_b*(pgbutt[PG_CIRC].x2-pgbutt[PG_CIRC].x1)/PI_L;
1772 lir_line(pg_x0+i,pgbutt[PG_CIRC].y1,pg_x0+i,pgbutt[PG_CIRC].y2-1,15);
1773 }
1774