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 #define HG_STON_RANGE 6.0
24 
25 
26 #include "globdef.h"
27 #include "uidef.h"
28 #include "fft1def.h"
29 #include "fft2def.h"
30 #include "screendef.h"
31 #include "blnkdef.h"
32 #include "seldef.h"
33 #include "graphcal.h"
34 #include "vernr.h"
35 #include "rusage.h"
36 #include "thrdef.h"
37 #include "sigdef.h"
38 
39 int hires_graph_scro;
40 int hg_old_x1;
41 int hg_old_x2;
42 int hg_old_y1;
43 int hg_old_y2;
44 void make_hires_graph(int clear_old);
45 
new_hg_pol(void)46 void new_hg_pol(void)
47 {
48 float *fftxy, *pwr;
49 int i, j, j_last;
50 int ib,k;
51 float t1,t2,t3,t4,r1,r2;
52 short int *zxy;
53 ib=hg_last_point;
54 k=2*hg_size;
55 for(i=0; i<k; i++) hg_fft2_pwrsum[i]=0;
56 j=fft2_nb;
57 j_last=(fft2_na+fft2n_mask)&fft2n_mask;
58 nwpol:;
59 pwr=&hg_fft2_pwr[2*j*hg_size];
60 k=0;
61 if(fft_cntrl[FFT2_CURMODE].mmx == 0)
62   {
63   fftxy=&fft2_float[twice_rxchan*j*fft2_size];
64   for(i=hg_first_point; i<ib; i++)
65     {
66     t1=fftxy[4*i  ];
67     t2=fftxy[4*i+1];
68     t3=fftxy[4*i+2];
69     t4=fftxy[4*i+3];
70     r1=pg.c1*t1+pg.c2*t3+pg.c3*t4;
71     r2=pg.c1*t2+pg.c2*t4-pg.c3*t3;
72     pwr[2*k  ]=r1*r1+r2*r2;
73     hg_fft2_pwrsum[2*k  ]+=pwr[2*k  ];
74     r1=pg.c1*t3-pg.c2*t1+pg.c3*t2;
75     r2=pg.c1*t4-pg.c2*t2-pg.c3*t1;
76     pwr[2*k+1]=r1*r1+r2*r2;
77     hg_fft2_pwrsum[2*k+1]+=pwr[2*k+1];
78     k++;
79     }
80   }
81 else
82   {
83   zxy=&fft2_short_int[twice_rxchan*j*fft2_size];
84   for(i=hg_first_point; i<ib; i++)
85     {
86     t1=zxy[4*i  ];
87     t2=zxy[4*i+1];
88     t3=zxy[4*i+2];
89     t4=zxy[4*i+3];
90     r1=pg.c1*t1+pg.c2*t3+pg.c3*t4;
91     r2=pg.c1*t2+pg.c2*t4-pg.c3*t3;
92     pwr[2*k  ]=r1*r1+r2*r2;
93     hg_fft2_pwrsum[2*k  ]+=pwr[2*k  ];
94     r1=pg.c1*t3-pg.c2*t1+pg.c3*t2;
95     r2=pg.c1*t4-pg.c2*t2-pg.c3*t1;
96     pwr[2*k+1]=r1*r1+r2*r2;
97     hg_fft2_pwrsum[2*k+1]+=pwr[2*k+1];
98     k++;
99     }
100   }
101 if(j==j_last)return;
102 j=(j+1)&fft2n_mask;
103 goto nwpol;
104 }
105 
106 
change_hg_spectrum_zero(void)107 void change_hg_spectrum_zero(void)
108 {
109 hg.spek_zero=numinput_int_data;
110 hg_ston1_yold=-1;
111 hg_ston2_yold=-1;
112 sc[SC_HG_Y_SCALE]++;
113 sc[SC_SHOW_FFT2]++;
114 make_modepar_file(GRAPHTYPE_HG);
115 }
116 
change_hg_spectrum_gain(void)117 void change_hg_spectrum_gain(void)
118 {
119 hg.spek_gain=numinput_int_data;
120 sc[SC_HG_Y_SCALE]++;
121 sc[SC_SHOW_FFT2]++;
122 hg_ston1_yold=-1;
123 hg_ston2_yold=-1;
124 make_modepar_file(GRAPHTYPE_HG);
125 }
126 
make_hires_valid(void)127 void make_hires_valid(void)
128 {
129 float *pwra;
130 int i, j, k, ib;
131 if(sw_onechan)
132   {
133   ib=hg_last_point;
134   j=fft2_nb;
135   pwra=&fft2_power_float[j*fft2_size];
136   k=0;
137   for(i=hg_first_point; i<ib; i++)
138     {
139     hg_fft2_pwrsum[k]=pwra[i];
140     k++;
141     }
142 sum_2:;
143   k=0;
144   pwra=&fft2_power_float[j*fft2_size];
145   for(i=hg_first_point; i<ib; i++)
146     {
147     hg_fft2_pwrsum[k]+=pwra[i];
148     k++;
149     }
150   j=(j+1)&fft2n_mask;
151   if(j == fft2_na)goto finish;
152   goto sum_2;
153   }
154 else
155   {
156   new_hg_pol();
157   }
158 finish:;
159 }
160 
161 
new_fft2_averages(void)162 void new_fft2_averages(void)
163 {
164 float *pwra;
165 TWOCHAN_POWER *y;
166 int i, j, n;
167 if(mix1_selfreq[0] < 0)return;
168 // The number to average over may have changed, update fft2_nb
169 i=(fft2_na-hg.spek_avgnum+max_fft2n)&fft2n_mask;
170 n=0;
171 if(i != fft2_nb)
172   {
173   fft2_nb=i;
174   if(sw_onechan)
175     {
176     pwra=&fft2_power_float[fft2_nb*fft2_size];
177     for(i=0; i<fft2_size; i++)
178       {
179       fft2_powersum_float[i]=pwra[i];
180       }
181     n+=fft2_size;
182     j=fft2_nb;
183     if(j==fft2_na)goto ex1;
184 sum:;
185     j=(j+1)&fft2n_mask;
186     if(j==fft2_na)goto ex1;
187     pwra=&fft2_power_float[j*fft2_size];
188     for(i=0; i<fft2_size; i++)
189       {
190       fft2_powersum_float[i]+=pwra[i];
191       }
192     n+=fft2_size;
193     if(n>3000000)
194       {
195       lir_sched_yield();
196       n=0;
197       }
198     goto sum;
199 ex1:;
200     }
201   else
202     {
203     y=&fft2_xypower[fft2_nb*fft2_size];
204     for(i=0; i<fft2_size; i++)
205       {
206       fft2_xysum[i].x2   =y[i].x2;
207       fft2_xysum[i].y2   =y[i].y2;
208       fft2_xysum[i].im_xy=y[i].im_xy;
209       fft2_xysum[i].re_xy=y[i].re_xy;
210       }
211     n+=fft2_size;
212     j=fft2_nb;
213     if(j==fft2_na)goto ex2;
214 sumxy:;
215     j=(j+1)&fft2n_mask;
216     if(j==fft2_na)goto ex2;
217     y=&fft2_xypower[j*fft2_size];
218     for(i=0; i<fft2_size; i++)
219       {
220       fft2_xysum[i].x2   +=y[i].x2;
221       fft2_xysum[i].y2   +=y[i].y2;
222       fft2_xysum[i].im_xy+=y[i].im_xy;
223       fft2_xysum[i].re_xy+=y[i].re_xy;
224       }
225     n+=fft2_size;
226     if(n>1000000)
227       {
228       lir_sched_yield();
229       n=0;
230       }
231     goto sumxy;
232 ex2:;
233     }
234   }
235 make_hires_valid();
236 }
237 
238 
239 
help_on_hires_graph(void)240 void help_on_hires_graph(void)
241 {
242 int msg_no;
243 int event_no;
244 // Set msg to select a frequency in case it is not button or border
245 msg_no=13;
246 // In case we are on one of the control bars, select the
247 // appropriate message.
248 if(mouse_y >= hg_ston_y0)
249   {
250   if(mouse_x >= timf2_hg_xmin && mouse_x <= timf2_hg_xmax)
251     {
252     msg_no=14;
253     }
254   else
255     {
256     msg_no=-1;
257     }
258   }
259 else
260   {
261 
262   if( mouse_x<hg_first_xpixel && mouse_y > hg_stonbars_ytop)
263     {
264     if(mouse_x <= hg_ston1_x2)
265       {
266       msg_no=15;
267       }
268     else
269       {
270       msg_no=16;
271       }
272     }
273   }
274 for(event_no=0; event_no<MAX_HGBUTT; event_no++)
275   {
276   if( hgbutt[event_no].x1 <= mouse_x &&
277       hgbutt[event_no].x2 >= mouse_x &&
278       hgbutt[event_no].y1 <= mouse_y &&
279       hgbutt[event_no].y2 >= mouse_y)
280     {
281     switch (event_no)
282       {
283       case HG_TOP:
284       case HG_BOTTOM:
285       case HG_LEFT:
286       case HG_RIGHT:
287       msg_no=100;
288       break;
289 
290       case HG_BLN_STUPID:
291       msg_no=17;
292       break;
293 
294       case HG_BLN_CLEVER:
295       msg_no=18;
296       break;
297 
298       case HG_TIMF2_STATUS:
299       if(sw_onechan)
300         {
301         msg_no=19;
302         }
303       else
304         {
305         msg_no=20;
306         }
307       break;
308 
309       case HG_TIMF2_ST_INC:
310       msg_no=73;
311       break;
312 
313       case HG_TIMF2_ST_DEC:
314       msg_no=74;
315       break;
316 
317       case HG_TIMF2_WK_INC:
318       msg_no=75;
319       break;
320 
321       case HG_TIMF2_WK_DEC:
322       msg_no=76;
323       break;
324 
325       case HG_TIMF2_LINES:
326       msg_no=77;
327       break;
328 
329       case HG_TIMF2_HOLD:
330       msg_no=78;
331       break;
332 
333       case HG_FFT2_AVGNUM:
334       msg_no=62;
335       break;
336 
337       case HG_SPECTRUM_GAIN:
338       msg_no=317;
339       break;
340 
341       case HG_SPECTRUM_ZERO:
342       msg_no=318;
343       break;
344 
345       case HG_MAP65_GAIN:
346       msg_no=334;
347       break;
348 
349       case HG_MAP65_STRONG:
350       msg_no=335;
351       break;
352       }
353     }
354   }
355 help_message(msg_no);
356 }
357 
change_fft2avgnum(void)358 void change_fft2avgnum(void)
359 {
360 hg.spek_avgnum=numinput_int_data;
361 if(hg.spek_avgnum <1)hg.spek_avgnum=1;
362 if(hg.spek_avgnum>fft2n_mask)hg.spek_avgnum=fft2n_mask;
363 make_modepar_file(GRAPHTYPE_HG);
364 new_fft2_averages();
365 hg_ston1_yold=-1;
366 hg_ston2_yold=-1;
367 sc[SC_HG_FQ_SCALE]++;
368 sc[SC_SHOW_FFT2]++;
369 sc[SC_HG_Y_SCALE]++;
370 }
371 
change_map65(void)372 void change_map65(void)
373 {
374 hg.map65_gain_db=numinput_int_data;
375 if(hg.map65_gain_db < 0)hg.map65_gain_db=0;
376 if(hg.map65_gain_db > 15)hg.map65_gain_db=15;
377 hg_map65_gain=(float)pow(10.0,-(float)hg.map65_gain_db/20.F);
378 make_modepar_file(GRAPHTYPE_HG);
379 sc[SC_SHOW_MAP65]++;
380 }
381 
mouse_continue_hires_graph(void)382 void mouse_continue_hires_graph(void)
383 {
384 int j;
385 switch (mouse_active_flag-1)
386   {
387   case HG_TOP:
388   if(hg.ytop!=mouse_y)
389     {
390     pause_screen_and_hide_mouse();
391     graph_borders((void*)&hg,0);
392     hg.ytop=mouse_y;
393     j=hg.ybottom-4*text_height;
394     if(hg.ytop > j)hg.ytop=j;
395     if(hg_old_y1 > hg.ytop)hg_old_y1=hg.ytop;
396     graph_borders((void*)&hg,15);
397     resume_thread(THREAD_SCREEN);
398     }
399   break;
400 
401   case HG_BOTTOM:
402   if(hg.ybottom!=mouse_y)
403     {
404     pause_screen_and_hide_mouse();
405     graph_borders((void*)&hg,0);
406     hg.ybottom=mouse_y;
407     j=hg.ytop+4*text_height;
408     if(hg.ybottom < j)hg.ybottom=j;
409     if(hg_old_y2 < hg.ybottom)hg_old_y2=hg.ybottom;
410     graph_borders((void*)&hg,15);
411     resume_thread(THREAD_SCREEN);
412     }
413   break;
414 
415   case HG_LEFT:
416   if(hg.xleft!=mouse_x)
417     {
418     pause_screen_and_hide_mouse();
419     graph_borders((void*)&hg,0);
420     hg.xleft=mouse_x;
421     j=hg.xright-32-6*text_width;
422     if(hg.xleft > j)hg.xleft=j;
423     if(hg_old_x1 > hg.xleft)hg_old_x1=hg.xleft;
424     graph_borders((void*)&hg,15);
425     resume_thread(THREAD_SCREEN);
426     }
427   break;
428 
429   case HG_RIGHT:
430   if(hg.xright!=mouse_x)
431     {
432     pause_screen_and_hide_mouse();
433     graph_borders((void*)&hg,0);
434     hg.xright=mouse_x;
435     j=hg.xleft+32+6*text_width;
436     if(hg.xright < j)hg.xright=j;
437     if(hg_old_x2 < hg.xright)hg_old_x2=hg.xright;
438     graph_borders((void*)&hg,15);
439     resume_thread(THREAD_SCREEN);
440     }
441   break;
442 
443   default:
444   goto await_release;
445   }
446 if(leftpressed == BUTTON_RELEASED)goto finish;
447 return;
448 await_release:;
449 if(leftpressed != BUTTON_RELEASED) return;
450 switch (mouse_active_flag-1)
451   {
452   case HG_BLN_STUPID:
453   hg.stupid_bln_mode++;
454   if(hg.stupid_bln_mode>2)hg.stupid_bln_mode=0;
455   break;
456 
457   case HG_BLN_CLEVER:
458   if( (fft1_calibrate_flag&CALAMP)==CALAMP)
459     {
460     hg.clever_bln_mode++;
461     if(hg.clever_bln_mode>2)hg.clever_bln_mode=0;
462     }
463   break;
464 
465   case HG_TIMF2_STATUS:
466   if(ui.operator_skil == OPERATOR_SKIL_EXPERT)
467     {
468     hg.timf2_display^=1;
469     timf2_display_counter=0;
470     timf2_display_maxval_uint=0;
471     timf2_display_powermax_uint=0;
472     timf2_display_maxval_float=0;
473     timf2_display_powermax_float=0;
474     timf2_show_pointer=-1;
475     }
476   break;
477 
478   case HG_TIMF2_ST_INC:
479   hg.timf2_display_st_gain *=2;
480   if(hg.timf2_display_st_gain > 256)hg.timf2_display_st_gain = 256;
481   break;
482 
483   case HG_TIMF2_ST_DEC:
484   hg.timf2_display_st_gain /=2;
485   if(hg.timf2_display_st_gain < 0.00002)hg.timf2_display_st_gain = 1./32768;
486   break;
487 
488   case HG_TIMF2_WK_INC:
489   hg.timf2_display_wk_gain *=2;
490   if(hg.timf2_display_wk_gain > 256)hg.timf2_display_wk_gain = 256;
491   break;
492 
493   case HG_TIMF2_WK_DEC:
494   hg.timf2_display_wk_gain /=2;
495   if(hg.timf2_display_wk_gain < 0.00002)hg.timf2_display_wk_gain = 1./32768;
496   break;
497 
498   case HG_TIMF2_LINES:
499   hg.timf2_display_lines^=1;
500   break;
501 
502   case HG_TIMF2_HOLD:
503   hg.timf2_display_hold^=1;
504   break;
505 
506   case HG_FFT2_AVGNUM:
507   mouse_active_flag=1;
508   numinput_xpix=hgbutt[HG_FFT2_AVGNUM].x1+text_width/2-1;
509   numinput_ypix=hgbutt[HG_FFT2_AVGNUM].y1+2;
510   numinput_chars=4;
511   erase_numinput_txt();
512   numinput_flag=FIXED_INT_PARM;
513   par_from_keyboard_routine=change_fft2avgnum;
514   return;
515 
516   case HG_SPECTRUM_ZERO:
517   mouse_active_flag=1;
518   numinput_xpix=hgbutt[HG_SPECTRUM_ZERO].x1+text_width/2-1;
519   numinput_ypix=hgbutt[HG_SPECTRUM_ZERO].y1+2;
520   numinput_chars=3;
521   erase_numinput_txt();
522   numinput_flag=FIXED_INT_PARM;
523   par_from_keyboard_routine=change_hg_spectrum_zero;
524   return;
525 
526   case HG_SPECTRUM_GAIN:
527   mouse_active_flag=1;
528   numinput_xpix=hgbutt[HG_SPECTRUM_GAIN].x1+text_width/2-1;
529   numinput_ypix=hgbutt[HG_SPECTRUM_GAIN].y1+2;
530   numinput_chars=3;
531   erase_numinput_txt();
532   numinput_flag=FIXED_INT_PARM;
533   par_from_keyboard_routine=change_hg_spectrum_gain;
534   return;
535 
536   case HG_MAP65_GAIN:
537   if(show_map65)
538     {
539     mouse_active_flag=1;
540     numinput_xpix=hgbutt[HG_MAP65_GAIN].x1+text_width/2-1;
541     numinput_ypix=hgbutt[HG_MAP65_GAIN].y1+2;
542     numinput_chars=2;
543     erase_numinput_txt();
544     numinput_flag=FIXED_INT_PARM;
545     par_from_keyboard_routine=change_map65;
546     }
547   return;
548 
549   case HG_MAP65_STRONG:
550   if(show_map65)
551     {
552     hg.map65_strong++;
553     hg.map65_strong&=1;
554     make_modepar_file(GRAPHTYPE_HG);
555     sc[SC_SHOW_MAP65]++;
556     }
557   break;
558   }
559 finish:;
560 leftpressed=BUTTON_IDLE;
561 mouse_active_flag=0;
562 timf2_hg_x[0]=-1;
563 timf2_hg_x[1]=-1;
564 new_fft2_averages();
565 make_hires_graph(TRUE);
566 if(kill_all_flag) return;
567 }
568 
569 
hg_control_finish(void)570 void hg_control_finish(void)
571 {
572 sc[SC_BLANKER_INFO]++;
573 if(leftpressed == BUTTON_RELEASED)
574   {
575   leftpressed=BUTTON_IDLE;
576   make_modepar_file(GRAPHTYPE_HG);
577   mouse_active_flag=0;
578   }
579 }
580 
clever_limit_control(void)581 void clever_limit_control(void)
582 {
583 if(mouse_x < timf2_hg_xmin || mouse_x > timf2_hg_xmax)
584   {
585   if(leftpressed == BUTTON_RELEASED)leftpressed=BUTTON_IDLE;
586   return;
587   }
588 hg.clever_bln_limit=(unsigned int)(2*exp((float)
589                 (mouse_x-timf2_hg_xmin)/timf2_hg_xfac)/timf2_hg_xlog);
590 if(hg.clever_bln_mode == 1)
591   {
592   hg.clever_bln_factor=(float)hg.clever_bln_limit/(float)timf2_noise_floor;
593   if(hg.clever_bln_factor < 0.7F)hg.clever_bln_factor=0.7F;
594   }
595 hg_control_finish();
596 }
597 
stupid_limit_control(void)598 void stupid_limit_control(void)
599 {
600 if(mouse_x < timf2_hg_xmin || mouse_x > timf2_hg_xmax)
601   {
602   if(leftpressed == BUTTON_RELEASED)leftpressed=BUTTON_IDLE;
603   return;
604   }
605 hg.stupid_bln_limit=(unsigned int)(2*exp((float)
606                  (mouse_x-timf2_hg_xmin)/timf2_hg_xfac)/timf2_hg_xlog);
607 if(hg.stupid_bln_mode == 1)
608   {
609   hg.stupid_bln_factor=(float)hg.stupid_bln_limit/(float)timf2_noise_floor;
610   if(hg.stupid_bln_factor < 0.7F) hg.stupid_bln_factor=0.7F;
611   }
612 hg_control_finish();
613 }
614 
make_blanker_ston1(void)615 void make_blanker_ston1(void)
616 {
617 int k;
618 k=hg_ston_y0-hg_ston1_y;
619 if(k<2)
620   {
621   k=2;
622   hg_ston1_y=hg_ston_y0+2;
623   }
624 hg.blanker_ston_fft1=(float)pow(10.,HG_STON_RANGE*k/hg_floatypix);
625 }
626 
make_blanker_ston2(void)627 void make_blanker_ston2(void)
628 {
629 int k;
630 k=hg_ston_y0-hg_ston2_y;
631 if(k<2)
632   {
633   k=2;
634   hg_ston2_y=hg_ston_y0+2;
635   }
636 hg.blanker_ston_fft2=(float)pow(10.,HG_STON_RANGE*k/hg_floatypix);
637 }
638 
hg_ston1_control(void)639 void hg_ston1_control(void)
640 {
641 int yb;
642 yb=mouse_y;
643 if(yb > hg_ston_y0-2)yb=hg_ston_y0-2;
644 if(yb < hg_stonbars_ytop)yb=hg_stonbars_ytop;
645 if(hg_ston1_y!=yb)
646   {
647   hg_ston1_y=yb;
648   make_blanker_ston1();
649   }
650 if(leftpressed == BUTTON_RELEASED)
651   {
652   leftpressed=BUTTON_IDLE;
653   make_modepar_file(GRAPHTYPE_HG);
654   mouse_active_flag=0;
655   }
656 sc[SC_HG_STONBARS_REDRAW]++;
657 }
658 
hg_ston2_control(void)659 void hg_ston2_control(void)
660 {
661 int yb;
662 yb=mouse_y;
663 if(yb > hg_ston_y0-2)yb=hg_ston_y0-2;
664 if(yb < hg_stonbars_ytop)yb=hg_stonbars_ytop;
665 if(hg_ston2_y!=yb)
666   {
667   hg_ston2_y=yb;
668   make_blanker_ston2();
669   }
670 if(leftpressed == BUTTON_RELEASED)
671   {
672   leftpressed=BUTTON_IDLE;
673   make_modepar_file(GRAPHTYPE_HG);
674   mouse_active_flag=0;
675   }
676 sc[SC_HG_STONBARS_REDRAW]++;
677 }
678 
hires_graph_selfreq(void)679 void hires_graph_selfreq(void)
680 {
681 int i;
682 float t1;
683 if(leftpressed != BUTTON_RELEASED)return;
684 leftpressed=BUTTON_IDLE;
685 t1=(float)hg_first_fq+(float)(mouse_x-hg_first_xpixel)*hg_hz_per_pixel;
686 new_mix1_curx[0]=-1;
687 if(t1 <  mix1_lowest_fq)t1=mix1_lowest_fq;
688 if(t1 > mix1_highest_fq)t1=mix1_highest_fq;
689 for(i=1; i<genparm[MIX1_NO_OF_CHANNELS]; i++)
690   {
691   if( fabs(t1-mix1_selfreq[i]) < 3*wg_hz_per_pixel)
692     {
693     new_mix1_curx[i]=-1;
694     mix1_selfreq[i]=-1;
695     mix1_point[i]=-1;
696     }
697   }
698 make_new_signal(0, t1);
699 sc[SC_FREQ_READOUT]++;
700 sc[SC_HG_FQ_SCALE]++;
701 sc[SC_BG_FQ_SCALE]++;
702 baseb_reset_counter++;
703 mouse_active_flag=0;
704 }
705 
mouse_on_hires_graph(void)706 void mouse_on_hires_graph(void)
707 {
708 int i, j, event_no;
709 // First find out if we are on a button or border line.
710 for(event_no=0; event_no<MAX_HGBUTT; event_no++)
711   {
712   if( hgbutt[event_no].x1 <= mouse_x &&
713       hgbutt[event_no].x2 >= mouse_x &&
714       hgbutt[event_no].y1 <= mouse_y &&
715       hgbutt[event_no].y2 >= mouse_y)
716     {
717     hg_old_y1=hg.ytop;
718     hg_old_y2=hg.ybottom;
719     hg_old_x1=hg.xleft;
720     hg_old_x2=hg.xright;
721     mouse_active_flag=1+event_no;
722     current_mouse_activity=mouse_continue_hires_graph;
723     return;
724     }
725   }
726 // Not button or border.
727 // Check if mouse is on bars or in the spectrum
728 if(mouse_y >= hg_ston_y0)
729   {
730   i=abs(mouse_x - timf2_hg_xmin-timf2_hg_clex);
731   j=abs(mouse_x - timf2_hg_xmin-timf2_hg_stux);
732   if(hg.clever_bln_mode ==0)i+=screen_width;
733   if(hg.stupid_bln_mode ==0)j+=screen_width;
734   if(i<j)
735     {
736     if(i<text_width)
737       {
738       current_mouse_activity=clever_limit_control;
739       }
740     else
741       {
742       current_mouse_activity=mouse_nothing;
743       }
744     }
745   else
746     {
747     if(j<text_width)
748       {
749       current_mouse_activity=stupid_limit_control;
750       }
751     else
752       {
753       current_mouse_activity=mouse_nothing;
754       }
755     }
756   }
757 else
758   {
759   if( mouse_x<hg_first_xpixel && mouse_y > hg_stonbars_ytop)
760     {
761     if(mouse_x <= hg_ston1_x2)
762       {
763       current_mouse_activity=hg_ston1_control;
764       }
765     else
766       {
767       current_mouse_activity=hg_ston2_control;
768       }
769     }
770   else
771     {
772     current_mouse_activity=hires_graph_selfreq;
773     }
774   }
775 mouse_active_flag=1;
776 }
777 
make_hires_graph(int clear_old)778 void make_hires_graph(int clear_old)
779 {
780 char s[80],chr;
781 int i,x,y,xt;
782 float t1,t2;
783 pause_thread(THREAD_SCREEN);
784 if(clear_old)
785   {
786   hide_mouse(hg_old_x1,hg_old_x2,hg_old_y1,hg_old_y2);
787   lir_fillbox(hg_old_x1,hg_old_y1,hg_old_x2-hg_old_x1+1,
788                                                     hg_old_y2-hg_old_y1+1,0);
789   }
790 hide_mouse(hg.xleft,hg.xright,hg.ytop,hg.ybottom);
791 current_graph_minh=7*text_height/2;
792 current_graph_minw=25*text_width;
793 check_graph_placement((void*)(&hg));
794 clear_button(hgbutt, MAX_HGBUTT);
795 hg_first_xpixel=hg.xleft+2*text_width+2;
796 hg_last_xpixel=hg.xright-text_width-3;
797 hg_size=hg_last_xpixel-hg_first_xpixel;
798 if(hg_size > fft2_size)
799   {
800   hg_size=fft2_size;
801   hg_first_xpixel=hg_last_xpixel-hg_size;
802   hg.xleft=hg_first_xpixel-2*text_width-2;
803   }
804 scro[hires_graph_scro].no=HIRES_GRAPH;
805 scro[hires_graph_scro].x1=hg.xleft;
806 scro[hires_graph_scro].x2=hg.xright;
807 scro[hires_graph_scro].y1=hg.ytop;
808 scro[hires_graph_scro].y2=hg.ybottom;
809 hgbutt[HG_LEFT].x1=hg.xleft;
810 hgbutt[HG_LEFT].x2=hg.xleft+2;
811 hgbutt[HG_LEFT].y1=hg.ytop;
812 hgbutt[HG_LEFT].y2=hg.ybottom;
813 hgbutt[HG_RIGHT].x1=hg.xright-2;
814 hgbutt[HG_RIGHT].x2=hg.xright;
815 hgbutt[HG_RIGHT].y1=hg.ytop;
816 hgbutt[HG_RIGHT].y2=hg.ybottom;
817 hgbutt[HG_TOP].x1=hg.xleft;
818 hgbutt[HG_TOP].x2=hg.xright;
819 hgbutt[HG_TOP].y1=hg.ytop;
820 hgbutt[HG_TOP].y2=hg.ytop+2;
821 hgbutt[HG_BOTTOM].x1=hg.xleft;
822 hgbutt[HG_BOTTOM].x2=hg.xright;
823 hgbutt[HG_BOTTOM].y1=hg.ybottom-2;
824 hgbutt[HG_BOTTOM].y2=hg.ybottom;
825 // Draw the border lines
826 graph_borders((void*)&hg,7);
827 hg_ymax=hg.ytop+3*text_height/2;
828 hg_stonbars_ytop=hg_ymax+text_height+1;
829 settextcolor(7);
830 x=hg.xleft+text_width;
831 y=hg.ybottom-text_height/2-2;
832 settextcolor(14);
833 make_button(x,y,hgbutt,HG_BLN_STUPID,modes_man_auto[hg.stupid_bln_mode]);
834 x+=2*text_width;
835 settextcolor(11);
836 make_button(x,y,hgbutt,HG_BLN_CLEVER,modes_man_auto[hg.clever_bln_mode]);
837 settextcolor(7);
838 hg_hz_per_pixel=timf1_sampling_speed/(float)fft2_size;
839 // Allocate memory for the high resolution graph.
840 hg_ston1_x1=hg.xleft+1;
841 hg_ston1_x2=hg.xleft+text_width;
842 hg_ston2_x1=hg_first_xpixel-text_width;
843 hg_ston2_x2=hg_first_xpixel-1;
844 hg_ston_y0=hg.ybottom-3*text_height/2-1;
845 if(hires_handle != NULL)
846   {
847   memcheck(2,hiresmem,&hires_handle);
848   if(kill_all_flag)return;
849   hires_handle=chk_free(hires_handle);
850   }
851 init_memalloc(hiresmem, MAX_HIRES_ARRAYS);
852 mem(1,&hg_spectrum,(size_t)(ui.rx_rf_channels*screen_width)*sizeof(short int),0);
853 mem(2,&hg_background,(size_t)screen_height*sizeof(char),0);
854 mem(3,&hg_stonbuf,(size_t)(text_width*(hg.ybottom-hg.ytop))*sizeof(char),0);
855 hires_totmem=memalloc(&hires_handle,"hires");
856 if(hires_totmem == 0)
857   {
858   lirerr(1066);
859   return;
860   }
861 // ********************************************************
862 // ********************************************************
863 // Write out the y scale for logarithmic spectrum graph.
864 // The zero level is the level set by wg.waterfall_db_zero and the number
865 // of dB per pixel is set by wg.waterfall_db_gain
866 // This way the wide graph will reflect the colour scale of the
867 // waterfall graph.
868 hg_redraw_counter=0;
869 hg_y0=hg.ybottom-text_height/2-4;
870 if(hg.timf2_display == 1)
871   {
872   hg_y0-=text_height+2;
873   make_button(hg.xright-text_width,hg_y0, hgbutt,HG_TIMF2_WK_INC,'+');
874   make_button(hg.xright-3*text_width,hg_y0, hgbutt,HG_TIMF2_WK_DEC,'-');
875   xt=hg.xleft+7*text_width/2;
876   chr='L';
877   if(  (hg.timf2_display_lines&1) != 0)chr='P';
878   if(xt+6*text_width > hg.xright)goto buttskip1;
879   make_button(xt,hg_y0, hgbutt,HG_TIMF2_LINES,chr);
880   xt+=2*text_width;
881   chr='C';
882   if(  (hg.timf2_display_hold&1) != 0)chr='H';
883   if(xt+6*text_width > hg.xright)goto buttskip1;
884   make_button(xt,hg_y0, hgbutt,HG_TIMF2_HOLD,chr);
885   xt+=2*text_width;
886   if(xt+6*text_width > hg.xright)goto buttskip1;
887   make_button(xt,hg_y0, hgbutt,HG_TIMF2_ST_DEC,'-');
888   xt+=2*text_width;
889   if(xt+6*text_width > hg.xright)goto buttskip1;
890   make_button(xt,hg_y0, hgbutt,HG_TIMF2_ST_INC,'+');
891   xt+=3*text_width/2;
892   sprintf(s,"%f",hg.timf2_display_st_gain);
893   s[8]=0;
894   i=7;
895   while(s[i-1]!='.' && s[i]=='0')
896     {
897     s[i]=0;
898     i--;
899     }
900   if(xt+6*text_width > hg.xright)goto buttskip1;
901   lir_pixwrite(xt,hg_y0-text_height/2+2,s);
902 //  xt+=i*text_width+3*text_width/2;
903 buttskip1:;
904   sprintf(s,"%f",hg.timf2_display_wk_gain);
905   s[8]=0;
906   i=7;
907   while(s[i-1]!='.' && s[i]=='0')
908     {
909     s[i]=0;
910     i--;
911     }
912   xt=hg.xright-11*text_width/2-i*text_width;
913   if(xt <= hg.xleft)goto buttskip2;
914   lir_pixwrite(xt,hg_y0-text_height/2+2,s);
915   lir_fillbox(0,timf2_ymin[4*ui.rx_rf_channels],screen_width/2,
916                          timf2_ymax[0]-timf2_ymin[4*ui.rx_rf_channels],0);
917   hg_y0-=2;
918 buttskip2:;
919   }
920 // hg_fft2_powersum, which may be the sum of many power values
921 // may become inaccurate because it is calculated each time
922 // by adding the difference between a new and a old value.
923 // This will make the noise floor inaccurate when a very strong
924 // signal disappears.
925 // Make sure to acctually sum all power values now and then so
926 // errors disappear within a reasonable time, twice the time
927 // covered by all the data or 2 seconds, whichever is longest.
928 t2=(float)fft2_new_points/(float)timf1_sampling_speed;
929 t1=(float)hg.spek_avgnum*t2;
930 if(t1<2)t1=2;
931 hg_powersum_recalc=(int)((float)hg_size*t2/t1);
932 // Make a box in which timf2 levels will be drawn.
933 timf2_hg_xmin=x+3*text_width/2;
934 if(ui.operator_skil == OPERATOR_SKIL_EXPERT)
935   {
936   make_button(hg.xright-text_width,y,hgbutt,HG_TIMF2_STATUS,'o');
937   }
938 hg_y0-=text_height/2+2;
939 xt=hg.xleft+5*text_width/2+2;
940 hgbutt[HG_FFT2_AVGNUM].x1=2+hg.xleft;
941 hgbutt[HG_FFT2_AVGNUM].x2=2+hg.xleft+9*text_width/2;
942 hgbutt[HG_FFT2_AVGNUM].y1=2+hg.ytop;
943 hgbutt[HG_FFT2_AVGNUM].y2=2+hg.ytop+text_height;
944 hgbutt[HG_SPECTRUM_GAIN].x1=hg.xright-7*text_width/2-2;
945 hgbutt[HG_SPECTRUM_GAIN].x2=hg.xright-2;
946 hgbutt[HG_SPECTRUM_GAIN].y1=hg_y0-text_height;
947 hgbutt[HG_SPECTRUM_GAIN].y2=hg_y0;
948 hgbutt[HG_SPECTRUM_ZERO].x1=xt;
949 hgbutt[HG_SPECTRUM_ZERO].x2=xt+7*text_width/2;
950 hgbutt[HG_SPECTRUM_ZERO].y1=hg_y0-text_height;
951 hgbutt[HG_SPECTRUM_ZERO].y2=hg_y0;
952 hgbutt[HG_MAP65_GAIN].x1=hgbutt[HG_SPECTRUM_ZERO].x2+text_width/2;
953 hgbutt[HG_MAP65_GAIN].x2=hgbutt[HG_MAP65_GAIN].x1+5*text_width/2;
954 hgbutt[HG_MAP65_GAIN].y1=hg_y0-text_height;
955 hgbutt[HG_MAP65_GAIN].y2=hg_y0;
956 hgbutt[HG_MAP65_STRONG].x1=hgbutt[HG_MAP65_GAIN].x2+text_width/2;
957 hgbutt[HG_MAP65_STRONG].x2=hgbutt[HG_MAP65_STRONG].x1+3*text_width/2;
958 hgbutt[HG_MAP65_STRONG].y1=hg_y0-text_height;
959 hgbutt[HG_MAP65_STRONG].y2=hg_y0;
960 show_map65=(genparm[SECOND_FFT_ENABLE] != 0 &&
961                           (ui.network_flag & NET_RXOUT_TIMF2) );
962 for(i=0; i<screen_width*ui.rx_rf_channels; i++) hg_spectrum[i]=(short int)hg_y0;
963 if(kill_all_flag) return;
964 timf2_hg_xmax=hg.xright-2*text_width-2;
965 timf2_hg_y[1]=y;
966 timf2_hg_y[0]=y-text_height/2;
967 timf2_hg_x[0]=0;
968 if(sw_onechan)
969   {
970   timf2_hg_yh=text_height;
971   }
972 else
973   {
974   timf2_hg_yh=text_height/2;
975   timf2_hg_x[1]=0;
976   }
977 lir_fillbox(timf2_hg_xmin,timf2_hg_y[0],
978                                 timf2_hg_xmax-timf2_hg_xmin+1,text_height,8);
979 // timf2 is 16 bit, level is 0 to 32767 (+ or -)
980 // Make a logarithmic scale that uses all pixels for the power level.
981 t1=1;
982 t2=32767.F*32767.F;
983 for(i=0; i<4; i++)
984   {
985   timf2_hg_xfac=(float)log(t2/t1)/((float)(timf2_hg_xmax-timf2_hg_xmin)+0.5F);
986   t1=(float)exp(timf2_hg_xfac);
987   }
988 timf2_hg_xfac=1/timf2_hg_xfac;
989 timf2_hg_xlog=1/t1;
990 timf2_hg_stux=-1;
991 timf2_hg_clex=-1;
992 // Set the quantisation error limit to some reasonable value (20dB = 100)
993 t1=100;
994 timf2_hg_qex=(int)(log(timf2_hg_xlog*t1)*timf2_hg_xfac);
995 lir_line(timf2_hg_xmin+timf2_hg_qex,timf2_hg_y[0],
996                      timf2_hg_xmin+timf2_hg_qex,timf2_hg_y[0]+text_height,12);
997 if(kill_all_flag) return;
998 make_modepar_file(GRAPHTYPE_HG);
999 hg_flag=1;
1000 fft2_nb=(fft2_na-hg.spek_avgnum+max_fft2n)&fft2n_mask;
1001 hg_cury2=hg.ybottom-3*text_height/2;
1002 hg_cury1=hg_stonbars_ytop;
1003 hg_cury0=(hg_cury1+4*hg_cury2)/5;
1004 // Get the number of pixels we have vertically for control bars.
1005 hg_floatypix=hg_ston_y0-hg.ytop-2*text_height;
1006 hg_ston1_y=hg_ston_y0-(int)(hg_floatypix*log10(hg.blanker_ston_fft1)/HG_STON_RANGE);
1007 hg_ston2_y=hg_ston_y0-(int)(hg_floatypix*log10(hg.blanker_ston_fft2)/HG_STON_RANGE);
1008 hg_ston1_yold=-1;
1009 hg_ston2_yold=-1;
1010 make_blanker_ston1();
1011 make_blanker_ston2();
1012 hg_center=0;
1013 if(kill_all_flag)return;
1014 afc_curx=-1;
1015 sc[SC_HG_Y_SCALE]++;
1016 sc[SC_BLANKER_INFO]++;
1017 sc[SC_HG_FQ_SCALE]++;
1018 sc[SC_SHOW_FFT2]++;
1019 hg_map65_gain=(float)pow(10.0,-hg.map65_gain_db/20.);
1020 if(show_map65)sc[SC_SHOW_MAP65]++;
1021 resume_thread(THREAD_SCREEN);
1022 lir_set_event(EVENT_SCREEN);
1023 if(genparm[AFC_ENABLE] != 0)sc[SC_AFC_CURSOR]++;
1024 }
1025 
1026 
init_hires_graph(void)1027 void init_hires_graph(void)
1028 {
1029 if (read_modepar_file(GRAPHTYPE_HG) == 0)
1030   {
1031 hg_default:;
1032 // Make the default window for the high resolution graph.
1033   hg.xleft=0;
1034   hg.xright=(int)(0.4F*(float)screen_width);
1035   hg.ytop=wg.ybottom+2;
1036   hg.ybottom=hg.ytop+(int)(0.3F*(float)screen_height);
1037   if(hg.ybottom>screen_height-text_height-1)
1038     {
1039     hg.ybottom=screen_height-text_height-1;
1040     hg.ytop=hg.ybottom-6*text_height;
1041     }
1042   hg.stupid_bln_mode=1;
1043   hg.clever_bln_mode=1;
1044   hg.stupid_bln_factor=5;
1045   hg.clever_bln_factor=10;
1046   hg.stupid_bln_limit=(unsigned int)((float)timf2_noise_floor*hg.stupid_bln_factor);
1047   hg.clever_bln_limit=(unsigned int)((float)timf2_noise_floor*hg.clever_bln_factor);
1048   hg.blanker_ston_fft1=30;
1049   hg.blanker_ston_fft2=30;
1050   hg.timf2_display=0;
1051   hg.timf2_display_lines=0;
1052   hg.timf2_display_hold=0;
1053   hg.timf2_display_wk_gain=1;
1054   hg.timf2_display_st_gain=1;
1055   hg.spek_zero=500;
1056   hg.spek_gain=500;
1057   hg.check = HG_VERNR;
1058   hg.map65_gain_db=0;
1059   hg.map65_strong=1;
1060   }
1061 if(hg.check != HG_VERNR)goto hg_default;
1062 if(hg.xleft < 0 || hg.xright > screen_last_xpixel)goto hg_default;
1063 if(hg.xright-hg.xleft<4*text_width)goto hg_default;
1064 if(hg.ytop < 0 || hg.ybottom > screen_height-1)goto hg_default;
1065 if(hg.ybottom-hg.ytop < 4*text_height+5)goto hg_default;
1066 if( (fft1_calibrate_flag&CALAMP)!=CALAMP)hg.clever_bln_mode=0;
1067 if(hg.stupid_bln_mode <0 || hg.stupid_bln_mode >2)goto hg_default;
1068 if(hg.clever_bln_mode <0 || hg.clever_bln_mode >2)goto hg_default;
1069 if(hg.stupid_bln_factor<0.7 || hg.stupid_bln_factor> 1000)goto hg_default;
1070 if(hg.clever_bln_factor<0.7 || hg.clever_bln_factor> 1000)goto hg_default;
1071 if(hg.map65_gain_db < 0)hg.map65_gain_db=0;
1072 if(hg.map65_gain_db > 15)hg.map65_gain_db=15;
1073 hg.map65_strong&=1;
1074 if(hg.spek_avgnum<1)hg.spek_avgnum=1;
1075 if(hg.spek_avgnum>fft2n_mask)hg.spek_avgnum=fft2n_mask;
1076 if(hg.blanker_ston_fft1<1.5)hg.blanker_ston_fft1=20;
1077 if(hg.blanker_ston_fft2<5)hg.blanker_ston_fft2=30;
1078 hires_graph_scro=no_of_scro;
1079 if(ui.operator_skil != OPERATOR_SKIL_EXPERT)hg.timf2_display=0;
1080 make_hires_graph(FALSE);
1081 no_of_scro++;
1082 if(no_of_scro >= MAX_SCRO)lirerr(89);
1083 }
1084 
1085