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 #include "globdef.h"
25 #include "uidef.h"
26 #include "seldef.h"
27 #include "screendef.h"
28 #include "hwaredef.h"
29 #include "fft1def.h"
30 #include "rusage.h"
31 #include "thrdef.h"
32 #include "sdrdef.h"
33 
34 int freq_graph_scro;
35 int fg_old_y1;
36 int fg_old_y2;
37 int fg_old_x1;
38 int fg_old_x2;
39 void make_freq_graph(int clear_old);
40 
check_fg_borders(void)41 void check_fg_borders(void)
42 {
43 current_graph_minh=FG_VSIZ;
44 if(ui.operator_skil == OPERATOR_SKIL_NEWCOMER)current_graph_minh+=text_height+4;
45 current_graph_minw=FG_HSIZ;
46 check_graph_placement((void*)(&fg));
47 set_graph_minwidth((void*)(&fg));
48 }
49 
check_filtercorr_direction(void)50 void check_filtercorr_direction(void)
51 {
52 int i,j,k,mm;
53 float t1,t2;
54 if( fft1_filtercorr_direction*fft1_direction < 0 )
55   {
56   fft1_filtercorr_direction = fft1_direction;
57   mm=2*ui.rx_rf_channels;
58   k=fft1_size;
59   for(i=0; i<fft1_size/2; i++)
60     {
61     k--;
62     for(j=0; j<mm; j+=2)
63       {
64       t1=fft1_filtercorr[mm*i+j];
65       t2=fft1_filtercorr[mm*i+j+1];
66       fft1_filtercorr[mm*i+j]=fft1_filtercorr[mm*k+j+1];
67       fft1_filtercorr[mm*i+j+1]=fft1_filtercorr[mm*k+j];
68       fft1_filtercorr[mm*k+j]=t2;
69       fft1_filtercorr[mm*k+j+1]=t1;
70       }
71     t1=fft1_desired[i];
72     fft1_desired[i]=fft1_desired[k];
73     fft1_desired[k]=t1;
74     }
75   for(i=0; i<fft1_size; i++)fft1_slowsum[i]=0;
76   for(i=0; i<fft1_sumsq_bufsize; i++)fft1_sumsq[i]=0;
77   }
78 if(fg.passband_center != 0)
79   {
80   frequency_scale_offset=fg.passband_center*10L-(double)timf1_sampling_speed/200000L;
81   }
82 else
83   {
84   frequency_scale_offset=0;
85   }
86 if( (ui.converter_mode & CONVERTER_USE) != 0)
87   {
88   if( (ui.converter_mode & CONVERTER_UP) == 0)
89     {
90     if( (ui.converter_mode & CONVERTER_LO_BELOW) != 0)
91       {
92       frequency_scale_offset+=10*converter_offset_mhz;
93       }
94     else
95       {
96       frequency_scale_offset=10*converter_offset_mhz-frequency_scale_offset-timf1_sampling_speed/100000;
97       }
98     }
99   else
100     {
101     frequency_scale_offset-=10*converter_offset_mhz;
102     }
103   }
104 frequency_scale_offset+=0.00001*rx_hware_fqshift;
105 rx_passband_center_mhz=0.1*frequency_scale_offset+timf1_sampling_speed/2000000;
106 frequency_scale_offset_hz=100000*frequency_scale_offset;
107 }
108 
109 
show_hardware_gain(void)110 void show_hardware_gain(void)
111 {
112 char s[80];
113 sprintf(s,"%3d dB",fg.gain);
114 lir_pixwrite(fg.xleft+2.5*text_width,fg.ybottom-text_height,s);
115 }
116 
copy_txfreq_to_rx(void)117 void copy_txfreq_to_rx(void)
118 {
119 double dt1;
120 if(use_tx == 0)return;
121 fg.passband_center=tg.freq;
122 set_hardware_rx_frequency();
123 dt1=1000000*tg.freq-100000*frequency_scale_offset;
124 make_new_signal(0, dt1);
125 sc[SC_SHOW_CENTER_FQ]++;
126 make_modepar_file(GRAPHTYPE_FG);
127 }
128 
new_center_frequency(void)129 void new_center_frequency(void)
130 {
131 double dt1;
132 if(numinput_double_data < 0)goto errinp;
133 numinput_double_data*=10000L;
134 numinput_double_data=rint(numinput_double_data);
135 numinput_double_data=numinput_double_data/10000L;
136 if( (ui.converter_mode & CONVERTER_USE) != 0)
137   {
138   if( (ui.converter_mode & CONVERTER_UP) == 0)
139     {
140     if( (ui.converter_mode & CONVERTER_LO_BELOW) != 0)
141       {
142       dt1=numinput_double_data-converter_offset_mhz;
143       }
144     else
145       {
146       dt1=converter_offset_mhz-numinput_double_data;
147       }
148     }
149   else
150     {
151     dt1=numinput_double_data+converter_offset_mhz;
152     }
153   }
154 else
155   {
156   dt1=numinput_double_data;
157   }
158 if(dt1 < 0)goto errinp;
159 if(ui.rx_addev_no == PERSEUS_DEVICE_CODE)
160   {
161   if(dt1*1000000+0.5 >= PERSEUS_SAMPLING_CLOCK/2)
162     {
163 errinp:;
164     sc[SC_SHOW_CENTER_FQ]++;
165     return;
166     }
167   }
168 fg.passband_center=dt1;
169 set_hardware_rx_frequency();
170 sc[SC_SHOW_CENTER_FQ]++;
171 make_modepar_file(GRAPHTYPE_FG);
172 }
173 
new_freq_step(void)174 void new_freq_step(void)
175 {
176 if(numinput_double_data >= 0.0001 && numinput_double_data <= 10.1)
177   {
178   fg.passband_increment=numinput_double_data;
179   make_modepar_file(GRAPHTYPE_FG);
180   }
181 sc[SC_SHOW_CENTER_FQ]++;
182 }
183 
new_rx_gain_value(void)184 void new_rx_gain_value(void)
185 {
186 fg.gain=numinput_int_data;
187 set_hardware_rx_gain();
188 pause_screen_and_hide_mouse();
189 show_hardware_gain();
190 resume_thread(THREAD_SCREEN);
191 make_modepar_file(GRAPHTYPE_FG);
192 }
193 
help_on_freq_graph(void)194 void help_on_freq_graph(void)
195 {
196 int msg_no;
197 int event_no;
198 if(mouse_y <= fg.yborder)
199   {
200   msg_no=84;
201   }
202 else
203   {
204   msg_no=87;
205   }
206 for(event_no=0; event_no<MAX_FGBUTT; event_no++)
207   {
208   if( fgbutt[event_no].x1 <= mouse_x &&
209       fgbutt[event_no].x2 >= mouse_x &&
210       fgbutt[event_no].y1 <= mouse_y &&
211       fgbutt[event_no].y2 >= mouse_y)
212     {
213     switch (event_no)
214       {
215       case FG_TOP:
216       case FG_BOTTOM:
217       case FG_LEFT:
218       case FG_RIGHT:
219       msg_no=101;
220       break;
221 
222       case FG_INCREASE_FQ:
223       msg_no=83;
224       break;
225 
226       case FG_DECREASE_FQ:
227       msg_no=82;
228       break;
229 
230       case FG_INCREASE_GAIN:
231       msg_no=85;
232       break;
233 
234       case FG_DECREASE_GAIN:
235       msg_no=86;
236       break;
237       }
238     }
239   }
240 help_message(msg_no);
241 }
242 
243 
244 
245 
mouse_continue_freq_graph(void)246 void mouse_continue_freq_graph(void)
247 {
248 int i, j;
249 switch (mouse_active_flag-1)
250   {
251   case FG_TOP:
252   if(fg.ytop!=mouse_y)goto fgm;
253   break;
254 
255   case FG_BOTTOM:
256   if(fg.ybottom!=mouse_y)goto fgm;
257   break;
258 
259   case FG_LEFT:
260   if(fg.xleft!=mouse_x)goto fgm;
261   break;
262 
263   case FG_RIGHT:
264   if(fg.xright==mouse_x)break;
265 fgm:;
266   pause_screen_and_hide_mouse();
267   dual_graph_borders((void*)&fg,0);
268   if(fg_oldx==-10000)
269     {
270     fg_oldx=mouse_x;
271     fg_oldy=mouse_y;
272     }
273   else
274     {
275     i=mouse_x-fg_oldx;
276     j=mouse_y-fg_oldy;
277     fg_oldx=mouse_x;
278     fg_oldy=mouse_y;
279     fg.ytop+=j;
280     fg.ybottom+=j;
281     fg.xleft+=i;
282     fg.xright+=i;
283     check_fg_borders();
284     fg.yborder=(fg.ytop+fg.ybottom)>>1;
285     }
286   dual_graph_borders((void*)&fg,15);
287   resume_thread(THREAD_SCREEN);
288   break;
289 
290   default:
291   goto await_release;
292   }
293 if(leftpressed == BUTTON_RELEASED)goto finish;
294 return;
295 await_release:;
296 if(leftpressed != BUTTON_RELEASED) return;
297 if(ui.network_flag != 2)
298   {
299   switch (mouse_active_flag-1)
300     {
301     case FG_INCREASE_FQ:
302     if(hware_flag == 0)
303       {
304       fg.passband_center+=fg.passband_increment;
305       set_hardware_rx_frequency();
306       }
307     break;
308 
309     case FG_DECREASE_FQ:
310     if(hware_flag == 0)
311       {
312       fg.passband_center-=fg.passband_increment;
313       set_hardware_rx_frequency();
314       }
315     break;
316 
317     case FG_INCREASE_GAIN:
318     if(hware_flag == 0)
319       {
320       fg.gain+=fg.gain_increment;
321       set_hardware_rx_gain();
322       }
323     break;
324 
325     case FG_DECREASE_GAIN:
326     if(hware_flag == 0)
327       {
328       fg.gain-=fg.gain_increment;
329       set_hardware_rx_gain();
330       }
331     break;
332 
333     default:
334     lirerr(872);
335     break;
336     }
337   }
338 finish:;
339 leftpressed=BUTTON_IDLE;
340 mouse_active_flag=0;
341 make_freq_graph(TRUE);
342 fg_oldx=-10000;
343 }
344 
mouse_on_freq_graph(void)345 void mouse_on_freq_graph(void)
346 {
347 int event_no;
348 // First find out is we are on a button or border line.
349 numinput_flag=0;
350 for(event_no=0; event_no<MAX_FGBUTT; event_no++)
351   {
352   if( fgbutt[event_no].x1 <= mouse_x &&
353       fgbutt[event_no].x2 >= mouse_x &&
354       fgbutt[event_no].y1 <= mouse_y &&
355       fgbutt[event_no].y2 >= mouse_y)
356     {
357     fg_old_y1=fg.ytop;
358     fg_old_y2=fg.ybottom;
359     fg_old_x1=fg.xleft;
360     fg_old_x2=fg.xright;
361     if(rightpressed == BUTTON_IDLE)
362       {
363       mouse_active_flag=1+event_no;
364       current_mouse_activity=mouse_continue_freq_graph;
365       return;
366       }
367     else
368       {
369       current_mouse_activity=mouse_nothing;
370       mouse_active_flag=1;
371       return;
372       }
373     }
374   }
375 // Not button or border.
376 // Prompt the user for a new center frequency from keyboard.
377 if(ui.network_flag != 2)
378   {
379   if(hware_flag == 0)
380     {
381     numinput_xpix=fg.xleft+2.5*text_width;
382     if(mouse_y < fg.yborder)
383       {
384       numinput_ypix=fg.yborder-text_height-1;
385       numinput_chars=FREQ_MHZ_DIGITS+FREQ_MHZ_DECIMALS+1;
386       erase_numinput_txt();
387       numinput_flag=FIXED_DOUBLE_PARM;
388       if(rightpressed == BUTTON_IDLE)
389         {
390         par_from_keyboard_routine=new_center_frequency;
391         }
392       else
393         {
394         par_from_keyboard_routine=new_freq_step;
395         }
396       }
397     else
398       {
399       if(diskread_flag < 2 && rightpressed == BUTTON_IDLE)
400         {
401         numinput_ypix=fg.ybottom-text_height;
402         numinput_chars=4;
403         erase_numinput_txt();
404         numinput_flag=FIXED_INT_PARM;
405         par_from_keyboard_routine=new_rx_gain_value;
406         }
407       else
408         {
409         current_mouse_activity=mouse_nothing;
410         }
411       }
412     }
413   else
414     {
415     current_mouse_activity=mouse_nothing;
416     }
417   }
418 else
419   {
420   current_mouse_activity=mouse_nothing;
421   }
422 mouse_active_flag=1;
423 }
424 
make_freq_graph(int clear_old)425 void make_freq_graph(int clear_old)
426 {
427 pause_thread(THREAD_SCREEN);
428 if(clear_old)
429   {
430   hide_mouse(fg_old_x1,fg_old_x2,fg_old_y1,fg_old_y2);
431   lir_fillbox(fg_old_x1,fg_old_y1,fg_old_x2-fg_old_x1+1,
432                                                     fg_old_y2-fg_old_y1+1,0);
433   }
434 fg_flag=1;
435 check_fg_borders();
436 clear_button(fgbutt, MAX_FGBUTT);
437 hide_mouse(fg.xleft,fg.xright,fg.ytop,fg.ybottom);
438 fg.yborder=(fg.ytop+fg.ybottom)>>1;
439 if(ui.operator_skil == OPERATOR_SKIL_NEWCOMER)
440   {
441   fg.yborder+=text_height/2+2;
442   lir_pixwrite(fg.xleft+2, fg.ytop+text_height/2-2,"Center Freq");
443   }
444 scro[freq_graph_scro].no=FREQ_GRAPH;
445 scro[freq_graph_scro].x1=fg.xleft;
446 scro[freq_graph_scro].x2=fg.xright;
447 scro[freq_graph_scro].y1=fg.ytop;
448 scro[freq_graph_scro].y2=fg.ybottom;
449 fgbutt[FG_LEFT].x1=fg.xleft;
450 fgbutt[FG_LEFT].x2=fg.xleft+2;
451 fgbutt[FG_LEFT].y1=fg.ytop;
452 fgbutt[FG_LEFT].y2=fg.ybottom;
453 fgbutt[FG_RIGHT].x1=fg.xright;
454 fgbutt[FG_RIGHT].x2=fg.xright-2;
455 fgbutt[FG_RIGHT].y1=fg.ytop;
456 fgbutt[FG_RIGHT].y2=fg.ybottom;
457 fgbutt[FG_TOP].x1=fg.xleft;
458 fgbutt[FG_TOP].x2=fg.xright;
459 fgbutt[FG_TOP].y1=fg.ytop;
460 fgbutt[FG_TOP].y2=fg.ytop+2;
461 fgbutt[FG_BOTTOM].x1=fg.xleft;
462 fgbutt[FG_BOTTOM].x2=fg.xright;
463 fgbutt[FG_BOTTOM].y1=fg.ybottom-2;
464 fgbutt[FG_BOTTOM].y2=fg.ybottom;
465 // Draw the border lines
466 dual_graph_borders((void*)&fg,7);
467 fg_oldx=-10000;
468 settextcolor(7);
469 make_button(fg.xleft+text_width,fg.yborder-text_height/2-2,
470                                          fgbutt,FG_DECREASE_FQ,25);
471 make_button(fg.xright-text_width,fg.yborder-text_height/2-2,
472                                      fgbutt,FG_INCREASE_FQ,24);
473 make_button(fg.xleft+text_width,fg.ybottom-text_height/2-2,
474                                          fgbutt,FG_DECREASE_GAIN,25);
475 make_button(fg.xright-text_width,fg.ybottom-text_height/2-2,
476                                      fgbutt,FG_INCREASE_GAIN,24);
477 show_hardware_gain();
478 resume_thread(THREAD_SCREEN);
479 sc[SC_SHOW_CENTER_FQ]++;
480 make_modepar_file(GRAPHTYPE_FG);
481 }
482 
read_freq_control_data(void)483 void read_freq_control_data(void)
484 {
485 if (read_modepar_file(GRAPHTYPE_FG) == 0)
486   {
487   fg.xleft=0;
488   fg.xright=FG_HSIZ;
489   fg.ytop=0.75*screen_height;
490   fg.ybottom=fg.ytop+FG_VSIZ;
491   switch (ui.rx_addev_no)
492     {
493     case SDR14_DEVICE_CODE:
494     case SDRIQ_DEVICE_CODE:
495     case PERSEUS_DEVICE_CODE:
496     case SDRIP_DEVICE_CODE:
497     case EXCALIBUR_DEVICE_CODE:
498     case BLADERF_DEVICE_CODE:
499     case OPENHPSDR_DEVICE_CODE:
500     case NETAFEDRI_DEVICE_CODE:
501     fg.passband_center=7.0;
502     fg.passband_direction=1;
503     fg.gain=0;
504     fg.gain_increment=5;
505     fg.passband_increment=0.1;
506     break;
507 
508     case MIRISDR_DEVICE_CODE:
509     case RTL2832_DEVICE_CODE:
510     fg.passband_center=97.0;
511     fg.passband_direction=1;
512     fg.gain=15;
513     fg.gain_increment=5;
514     fg.passband_increment=0.5;
515     break;
516 
517     default:
518     fg.passband_center=7;
519     fg.passband_direction=1;
520     fg.gain=0;
521     fg.gain_increment=0;
522     fg.passband_increment=0.05;
523     break;
524     }
525   make_modepar_file(GRAPHTYPE_FG);
526   }
527 if(diskread_flag == 2)
528   {
529   fg.passband_direction=fft1_direction;
530   }
531 else
532   {
533   fft1_direction=fg.passband_direction;
534   }
535 check_filtercorr_direction();
536 }
537 
538 
init_freq_control(void)539 void init_freq_control(void)
540 {
541 clear_hware_data();
542 freq_graph_scro=no_of_scro;
543 make_freq_graph(FALSE);
544 no_of_scro++;
545 if(no_of_scro >= MAX_SCRO)lirerr(89);
546 set_hardware_rx_frequency();
547 }
548