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