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