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 <ctype.h>
25 #include <unistd.h>
26 #include <string.h>
27
28
29
30 #include "globdef.h"
31 #if(OSNUM == OSNUM_WINDOWS)
32 #include <winsock.h>
33 #define INVSOCK INVALID_SOCKET
34 #endif
35
36 #if(OSNUM == OSNUM_LINUX)
37 #define INVSOCK -1
38 #include "lconf.h"
39 #if (ALSA_PRESENT == 1)
40 #include <alsa/asoundlib.h>
41 int alsa_get_native_samplerate(int n,int mode,int *line,unsigned int *new_sampling_rate);
42 #endif
43 #endif
44
45
46
47 #include "uidef.h"
48 #include "fft1def.h"
49 #include "fft2def.h"
50 #include "screendef.h"
51 #include "powtdef.h"
52 #include "vernr.h"
53 #include "sigdef.h"
54 #include "seldef.h"
55 #include "rusage.h"
56 #include "thrdef.h"
57 #include "sdrdef.h"
58 #include "caldef.h"
59 #include "conf.h"
60 #include "keyboard_def.h"
61 #include "txdef.h"
62 #include "options.h"
63 #include "hwaredef.h"
64 #include "fft3def.h"
65 #include "padef.h"
66
67 extern int tune_bytes;
68 #if (USERS_EXTRA_PRESENT == 1)
69 extern void init_users_extra(void);
70 #endif
71
72 char *parfilnam;
73 int uiparm_save[MAX_UIPARM];
74 int dirflag, iqflag;
75 void lir_fix_bug(int bug);
76 int first_txproc_no;
77
enable_extio(void)78 void enable_extio(void)
79 {
80 if(diskread_flag == 0 && ui.use_extio != 0)
81 {
82 command_extio_library(EXTIO_COMMAND_LOAD_DLL);
83 first_check_extio();
84 if(ui.use_extio == 0)
85 {
86 lir_status=LIR_SAVE_UIPARM;
87 return;
88 }
89 if(extio_handle==NULL)
90 {
91 lirerr(42977);
92 return;
93 }
94 extio_show_gui=TRUE;
95 command_extio_library(EXTIO_COMMAND_START);
96 }
97 }
98
disable_extio(void)99 void disable_extio(void)
100 {
101 if(extio_running)command_extio_library(EXTIO_COMMAND_STOP);
102 if(extio_handle != NULL)
103 {
104 clear_screen();
105 lir_text(3,3,"UNLOADING ExtIO LIBRARY");
106 lir_refresh_screen();
107 lir_sleep(100000);
108 command_extio_library(EXTIO_COMMAND_UNLOAD_DLL);
109 }
110 }
111
radar_routine(void)112 void radar_routine(void)
113 {
114 char s[80];
115 float t1;
116 int i, k, m;
117 use_bfo=1;
118 usercontrol_mode=USR_NORMAL_RX;
119 if(read_txpar_file()==FALSE)use_tx=0;
120 get_wideband_sizes();
121 if(kill_all_flag)return;
122 get_buffers(1);
123 if(kill_all_flag || lir_status != LIR_OK)return;
124 if(!freq_from_file)
125 {
126 read_freq_control_data();
127 }
128 check_filtercorr_direction();
129 init_semaphores();
130 init_wide_graph();
131 if( genparm[SECOND_FFT_ENABLE] != 0 )init_blanker();
132 if(kill_all_flag || lir_status != LIR_OK) goto radar_x;
133 if(genparm[SECOND_FFT_ENABLE] != 0)
134 {
135 init_hires_graph();
136 if(kill_all_flag || lir_status != LIR_OK) goto radar_x;
137 }
138 if(genparm[AFC_ENABLE] != 0)
139 {
140 init_afc_graph();
141 if(kill_all_flag || lir_status != LIR_OK) goto radar_x;
142 }
143 if(ui.rx_rf_channels == 2)
144 {
145 init_pol_graph();
146 if(kill_all_flag || lir_status != LIR_OK) goto radar_x;
147 }
148 init_radar_graph();
149 if(kill_all_flag || lir_status != LIR_OK) goto radar_x;
150 if(!freq_from_file)
151 {
152 init_freq_control();
153 if(kill_all_flag || lir_status != LIR_OK) goto radar_x;
154 }
155 if(use_tx != 0)
156 {
157 // Get the xxproc file that the user stored in tg.spproc_no
158 init_tx_graph();
159 if(read_txpar_file()==FALSE)
160 {
161 // If it failed, read the one that was succesful before.
162 tg.spproc_no=first_txproc_no;
163 read_txpar_file();
164 }
165 }
166 // Make sure users_init_mode is the last window(s) we open.
167 // the avoid collission routine does not know where
168 // users windows are placed.
169 if(ui.soundcard_radio == SOUNDCARD_RADIO_ELEKTOR &&
170 diskread_flag == 0)
171 {
172 if(init_elektor_control_window() != EXIT_SUCCESS)ui.soundcard_radio=0;
173 }
174 #if LIBUDEV_PRESENT == 1
175 if(ui.soundcard_radio == SOUNDCARD_RADIO_FCDPROPLUS &&
176 diskread_flag == 0)
177 {
178 init_fcdproplus_control_window();
179 }
180 if(ui.soundcard_radio == SOUNDCARD_RADIO_AFEDRI_USB &&
181 diskread_flag == 0)
182 {
183 open_afedriusb_control();
184 }
185 #endif
186 users_init_mode();
187 if(kill_all_flag || lir_status != LIR_OK) goto radar_x;
188 show_name_and_size();
189 linrad_thread_create(rx_input_thread);
190 lir_sleep(100000);
191 if(lir_status != LIR_OK)
192 {
193 lir_join(rx_input_thread);
194 goto radar_x;
195 }
196 if(kill_all_flag) goto radar_x;
197 linrad_thread_create(THREAD_USER_COMMAND);
198 if(kill_all_flag) goto radar_x;
199 linrad_thread_create(THREAD_RADAR);
200 if(kill_all_flag) goto radar_x;
201 linrad_thread_create(THREAD_WIDEBAND_DSP);
202 if(kill_all_flag) goto radar_x;
203 linrad_thread_create(THREAD_SCREEN);
204 if(kill_all_flag) goto radar_x;
205 if((ui.network_flag&NET_RX_OUTPUT)!=0)
206 {
207 linrad_thread_create(THREAD_LIR_SERVER);
208 if(kill_all_flag) goto radar_x;
209 }
210 if(use_tx != 0 )
211 {
212 init_txmem_cwproc();
213 if(kill_all_flag)goto radar_x;
214 linrad_thread_create(THREAD_TX_INPUT);
215 if(kill_all_flag) goto radar_x;
216 linrad_thread_create(THREAD_TX_OUTPUT);
217 if(kill_all_flag) goto radar_x;
218 }
219 fft1_waterfall_flag=1;
220 lir_refresh_screen();
221 all_threads_started=TRUE;
222 lir_sleep(50000);
223 rxin_block_counter=0;
224 i=0;
225 k=0;
226 t1=50000+2000000./snd[RXAD].interrupt_rate;
227 if(diskread_flag < 2)
228 {
229 while(!kill_all_flag &&
230 thread_status_flag[THREAD_USER_COMMAND]==THRFLAG_ACTIVE)
231 {
232 m=30;
233 while(!kill_all_flag && m>0 && rxin_block_counter == i)
234 {
235 m--;
236 lir_sleep(t1);
237 }
238 if(rxin_block_counter == i && i!=0)
239 {
240 sprintf(s,"No input %d",k);
241 lir_text(0,screen_last_line,s);
242 lir_refresh_screen();
243 }
244 k++;
245 if(k==10000)k=1;
246 i=rxin_block_counter;
247 }
248 m=30;
249 while(!kill_all_flag && m>0 && rxin_block_counter == i)
250 {
251 m--;
252 lir_sleep(t1);
253 }
254 if(rxin_block_counter == i && i!=0)
255 {
256 sprintf(s,"No input %d",k);
257 lir_text(0,screen_last_line,s);
258 lir_refresh_screen();
259 lirerr(1284);
260 }
261 }
262 lir_join(THREAD_USER_COMMAND);
263 if(use_tx != 0)
264 {
265 linrad_thread_stop_and_join(THREAD_TX_INPUT);
266 linrad_thread_stop_and_join(THREAD_TX_OUTPUT);
267 close_tx_sndin();
268 close_tx_sndout();
269 if(txmem_handle != NULL)free(txmem_handle);
270 txmem_handle=NULL;
271 lir_close_event(EVENT_TX_INPUT);
272 }
273 linrad_thread_stop_and_join(rx_input_thread);
274 linrad_thread_stop_and_join(THREAD_SCREEN);
275 linrad_thread_stop_and_join(THREAD_RADAR);
276 if((ui.network_flag&NET_RX_OUTPUT)!=0)
277 {
278 linrad_thread_stop_and_join(THREAD_LIR_SERVER);
279 }
280 linrad_thread_stop_and_join(THREAD_WIDEBAND_DSP);
281 radar_x:;
282 #if LIBUDEV_PRESENT == 1
283 if(ui.soundcard_radio == SOUNDCARD_RADIO_AFEDRI_USB &&
284 diskread_flag == 0)
285 {
286 close_afedriusb_control();
287 }
288 #endif
289 free_semaphores();
290 }
291
tune_wse_routine(void)292 void tune_wse_routine(void)
293 {
294 usercontrol_mode=USR_TUNE;
295 genparm[SECOND_FFT_ENABLE]=0;
296 get_wideband_sizes();
297 if(kill_all_flag)return;
298 clear_screen();
299 if( (ui.rx_input_mode&IQ_DATA) == 0 ||
300 (ui.rx_rf_channels == 1) ||
301 ui.rx_ad_speed != 96000)
302 {
303 settextcolor(14);
304 lir_text(10,10,"Incorrect soundcard settings");
305 lir_text(5,12,"Set ""Two Rx channels I/Q data"", 96 kHz and 32 bit.");
306 settextcolor(7);
307 lir_text(13,14,press_any_key);
308 await_processed_keyboard();
309 lir_status=LIR_TUNEERR;
310 return;
311 }
312 get_buffers(1);
313 if(kill_all_flag || lir_status != LIR_OK)return;
314 // Collect data during TUNETIME seconds.
315 #define TUNETIME 0.1
316 tune_bytes=96000*TUNETIME;
317 if(tune_bytes < 2*fft1_size)tune_bytes=2*fft1_size;
318 tune_bytes*=snd[RXAD].framesize;
319 tune_bytes/=timf1_blockbytes;
320 tune_bytes++;
321 tune_bytes*=timf1_blockbytes;
322 if(tune_bytes < 2*fft1_size*(int)snd[RXAD].framesize)
323 {
324 lir_text(5,5,"Set fft1 bandwidth higher.");
325 lir_text(5,7,press_any_key);
326 await_processed_keyboard();
327 return;
328 }
329 if(fft1_desired[0] > .99 || bal_updflag == 1)
330 {
331 settextcolor(14);
332 lir_text(3,10,"Calibrate the RX2500 (Read z_CALIBRATE.txt)");
333 settextcolor(7);
334 lir_text(5,13,press_any_key);
335 await_processed_keyboard();
336 return;
337 }
338 lir_inkey=0;
339 init_semaphores();
340 linrad_thread_create(rx_input_thread);
341 lir_sleep(100000);
342 if(lir_status != LIR_OK)
343 {
344 lir_join(rx_input_thread);
345 goto tune_x;
346 }
347 if(kill_all_flag) goto tune_x;
348 linrad_thread_create(THREAD_TUNE);
349 if(kill_all_flag) goto tune_x;
350 linrad_thread_create(THREAD_USER_COMMAND);
351 lir_sleep(50000);
352 lir_refresh_screen();
353 all_threads_started=TRUE;
354 lir_join(THREAD_USER_COMMAND);
355 linrad_thread_stop_and_join(rx_input_thread);
356 linrad_thread_stop_and_join(THREAD_TUNE);
357 tune_x:;
358 free_semaphores();
359 }
360
361
rx_adtest_routine(void)362 void rx_adtest_routine(void)
363 {
364 usercontrol_mode=USR_ADTEST;
365 genparm[SECOND_FFT_ENABLE]=0;
366 get_wideband_sizes();
367 if(kill_all_flag)return;
368 get_buffers(1);
369 if(kill_all_flag || lir_status != LIR_OK)return;
370 init_semaphores();
371 linrad_thread_create(rx_input_thread);
372 lir_sleep(100000);
373 if(lir_status != LIR_OK)
374 {
375 lir_join(rx_input_thread);
376 goto adtest_x;
377 }
378 if(kill_all_flag) goto adtest_x;
379 linrad_thread_create(THREAD_USER_COMMAND);
380 if(kill_all_flag) goto adtest_x;
381 linrad_thread_create(THREAD_RX_ADTEST);
382 lir_sleep(50000);
383 lir_refresh_screen();
384 all_threads_started=TRUE;
385 lir_join(THREAD_USER_COMMAND);
386 linrad_thread_stop_and_join(rx_input_thread);
387 linrad_thread_stop_and_join(THREAD_RX_ADTEST);
388 adtest_x:;
389 free_semaphores();
390 }
391
txtest_routine(void)392 void txtest_routine(void)
393 {
394 int i;
395 usercontrol_mode=USR_TXTEST;
396 if(ui.network_flag != 0 || diskread_flag != 0)
397 {
398 lirerr(1158);
399 return;
400 }
401 if( (ui.rx_input_mode&IQ_DATA) != 0)
402 {
403 ui.rx_ad_channels=2;
404 }
405 else
406 {
407 ui.rx_ad_channels=1;
408 }
409 ui.rx_input_mode&=-1-TWO_CHANNELS;
410 ui.rx_rf_channels=1;
411 genparm[AFC_ENABLE]=0;
412 genparm[SECOND_FFT_ENABLE]=0;
413 get_wideband_sizes();
414 if(kill_all_flag) return;
415 // Open the graph windows on the screen.
416 // Note that they must be opened in this order because
417 // Each window is placed outside the previous ones and the init
418 // routines assumes the order below and does not check for all possible
419 // conflicts.
420 get_buffers(1);
421 if(kill_all_flag)return;
422 if(lir_status != LIR_OK)return;
423 read_freq_control_data();
424 init_semaphores();
425 init_wide_graph();
426 if(kill_all_flag) goto txtest_x;
427 for(i=0; i<txtest_no_of_segs*wg.spek_avgnum; i++)txtest_power[i]=0;
428 if(lir_status != LIR_OK)goto txtest_x;
429 init_freq_control();
430 // Make sure users_init_mode is the last window(s) we open.
431 // the avoid collission routine does not know where
432 // users windows are placed.
433 if(ui.soundcard_radio == SOUNDCARD_RADIO_ELEKTOR &&
434 diskread_flag == 0)
435 {
436 if(init_elektor_control_window() != EXIT_SUCCESS)ui.soundcard_radio=0;
437 }
438 #if LIBUDEV_PRESENT == 1
439 if(ui.soundcard_radio == SOUNDCARD_RADIO_FCDPROPLUS &&
440 diskread_flag == 0)
441 {
442 init_fcdproplus_control_window();
443 }
444 if(ui.soundcard_radio == SOUNDCARD_RADIO_AFEDRI_USB &&
445 diskread_flag == 0)
446 {
447 open_afedriusb_control();
448 }
449 #endif
450 users_init_mode();
451 show_name_and_size();
452 settextcolor(7);
453 new_baseb_flag=-1;
454 ampinfo_flag=1;
455 linrad_thread_create(rx_input_thread);
456 lir_sleep(100000);
457 if(lir_status != LIR_OK)
458 {
459 lir_join(rx_input_thread);
460 goto txtest_x;
461 }
462 if(kill_all_flag) goto txtest_x;
463 linrad_thread_create(THREAD_USER_COMMAND);
464 if(kill_all_flag) goto txtest_x;
465 linrad_thread_create(THREAD_TXTEST);
466 if(kill_all_flag) goto txtest_x;
467 linrad_thread_create(THREAD_WIDEBAND_DSP);
468 if(kill_all_flag) goto txtest_x;
469 linrad_thread_create(THREAD_SCREEN);
470 fft1_waterfall_flag=1;
471 lir_refresh_screen();
472 all_threads_started=TRUE;
473 lir_join(THREAD_USER_COMMAND);
474 linrad_thread_stop_and_join(rx_input_thread);
475 linrad_thread_stop_and_join(THREAD_WIDEBAND_DSP);
476 linrad_thread_stop_and_join(THREAD_TXTEST);
477 linrad_thread_stop_and_join(THREAD_SCREEN);
478 free_semaphores();
479 if(kill_all_flag)return;
480 if(lir_status == LIR_POWTIM)
481 {
482 usercontrol_mode=USR_POWTIM;
483 free_buffers();
484 if(kill_all_flag)return;
485 clear_screen();
486 genparm[SECOND_FFT_ENABLE]=1;
487 genparm[FIRST_BCKFFT_VERNR]=0;
488 genparm[SECOND_FFT_VERNR]=0;
489 genparm[FIRST_FFT_SINPOW] = 2;
490 genparm[SECOND_FFT_SINPOW] = 2;
491 genparm[AFC_ENABLE]=0;
492 get_wideband_sizes();
493 if(kill_all_flag)return;
494 get_buffers(1);
495 if(kill_all_flag)return;
496 set_fft1_endpoints();
497 if(kill_all_flag)return;
498 if(lir_status != LIR_POWTIM)return;
499 genparm[SECOND_FFT_ENABLE]=0;
500 fft1_waterfall_flag=0;
501 init_semaphores();
502 linrad_thread_create(rx_input_thread);
503 lir_sleep(100000);
504 if(lir_status != LIR_OK)
505 {
506 lir_join(rx_input_thread);
507 goto txtest_x;
508 }
509 if(kill_all_flag) goto txtest_x;
510 linrad_thread_create(THREAD_USER_COMMAND);
511 if(kill_all_flag) goto txtest_x;
512 linrad_thread_create(THREAD_POWTIM);
513 if(kill_all_flag) goto txtest_x;
514 linrad_thread_create(THREAD_WIDEBAND_DSP);
515 lir_sleep(50000);
516 fft1_waterfall_flag=0;
517 lir_refresh_screen();
518 all_threads_started=TRUE;
519 lir_join(THREAD_USER_COMMAND);
520 linrad_thread_stop_and_join(THREAD_POWTIM);
521 linrad_thread_stop_and_join(rx_input_thread);
522 linrad_thread_stop_and_join(THREAD_WIDEBAND_DSP);
523 clear_keyboard();
524 }
525 else
526 {
527 return;
528 }
529 txtest_x:;
530 #if LIBUDEV_PRESENT == 1
531 if(ui.soundcard_radio == SOUNDCARD_RADIO_AFEDRI_USB &&
532 diskread_flag == 0)
533 {
534 close_afedriusb_control();
535 }
536 #endif
537 free_semaphores();
538 }
539
540
normal_rx_routine(void)541 void normal_rx_routine(void)
542 {
543 char s[256];
544 int i, k, m;
545 int local_block_cnt;
546 int wlcnt, wlcnt_max, local_workload_reset;
547 double total_time1, total_time2;
548 double cpu_time1, cpu_time2;
549 lir_set_title(rxmodes[rx_mode]);
550 workload_counter=0;
551 workload=-1;
552 computation_pause_flag=0;
553 usercontrol_mode=USR_NORMAL_RX;
554 #if RUSAGE_OLD != TRUE
555 #if OSNUM == OSNUM_LINUX
556 for(i=0; i<THREAD_MAX; i++)thread_pid[i]=0;
557 #endif
558 #endif
559 init_semaphores();
560 enable_extio();
561 if(kill_all_flag) goto normal_rx_x;
562 if(ui.network_flag!=0)
563 {
564 init_network();
565 if(kill_all_flag) goto normal_rx_x;
566 if( (ui.network_flag & (NET_RXOUT_FFT2+NET_RXOUT_TIMF2)) != 0 &&
567 genparm[SECOND_FFT_ENABLE] == 0)
568 {
569 lirerr(1281);
570 goto normal_rx_x;
571 }
572 }
573 else
574 {
575 get_wideband_sizes();
576 if(kill_all_flag) goto normal_rx_x;
577 get_buffers(1);
578 netfd.rec_rx=INVSOCK;
579 }
580 if(kill_all_flag || lir_status != LIR_OK) goto normal_rx_x;
581 if(!freq_from_file)
582 {
583 read_freq_control_data();
584 }
585 check_filtercorr_direction();
586 init_wide_graph();
587 if( genparm[SECOND_FFT_ENABLE] != 0 )init_blanker();
588 if(kill_all_flag || lir_status != LIR_OK) goto normal_rx_x;
589 if(genparm[SECOND_FFT_ENABLE] != 0)
590 {
591 init_hires_graph();
592 if(kill_all_flag || lir_status != LIR_OK) goto normal_rx_x;
593 }
594 if(genparm[AFC_ENABLE] != 0)
595 {
596 init_afc_graph();
597 if(kill_all_flag || lir_status != LIR_OK) goto normal_rx_x;
598 }
599 if(ui.rx_rf_channels == 2)
600 {
601 init_pol_graph();
602 if(kill_all_flag || lir_status != LIR_OK) goto normal_rx_x;
603 }
604 init_baseband_graph();
605 if(kill_all_flag || lir_status != LIR_OK) goto normal_rx_x;
606 init_coherent_graph();
607 if(kill_all_flag || lir_status != LIR_OK) goto normal_rx_x;
608 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER && eme_flag != 0)
609 {
610 init_eme_graph();
611 if(kill_all_flag || lir_status != LIR_OK) goto normal_rx_x;
612 }
613 if(!freq_from_file)
614 {
615 init_freq_control();
616 if(kill_all_flag || lir_status != LIR_OK) goto normal_rx_x;
617 }
618 if(use_tx != 0)
619 {
620 // Get the xxproc file that the user stored in tg.spproc_no
621 init_tx_graph();
622 if(read_txpar_file()==FALSE)
623 {
624 // If it failed, read the one that was succesful before.
625 tg.spproc_no=first_txproc_no;
626 read_txpar_file();
627 }
628 }
629 // Make sure users_init_mode is the last window(s) we open.
630 // the avoid collission routine does not know where
631 // users windows are placed.
632 if(ui.soundcard_radio == SOUNDCARD_RADIO_ELEKTOR &&
633 diskread_flag == 0)
634 {
635 if(init_elektor_control_window() != EXIT_SUCCESS)ui.soundcard_radio=0;
636 }
637 #if LIBUDEV_PRESENT == 1
638 if(ui.soundcard_radio == SOUNDCARD_RADIO_FCDPROPLUS &&
639 diskread_flag == 0)
640 {
641 init_fcdproplus_control_window();
642 }
643 if(ui.soundcard_radio == SOUNDCARD_RADIO_AFEDRI_USB &&
644 diskread_flag == 0)
645 {
646 open_afedriusb_control();
647 }
648 #endif
649 users_init_mode();
650 if(kill_all_flag || lir_status != LIR_OK) goto normal_rx_x;
651 show_name_and_size();
652 lir_refresh_screen();
653 fft3_show_time=current_time();
654 fft1_show_time=fft3_show_time;
655 sys_func(THRFLAG_PORTAUDIO_STARTSTOP);
656 linrad_thread_create(THREAD_RX_OUTPUT);
657 while(!kill_all_flag &&
658 thread_status_flag[THREAD_RX_OUTPUT]!=THRFLAG_ACTIVE)
659 {
660 lir_sleep(3000);
661 }
662 if(kill_all_flag)
663 {
664 linrad_thread_stop_and_join(THREAD_RX_OUTPUT);
665 goto normal_rx_x;
666 }
667 thread_command_flag[THREAD_RX_OUTPUT]=THRFLAG_IDLE;
668 i=0;
669 while(thread_status_flag[THREAD_RX_OUTPUT] != THRFLAG_IDLE)
670 {
671 lir_sleep(10000);
672 i++;
673 if(kill_all_flag) goto normal_rx_x;
674 if(i>100)
675 {
676 lirerr(1167);
677 goto normal_rx_x;
678 }
679 }
680 thread_command_flag[THREAD_RX_OUTPUT]=THRFLAG_SEMCLEAR;
681 if(kill_all_flag) goto normal_rx_x;
682 linrad_thread_create(THREAD_USER_COMMAND);
683 if(kill_all_flag) goto normal_rx_x;
684 linrad_thread_create(THREAD_NARROWBAND_DSP);
685 if(kill_all_flag) goto normal_rx_x;
686 linrad_thread_create(THREAD_WIDEBAND_DSP);
687 if(kill_all_flag) goto normal_rx_x;
688 linrad_thread_create(THREAD_SCREEN);
689 if(kill_all_flag) goto normal_rx_x;
690 if((ui.network_flag&NET_RX_OUTPUT)!=0)
691 {
692 linrad_thread_create(THREAD_LIR_SERVER);
693 if(kill_all_flag) goto normal_rx_x;
694 }
695 // Make sure that all the threads are running before
696 // opening inputs in order to avoid overrun errors.
697 // Some system calls they might do could cause overrun
698 // errors if the input were open.
699 while(thread_status_flag[THREAD_RX_OUTPUT]!=THRFLAG_SEMCLEAR &&
700 thread_status_flag[THREAD_USER_COMMAND]!=THRFLAG_ACTIVE &&
701 thread_status_flag[THREAD_NARROWBAND_DSP]!=THRFLAG_SEM_WAIT &&
702 thread_status_flag[THREAD_WIDEBAND_DSP]!=THRFLAG_ACTIVE )
703 {
704 if(kill_all_flag) goto normal_rx_x;
705 lir_sleep(3000);
706 }
707 mailbox[0]=0;
708 mailbox[1]=0;
709 mailbox[2]=0;
710 if(kill_all_flag) goto normal_rx_x;
711 linrad_thread_create(rx_input_thread);
712 lir_sleep(100000);
713 if(lir_status != LIR_OK)
714 {
715 linrad_thread_stop_and_join(THREAD_USER_COMMAND);
716 goto normal_rx_join;
717 }
718 if(kill_all_flag) goto normal_rx_x;
719 if(use_tx != 0 )
720 {
721 switch (rx_mode)
722 {
723 case MODE_SSB:
724 init_txmem_spproc();
725 break;
726
727 case MODE_WCW:
728 case MODE_NCW:
729 case MODE_HSMS:
730 case MODE_QRSS:
731 init_txmem_cwproc();
732 break;
733
734 case MODE_RADAR:
735 init_txmem_cwproc();
736 break;
737 }
738 if(kill_all_flag)goto normal_rx_x;
739 linrad_thread_create(THREAD_TX_OUTPUT);
740 while(thread_status_flag[THREAD_TX_OUTPUT]!=THRFLAG_ACTIVE)
741 {
742 if(kill_all_flag) goto normal_rx_x;
743 lir_sleep(3000);
744 }
745 if(kill_all_flag) goto normal_rx_x;
746 lir_refresh_screen();
747 linrad_thread_create(THREAD_TX_INPUT);
748 while(thread_status_flag[THREAD_TX_INPUT]!=THRFLAG_ACTIVE)
749 {
750 if(kill_all_flag) goto normal_rx_x;
751 lir_sleep(3000);
752 }
753 }
754 lir_refresh_screen();
755 lir_sched_yield();
756 #if OSNUM == OSNUM_WINDOWS
757 if(ui.timer_resolution > 0)timeBeginPeriod(ui.timer_resolution);
758 #endif
759 fft1_waterfall_flag=1;
760 setup_thread_affinities();
761 lir_sleep(50000);
762 if(kill_all_flag) goto normal_rx_x;
763 lir_refresh_screen();
764 all_threads_started=TRUE;
765 rxin_block_counter=0;
766 i=0;
767 k=0;
768 wlcnt_max=1+snd[RXAD].interrupt_rate;
769 wlcnt=wlcnt_max;
770 local_workload_reset=workload_reset_flag;
771 #if RUSAGE_OLD != TRUE
772 lir_system_times(&cpu_time1, &total_time1);
773 #if OSNUM == OSNUM_LINUX
774 current_time();
775 for(i=0; i<THREAD_MAX; i++)
776 {
777 thread_tottim1[i]=recent_time;
778 thread_cputim1[i]=0;
779 }
780 #endif
781 #endif
782 local_block_cnt=0;
783 while( !kill_all_flag &&
784 thread_status_flag[THREAD_USER_COMMAND]==THRFLAG_ACTIVE &&
785 thread_status_flag[rx_input_thread] != THRFLAG_RETURNED)
786 {
787 m=60;
788 lir_sleep(50000);
789 while(!kill_all_flag && m>0 && rxin_block_counter == local_block_cnt)
790 {
791 m--;
792 if(local_workload_reset != workload_reset_flag)goto loadprt;
793 lir_sleep(50000);
794 }
795 if( (diskread_flag < 2 || diskread_pause_flag==0) &&
796 rxin_block_counter == local_block_cnt && local_block_cnt==0)
797 {
798 wlcnt=0;
799 sprintf(s,"No input %d",k);
800 lir_text(20,screen_last_line,s);
801 lir_refresh_screen();
802 }
803 if(diskwrite_flag)
804 {
805 lir_sync();
806 }
807 wlcnt-=rxin_block_counter-local_block_cnt;
808 if(wlcnt <= 0)
809 {
810 loadprt:;
811 fix_thread_affinities();
812 wlcnt=wlcnt_max;
813 // *******************************************************************
814 // Compute the workload. We should arrive here at a rate of about 1 Hz.
815 // Modern Linux kernels (2.6.8 or 2.6.9 and later) as well as Windows
816 // allow us to compute the work load from here.
817 // For old Linux kernels with RUSAGE_OLD == TRUE we use get_rusage to
818 // get the work load for each individual thread by calling from inside
819 // each one of the threads.
820 #if RUSAGE_OLD != TRUE
821 current_time();
822 for(i=0; i<THREAD_MAX; i++)
823 {
824 #if OSNUM == OSNUM_LINUX
825 if(thread_pid[i] != 0)
826 #endif
827 #if OSNUM == OSNUM_WINDOWS
828 if(thread_command_flag[i]!=THRFLAG_NOT_ACTIVE)
829 #endif
830 {
831 thread_tottim2[i]=recent_time;
832 thread_cputim2[i]=lir_get_thread_time(i);
833 thread_workload[i]=100*(thread_cputim2[i]-thread_cputim1[i])/
834 (thread_tottim2[i]-thread_tottim1[i]);
835 }
836 }
837 #endif
838 #if RUSAGE_OLD == TRUE
839 workload=lir_get_cpu_time();
840 #else
841 lir_system_times(&cpu_time2, &total_time2);
842 workload=100*(cpu_time2-cpu_time1)/(total_time2-total_time1);
843 #endif
844 #if OSNUM == OSNUM_LINUX
845 workload/=no_of_processors;
846 #endif
847 if(workload<0)workload=0;
848 lir_fix_bug(1);
849 if(local_workload_reset != workload_reset_flag)
850 {
851 local_workload_reset=workload_reset_flag;
852 total_time1=total_time2;
853 cpu_time1=cpu_time2;
854 for(i=0; i<THREAD_MAX; i++)
855 {
856 if(thread_command_flag[i]!=THRFLAG_NOT_ACTIVE)
857 {
858 thread_tottim1[i]=thread_tottim2[i];
859 thread_cputim1[i]=thread_cputim2[i];
860 }
861 }
862 }
863 workload_counter++;
864 lir_set_event(EVENT_SCREEN);
865 }
866 k++;
867 if(k==10000)k=1;
868 local_block_cnt=rxin_block_counter;
869 }
870 lir_join(THREAD_USER_COMMAND);
871 if(diskwrite_flag != 0)disksave_stop();
872 #if OSNUM == OSNUM_WINDOWS
873 if(ui.timer_resolution > 0)timeEndPeriod(ui.timer_resolution);
874 #endif
875 if(use_tx != 0)
876 {
877 linrad_thread_stop_and_join(THREAD_TX_INPUT);
878 linrad_thread_stop_and_join(THREAD_TX_OUTPUT);
879 close_tx_sndin();
880 close_tx_sndout();
881 if(txmem_handle != NULL)free(txmem_handle);
882 txmem_handle=NULL;
883 lir_close_event(EVENT_TX_INPUT);
884 }
885 normal_rx_join:;
886 linrad_thread_stop_and_join(THREAD_RX_OUTPUT);
887 linrad_thread_stop_and_join(rx_input_thread);
888 linrad_thread_stop_and_join(THREAD_SCREEN);
889 linrad_thread_stop_and_join(THREAD_NARROWBAND_DSP);
890 if((ui.network_flag&NET_RX_OUTPUT)!=0)
891 {
892 linrad_thread_stop_and_join(THREAD_LIR_SERVER);
893 }
894 linrad_thread_stop_and_join(THREAD_WIDEBAND_DSP);
895 normal_rx_x:;
896 #if LIBUDEV_PRESENT == 1
897 if(ui.soundcard_radio == SOUNDCARD_RADIO_AFEDRI_USB &&
898 diskread_flag == 0)
899 {
900 close_afedriusb_control();
901 }
902 #endif
903 disable_extio();
904 free_semaphores();
905 }
906
prompt_reason(char * s)907 void prompt_reason(char *s)
908 {
909 clear_screen();
910 lir_text(5,8,"You are prompted to the parameter selection screens");
911 lir_text(15,10,"for the following reason:");
912 lir_text(5,13,s);
913 lir_text(20,16,press_any_key);
914 clear_keyboard();
915 await_keyboard();
916 }
917
check_output_no_of_channels(void)918 void check_output_no_of_channels(void)
919 {
920 int i;
921 i=1+((genparm[OUTPUT_MODE]>>1)&1);
922 if(i<ui.rx_min_da_channels)i=ui.rx_min_da_channels;
923 if(i>ui.rx_max_da_channels)i=ui.rx_max_da_channels;
924 i--;
925 genparm[OUTPUT_MODE]&=-3;
926 genparm[OUTPUT_MODE]|=i<<1;
927 }
928
fix_limits(int * k,int * m,int parnum)929 void fix_limits(int *k, int *m, int parnum)
930 {
931 int i;
932 k[0]=genparm_max[parnum];
933 m[0]=genparm_min[parnum];
934 if(parnum == FIRST_FFT_VERNR)
935 {
936 k[0]=0;
937 fft1mode=(ui.rx_input_mode&(TWO_CHANNELS+IQ_DATA))/2;
938 while( fft1_version[fft1mode][k[0]+1] >= 0 &&
939 k[0] < MAX_FFT1_VERNR-1)k[0]++;
940 if(simd_present == 0)
941 {
942 while( fft_cntrl[fft1_version[fft1mode][k[0]]].simd != 0)k[0]--;
943 }
944 if(mmx_present == 0)
945 {
946 while( fft_cntrl[fft1_version[fft1mode][k[0]]].mmx != 0)k[0]--;
947 }
948 }
949 if(parnum == FIRST_BCKFFT_VERNR)
950 {
951 i=0;
952 while(fft1_back_version[ui.rx_rf_channels-1][i+1] > 0 &&
953 i < MAX_FFT1_BCKVERNR-1)i++;
954 if(mmx_present == 0)
955 {
956 while( fft_cntrl[fft1_back_version[ui.rx_rf_channels-1][i]].mmx != 0)i--;
957 }
958 k[0]=i;
959 }
960 if(parnum == FIRST_BCKFFT_ATT_N)
961 {
962 k[0]=(fft1_n-4)&0xfffe;
963 }
964 if(parnum == SECOND_FFT_ATT_N)
965 {
966 k[0]=fft2_n-2;
967 }
968 // Please check if index is within constaints *BEFORE* using it.
969 // This error was caught by GCC5 diagnostics marino@FreeBSD.org
970 if(parnum == SECOND_FFT_VERNR)
971 {
972 i=0;
973 while( i < MAX_FFT2_VERNR-1 &&
974 fft2_version[ui.rx_rf_channels-1][i+1] > 0)i++;
975 if(mmx_present == 0)
976 {
977 while( fft_cntrl[fft2_version[ui.rx_rf_channels-1][i]].mmx != 0)i--;
978 }
979 k[0]=i;
980 }
981 if(parnum == MIX1_BANDWIDTH_REDUCTION_N)
982 {
983 if(genparm[SECOND_FFT_ENABLE] == 0)
984 {
985 k[0]=fft1_n-3;
986 }
987 else
988 {
989 k[0]=fft2_n-3;
990 }
991 }
992 if(parnum == DA_OUTPUT_SPEED)
993 {
994 m[0]=ui.rx_min_da_speed;
995 k[0]=ui.rx_max_da_speed;
996 }
997 if(parnum == MAX_NO_OF_SPURS)
998 {
999 if(genparm[AFC_ENABLE]==0)
1000 {
1001 k[0]=0;
1002 }
1003 else
1004 {
1005 if(genparm[SECOND_FFT_ENABLE] == 0)
1006 {
1007 k[0]=2*fft1_size/SPUR_WIDTH;
1008 }
1009 else
1010 {
1011 k[0]=2*fft2_size/SPUR_WIDTH;
1012 }
1013 }
1014 }
1015 if(parnum == SPUR_TIMECONSTANT)
1016 {
1017 if(genparm[SECOND_FFT_ENABLE] == 0)
1018 {
1019 k[0]=5*genparm[FFT1_STORAGE_TIME];
1020 }
1021 else
1022 {
1023 k[0]=5*genparm[FFT2_STORAGE_TIME];
1024 }
1025 }
1026 // In case fft sizes are not set.
1027 if(k[0] < m[0] || m[0]<genparm_min[parnum] || k[0]>genparm_max[parnum])
1028 {
1029 k[0]=genparm_max[parnum];
1030 m[0]=genparm_min[parnum];
1031 }
1032 }
1033
modify_parms(char * line1,int first,int last)1034 void modify_parms(char *line1, int first, int last)
1035 {
1036 unsigned int new_sample_rate;
1037 char s[80];
1038 int line1_len, line;
1039 int i, j, k, m, no, mouse_line,parnum;
1040 line1_len=strlen(line1)+8;
1041 no=last-first+1;
1042 start:;
1043 hide_mouse(0,screen_width,0,screen_height);
1044 clear_screen();
1045 settextcolor(14);
1046 lir_text(5,1, line1);
1047 // Make sure fft1_n and fft2_n are defined and
1048 // in agreement with current parameters.
1049 get_wideband_sizes();
1050 if( first <= FIRST_FFT_SINPOW && last >= FIRST_FFT_SINPOW)
1051 {
1052 sprintf(s,"fft1 size=%d (Bw=%fHz) %s",fft1_size,fft1_bandwidth,
1053 fft_cntrl[FFT1_CURMODE].text);
1054 lir_text(line1_len,1,s);
1055 }
1056 if( first <= SECOND_FFT_SINPOW && last >= SECOND_FFT_SINPOW)
1057 {
1058 sprintf(s,"fft2 size=%d (Bw=%fHz)",fft2_size,fft2_bandwidth);
1059 lir_text(line1_len,1,s);
1060 }
1061 if(kill_all_flag) return;
1062 if( first <= DA_OUTPUT_SPEED && last >= DA_OUTPUT_SPEED)
1063 {
1064 if(genparm[DA_OUTPUT_SPEED] < ui.rx_min_da_speed)
1065 genparm[DA_OUTPUT_SPEED]=ui.rx_min_da_speed;
1066
1067 if(genparm[DA_OUTPUT_SPEED] > ui.rx_max_da_speed)
1068 genparm[DA_OUTPUT_SPEED]=ui.rx_max_da_speed;
1069
1070 }
1071 if( first <= CW_DECODE_ENABLE && last >= CW_DECODE_ENABLE)
1072 {
1073 if(rx_mode==MODE_WCW || rx_mode==MODE_NCW || rx_mode==MODE_HSMS)
1074 {
1075 if(genparm[CW_DECODE_ENABLE] != 0)
1076 {
1077 settextcolor(12);
1078 lir_text(1,14,"WARNING: The Morse decode routines are incomplete.");
1079 lir_text(1,15,"They will not produce any useful output and may cause");
1080 lir_text(1,16,"a program crasch. Use only for development and perhaps");
1081 lir_text(1,17,"for some evaluation of chirp and other keying defects");
1082 lir_text(1,18,"with the coherent graph oscilloscope.");
1083 }
1084 }
1085 else
1086 {
1087 genparm[CW_DECODE_ENABLE]=0;
1088 }
1089 }
1090 if( first <= FIRST_BCKFFT_ATT_N && last >= FIRST_BCKFFT_ATT_N)
1091 {
1092 k=(fft1_n-4)&0xfffe;
1093 if(genparm[FIRST_BCKFFT_ATT_N]>k)genparm[FIRST_BCKFFT_ATT_N]=k;
1094 if(genparm[FIRST_BCKFFT_ATT_N]<0)genparm[FIRST_BCKFFT_ATT_N]=
1095 genparm_min[FIRST_BCKFFT_ATT_N];
1096 }
1097 if( first <= SECOND_FFT_ATT_N && last >= SECOND_FFT_ATT_N)
1098 {
1099 k=fft2_n-2;
1100 if(genparm[SECOND_FFT_ATT_N]>k)genparm[SECOND_FFT_ATT_N]=k;
1101 }
1102 settextcolor(7);
1103 line=0;
1104 for(i=0; i<no; i++)
1105 {
1106 j=i+first;
1107 if(ui.operator_skil == OPERATOR_SKIL_NEWCOMER && newco_genparm[j] ==0)
1108 {
1109 settextcolor(8);
1110 }
1111 else
1112 {
1113 settextcolor(7);
1114 }
1115 sprintf(s,"%s [%d] ",genparm_text[j],genparm[j]);
1116 lir_text(1,3+i, s);
1117 }
1118 lir_text(1,5+no,"Use left mouse button to select line");
1119 lir_text(1,3+no,"CONTINUE");
1120 settextcolor(15);
1121 show_mouse();
1122 modloop:;
1123 if( new_mouse_x!=mouse_x || new_mouse_y!=mouse_y)
1124 {
1125 lir_move_mouse_cursor();
1126 show_mouse();
1127 }
1128 lir_refresh_screen();
1129 lir_sleep(10000);
1130 if(new_lbutton_state==1)lbutton_state=1;
1131 if(new_lbutton_state==0 && lbutton_state==1)
1132 {
1133 lbutton_state=0;
1134 mouse_line=mouse_y/text_height-3;
1135 if(mouse_line == no)goto loopx;
1136 if(mouse_line >= 0 && mouse_line <no)
1137 {
1138 parnum=mouse_line+first;
1139 clear_screen();
1140 settextcolor(14);
1141 lir_text(5,1, line1);
1142 line=3;
1143 settextcolor(15);
1144 sprintf(s,"Old value = %d",genparm[parnum]);
1145 lir_text(1,line, s);
1146 line++;
1147 lir_text(1,line,"Enter new value for:");
1148 line++;
1149 fix_limits(&k, &m, parnum);
1150 sprintf(s," %s (%d to %d)",genparm_text[parnum], m,k);
1151 lir_text(1,line, s);
1152 i=line+1;
1153 line+=4;
1154 msg_filename="help.lir";
1155 write_from_msg_file(&line, 201+mouse_line+first, TRUE, HELP_VERNR);
1156 if(parnum == DA_OUTPUT_SPEED && ui.rx_dadev_no != DISABLED_DEVICE_CODE)
1157 {
1158 #if(OSNUM == OSNUM_LINUX)
1159 #if (ALSA_PRESENT == 1)
1160 if (( (ui.use_alsa&NATIVE_ALSA_USED) != 0) && ((ui.use_alsa&PORTAUDIO_RX_OUT)== 0) )
1161 {
1162 alsa_get_native_samplerate(ui.rx_dadev_no,SND_PCM_STREAM_PLAYBACK,&line,&new_sample_rate);
1163 genparm[parnum]=new_sample_rate;
1164 goto modify_parms_next_a;
1165 }
1166 else
1167 #endif
1168 #endif
1169 {
1170 if( (ui.use_alsa&PORTAUDIO_RX_OUT) != 0 &&
1171 ui.rx_dadev_no != DISABLED_DEVICE_CODE)
1172 {
1173 pa_get_valid_samplerate(ui.rx_dadev_no,RXDA,&line,&new_sample_rate);
1174 genparm[parnum]=new_sample_rate;
1175 goto modify_parms_next_p;
1176 }
1177 }
1178 }
1179 lir_text(7,i,"=>");
1180 genparm[parnum]=lir_get_integer(10, i, 8, m,k);
1181 modify_parms_next_p:;
1182 #if(OSNUM == OSNUM_LINUX)
1183 #if (ALSA_PRESENT == 1)
1184 modify_parms_next_a:;
1185 #endif
1186 #endif
1187
1188 if(kill_all_flag) return;
1189 if(parnum == OUTPUT_MODE)check_output_no_of_channels();
1190 goto start;
1191 }
1192 }
1193 test_keyboard();
1194 if(kill_all_flag) return;
1195 if(lir_inkey != 0)
1196 {
1197 process_current_lir_inkey();
1198 if(kill_all_flag) return;
1199 }
1200 if(lir_inkey == F1_KEY || lir_inkey == '!')
1201 {
1202 mouse_line=mouse_y/text_height-3;
1203 if(mouse_line >= 0 && mouse_line <no)
1204 {
1205 help_message(201+mouse_line+first);
1206 }
1207 else
1208 {
1209 help_message(200);
1210 }
1211 if(kill_all_flag) return;
1212 goto start;
1213 }
1214 if(lir_inkey != 10 && lir_inkey!= 'X')goto modloop;
1215 loopx:;
1216 }
1217
set_general_parms(char * mode)1218 void set_general_parms(char *mode)
1219 {
1220 char s[80];
1221 sprintf(s,"%s: Rx channels=%d",mode,ui.rx_rf_channels);
1222 if(lir_status < LIR_OK)goto bufreduce;
1223 setfft1:;
1224 if(kill_all_flag) return;
1225 modify_parms(s, 0, SECOND_FFT_ENABLE);
1226 if(kill_all_flag) return;
1227 if(lir_inkey == 'X')return;
1228 // Make sure fft1_n and fft2_n are defined and that we can
1229 // allocate memory.
1230 get_wideband_sizes();
1231 if(kill_all_flag) return;
1232 get_buffers(0);
1233 if(kill_all_flag) return;
1234 if(fft1_handle != NULL)fft1_handle=chk_free(fft1_handle);
1235 if(lir_status != LIR_OK)goto bufreduce;
1236 if(genparm[SECOND_FFT_ENABLE]==1)
1237 {
1238 modify_parms(s, FIRST_BCKFFT_VERNR, FFT2_STORAGE_TIME);
1239 if(kill_all_flag) return;
1240 if(lir_inkey == 'X')return;
1241 get_wideband_sizes();
1242 if(kill_all_flag) return;
1243 get_buffers(0);
1244 if(kill_all_flag) return;
1245 if(fft1_handle != NULL)fft1_handle=chk_free(fft1_handle);
1246 if(lir_status != LIR_OK)
1247 {
1248 bufreduce:;
1249 clear_screen();
1250 settextcolor(15);
1251 switch (lir_status)
1252 {
1253 case LIR_FFT1ERR:
1254 lir_text(5,5,"Out of memory !!!");
1255 lir_text(10,10,"Storage times are set to minimum.");
1256 settextcolor(14);
1257 lir_text(10,13,"Check memory allocations in waterfall window");
1258 lir_text(10,14,"to decide how much you may increase storage times.");
1259 genparm[FFT1_STORAGE_TIME]=genparm_min[FFT1_STORAGE_TIME];
1260 genparm[FFT2_STORAGE_TIME]=genparm_min[FFT2_STORAGE_TIME];
1261 genparm[BASEBAND_STORAGE_TIME]=genparm_min[BASEBAND_STORAGE_TIME];
1262 lir_status=LIR_OK;
1263 break;
1264
1265 case LIR_SPURERR:
1266 sprintf(s,"fft1 storage time too short for spur removal");
1267 if(genparm[SECOND_FFT_ENABLE] != 0)s[3]='2';
1268 lir_text(7,7,s);
1269 lir_text(7,8,"Spur removal disabled");
1270 genparm[MAX_NO_OF_SPURS]=0;
1271 lir_status=LIR_OK;
1272 break;
1273
1274 case LIR_NEW_SETTINGS:
1275 goto setfft1;
1276 }
1277 settextcolor(7);
1278 lir_text(10,17,"Press ESC to quit, any other key to continue");
1279 await_processed_keyboard();
1280 if(kill_all_flag) return;
1281 goto setfft1;
1282 }
1283 }
1284 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
1285 {
1286 modify_parms(s, AFC_ENABLE, AFC_ENABLE);
1287 if(kill_all_flag) return;
1288 if(lir_inkey == 'X')return;
1289 if(genparm[AFC_ENABLE] != 0)modify_parms(s, AFC_ENABLE+1, SPUR_TIMECONSTANT);
1290 if(kill_all_flag) return;
1291 if(lir_inkey == 'X')return;
1292 }
1293 modify_parms(s, MIX1_BANDWIDTH_REDUCTION_N, MAX_GENPARM-1);
1294 if(kill_all_flag) return;
1295 if(lir_inkey == 'X')return;
1296 clear_screen();
1297 }
1298
cal_package(void)1299 void cal_package(void)
1300 {
1301 char s[80], ss[80];
1302 int single_run;
1303 int i, ia, ib, ic;
1304 float t1,t2;
1305 calibrate_flag = 1;
1306 // **************************************************************
1307 // Set fft1_direction positive.
1308 // The calibration routine does not want to know if the fft1 routine
1309 // will invert the frequency scale.
1310 fft1_direction=1;
1311 single_run=0;
1312 // Get normal buffers with minimum for all parameters.
1313 // Everything selectable becomes deselected.
1314 // Save fft1 version, window and bandwidth.
1315 ia=genparm[FIRST_FFT_VERNR];
1316 ib=genparm[FIRST_FFT_SINPOW];
1317 ic=genparm[FIRST_FFT_BANDWIDTH];
1318 for(i=0; i<MAX_GENPARM; i++)genparm[i]=genparm_min[i];
1319 // Select the correct fft version for the current rx_mode
1320 // This is not really needed for versions above Linrad-01.xx
1321 // because the approximate fft has been removed. None of the
1322 // fft implementations contains a filter any more.
1323 genparm[FIRST_FFT_VERNR]=ia;
1324 // Force fft1_size to be 4 times larger than specified for the current
1325 // rx_mode by dividing bandwidth by 4.
1326 t2=ic/4;
1327 // Compensate for not using the specified window
1328 // We use sin power 4 to suppress wideband noise that otherwise would
1329 // be produced by discontinuities in matching between transform ends.
1330 t1=pow(0.5,1.0/ib);
1331 t2*=(1-2*asin(t1)/PI_L);
1332 t1=pow(0.5,1.0/4);
1333 t2/=(1-2*asin(t1)/PI_L);
1334 genparm[FIRST_FFT_SINPOW]=4;
1335 i=t2+0.5;
1336 if(i < genparm_min[FIRST_FFT_BANDWIDTH])i=genparm_min[FIRST_FFT_BANDWIDTH];
1337 genparm[FIRST_FFT_BANDWIDTH]=i;
1338 clear_screen();
1339 get_wideband_sizes();
1340 if(kill_all_flag) return;
1341 get_buffers(1);
1342 if(kill_all_flag) return;
1343 if(lir_status != LIR_OK)return;
1344 wg.first_xpoint=0;
1345 wg.xpoints=fft1_size;
1346 set_fft1_endpoints();
1347 if(fft1afc_flag == 0)fft1afc_flag=-1;
1348 init_memalloc(calmem, MAX_CAL_ARRAYS);
1349 mem( 1,&cal_graph,2*MAX_ADCHAN*screen_width*sizeof(short int),0);
1350 mem( 2,&cal_table,fft1_size*sizeof(COSIN_TABLE )/2,0);
1351 mem( 3,&cal_permute,fft1_size*sizeof(short int),0);
1352 mem(22,&fft2_tab,fft1_size*sizeof(COSIN_TABLE )/2,0);
1353 mem(23,&fft2_permute,fft1_size*sizeof(short int),0);
1354 mem( 4,&cal_win,(1+fft1_size/2)*sizeof(float),0);
1355 mem( 5,&cal_tmp,twice_rxchan*fft1_size*sizeof(float),0);
1356 mem( 6,&cal_buf,twice_rxchan*fft1_size*sizeof(float),0);
1357 mem( 7,&bal_flag,(BAL_MAX_SEG+1)*sizeof(int),0);
1358 mem( 8,&bal_pos,BAL_AVGNUM*(BAL_MAX_SEG+1)*ui.rx_rf_channels*sizeof(int),0);
1359 mem( 9,&bal_phsum,BAL_AVGNUM*(BAL_MAX_SEG+1)*ui.rx_rf_channels*sizeof(float),0);
1360 mem(10,&bal_amprat,BAL_AVGNUM*(BAL_MAX_SEG+1)*ui.rx_rf_channels*sizeof(float),0);
1361 mem(11,&contracted_iq_foldcorr,8*(BAL_MAX_SEG+1)*ui.rx_rf_channels*
1362 sizeof(float),0);
1363 mem(12,&cal_buf2,twice_rxchan*fft1_size*sizeof(float),0);
1364 mem(13,&cal_buf3,twice_rxchan*fft1_size*sizeof(float),0);
1365 mem(14,&cal_buf4,twice_rxchan*fft1_size*sizeof(float),0);
1366 mem(15,&cal_buf5,twice_rxchan*fft1_size*sizeof(float),0);
1367 mem(16,&cal_buf6,twice_rxchan*fft1_size*sizeof(float),0);
1368 mem(17,&cal_buf7,twice_rxchan*fft1_size*sizeof(float),0);
1369 mem(47,&cal_fft1_filtercorr,twice_rxchan*fft1_size*sizeof(float),0);
1370 mem(48,&cal_fft1_desired,fft1_size*sizeof(float),0);
1371 mem(49,&cal_fft1_sumsq,fft1_size*ui.rx_rf_channels*sizeof(float),0);
1372 mem(50,&cal_fft1_slowsum,fft1_size*ui.rx_rf_channels*sizeof(float),0);
1373 i=memalloc(&calmem_handle,"calmem");
1374 if(i==0)
1375 {
1376 lirerr(1188);
1377 return;
1378 }
1379 if(ui.rx_rf_channels == 1)
1380 {
1381 cal_ymax=.25;
1382 cal_yzer=.65;
1383 }
1384 else
1385 {
1386 cal_ymax=.15;
1387 cal_yzer=.5;
1388 }
1389 init_fft(0,fft1_n, fft1_size, cal_table, cal_permute);
1390 make_window(2,fft1_size/2, 4, cal_win);
1391 iqbeg:;
1392 single_run++;
1393 if(single_run >=2)goto cal_skip;
1394 fft1_pa=fft1_block;
1395 fft1_na=1;
1396 fft1_pb=0;
1397 fft1_px=0;
1398 fft1_nx=0;
1399 timf1p_pa=snd[RXAD].block_bytes;
1400 rxin_isho=(short int*)(&timf1_char[timf1p_pa]);
1401 rxin_int=(int*)(&timf1_char[timf1p_pa]);
1402 rxin_char=(char*)(&timf1_char[timf1p_pa]);
1403 timf1p_px=0;
1404 if(kill_all_flag) goto cal_skip;
1405 cal_type=CAL_TYPE_MENU;
1406 cal_initscreen();
1407 if( (ui.rx_input_mode&IQ_DATA) != 0)
1408 {
1409 if( (ui.rx_input_mode&DIGITAL_IQ) == 0)
1410 {
1411 lir_text(0, 5,"Running in IQ mode (direct conversion receiver)");
1412 lir_text(0, 6,"The I/Q phase and amplitude should be calibrated before");
1413 lir_text(0, 7,"the total amplitude and phase response is calibrated");
1414 lir_text(5, 9,"A=> Calibrate I/Q phase and amplitude.");
1415 }
1416 lir_text(5,10,"B=> Calibrate total amplitude and phase");
1417 lir_text(5,11,"C=> Remove center discontinuity");
1418 lir_text(5,12,"D=> Refine amplitude and phase correction");
1419 lir_text(5,13,"X=> Skip");
1420 lir_text(5,14,"F1 or !=> Help");
1421 get_kbd:;
1422 await_processed_keyboard();
1423 if(kill_all_flag) goto cal_skip;
1424 switch (lir_inkey)
1425 {
1426 case 'X':
1427 goto cal_skip;
1428
1429 case 'A':
1430 if( (ui.rx_input_mode&DIGITAL_IQ) != 0)break;
1431 if( (fft1_calibrate_flag&CALAMP)==CALAMP)
1432 {
1433 clear_screen();
1434 lir_text(5,5,"The amplitudes are already calibrated.");
1435 make_filfunc_filename(s);
1436 sprintf(ss,"Exit from Linrad and remove the file %s",s);
1437 lir_text(1,6,ss);
1438 lir_text(5,8,press_any_key);
1439 await_keyboard();
1440 break;
1441 }
1442 usercontrol_mode=USR_IQ_BALANCE;
1443 init_semaphores();
1444 ampinfo_flag=1;
1445 linrad_thread_create(rx_input_thread);
1446 lir_sleep(100000);
1447 if(lir_status != LIR_OK)
1448 {
1449 lir_join(rx_input_thread);
1450 goto cal_skip_freesem;
1451 }
1452 if(kill_all_flag) goto cal_skip_freesem;
1453 linrad_thread_create(THREAD_USER_COMMAND);
1454 if(kill_all_flag) goto iqbal;
1455 linrad_thread_create(THREAD_CAL_IQBALANCE);
1456 if(kill_all_flag) goto iqbal;
1457 linrad_thread_create(THREAD_WIDEBAND_DSP);
1458 iqbal:;
1459 lir_sleep(50000);
1460 lir_refresh_screen();
1461 lir_join(THREAD_USER_COMMAND);
1462 linrad_thread_stop_and_join(rx_input_thread);
1463 linrad_thread_stop_and_join(THREAD_CAL_IQBALANCE);
1464 linrad_thread_stop_and_join(THREAD_WIDEBAND_DSP);
1465 free_semaphores();
1466 if(kill_all_flag) goto cal_skip;
1467 break;
1468
1469 case 'B':
1470 goto pulsecal;
1471
1472 case 'C':
1473 if(remove_iq_notch() == 0)goto cal_skip;
1474 break;
1475
1476 case 'D':
1477 final_filtercorr_init();
1478 goto cal_skip;
1479
1480 case F1_KEY:
1481 case '!':
1482 help_message(302);
1483 break;
1484
1485 default:
1486 goto get_kbd;
1487 }
1488 }
1489 else
1490 {
1491 lir_text(5, 9,"A=> Calibrate frequency response");
1492 lir_text(5,10,"B=> Refine amplitude and phase correction");
1493 lir_text(5,11,"X=> Skip");
1494 lir_text(5,12,"F1 or !=> Help");
1495 get_valid_keypress:;
1496 await_processed_keyboard();
1497 if(kill_all_flag) goto cal_skip;
1498 switch (lir_inkey)
1499 {
1500 case 'X':
1501 goto cal_skip;
1502
1503 case 'A':
1504 goto pulsecal;
1505
1506 case 'B':
1507 final_filtercorr_init();
1508 goto cal_skip;
1509
1510 case F1_KEY:
1511 case '!':
1512 help_message(303);
1513 break;
1514
1515 default:
1516 goto get_valid_keypress;
1517 }
1518 }
1519 goto iqbeg;
1520 pulsecal:;
1521 enable_extio();
1522 timf1p_pa=0;
1523 rxin_isho=(short int*)timf1_char;
1524 rxin_int=(int*)timf1_char;
1525 rxin_char=(char*)timf1_char;
1526 usercontrol_mode=USR_CAL_INTERVAL;
1527 init_semaphores();
1528 ampinfo_flag=1;
1529 linrad_thread_create(rx_input_thread);
1530 lir_sleep(100000);
1531 if(lir_status != LIR_OK)
1532 {
1533 lir_join(rx_input_thread);
1534 goto cal_skip_freesem;
1535 }
1536 if(kill_all_flag) goto cal_skip_freesem;
1537 linrad_thread_create(THREAD_USER_COMMAND);
1538 if(kill_all_flag) goto calint;
1539 linrad_thread_create(THREAD_CAL_INTERVAL);
1540 if(kill_all_flag)goto cal_skip;
1541 calint:;
1542 lir_sleep(50000);
1543 lir_refresh_screen();
1544 lir_join(THREAD_USER_COMMAND);
1545 linrad_thread_stop_and_join(rx_input_thread);
1546 linrad_thread_stop_and_join(THREAD_CAL_INTERVAL);
1547 free_semaphores();
1548 if(kill_all_flag)goto cal_skip;
1549 clear_screen();
1550 lir_refresh_screen();
1551 if(usercontrol_mode != USR_CAL_FILTERCORR)
1552 {
1553 disable_extio();
1554 goto iqbeg;
1555 }
1556 if( (ui.rx_input_mode&IQ_DATA) == 0)cal_interval/=2;
1557 #define ERRLINE 5
1558 if(cal_interval > fft1_size/5)
1559 {
1560 lir_text(5,ERRLINE,"Pulse repetition frequency too low.");
1561 lir_text(5,ERRLINE+1,"Increase PRF or set fft1 bandwidth lower to");
1562 lir_text(5,ERRLINE+2,"increase transform size.");
1563 err1:;
1564 lir_text(5,ERRLINE+5,press_any_key);
1565 await_keyboard();
1566 disable_extio();
1567 goto iqbeg;
1568 }
1569 if(cal_signal_level > 0.9)
1570 {
1571 lir_text(5,ERRLINE,"Pulses too strong (above 90%)");
1572 goto err1;
1573 }
1574 timf1p_pa=0;
1575 rxin_isho=(short int*)timf1_char;
1576 rxin_int=(int*)timf1_char;
1577 rxin_char=(char*)timf1_char;
1578 timf1p_px=0;
1579 init_semaphores();
1580 linrad_thread_create(rx_input_thread);
1581 lir_sleep(100000);
1582 if(lir_status != LIR_OK)
1583 {
1584 lir_join(rx_input_thread);
1585 goto cal_skip_freesem;
1586 }
1587 if(kill_all_flag) goto cal_skip_freesem;
1588 linrad_thread_create(THREAD_WIDEBAND_DSP);
1589 if(kill_all_flag) goto calfil;
1590 linrad_thread_create(THREAD_CAL_FILTERCORR);
1591 if(kill_all_flag) goto calfil;
1592 linrad_thread_create(THREAD_USER_COMMAND);
1593 calfil:;
1594 lir_sleep(50000);
1595 lir_refresh_screen();
1596 lir_join(THREAD_USER_COMMAND);
1597 linrad_thread_stop_and_join(rx_input_thread);
1598 linrad_thread_stop_and_join(THREAD_CAL_FILTERCORR);
1599 linrad_thread_stop_and_join(THREAD_WIDEBAND_DSP);
1600 free_semaphores();
1601 if(kill_all_flag)goto cal_skip;
1602 disable_extio();
1603 goto iqbeg;
1604 // ********************************
1605 cal_skip_freesem:;
1606 free_semaphores();
1607 cal_skip:;
1608 disable_extio();
1609 memcheck(199,calmem,&calmem_handle);
1610 calmem_handle=chk_free(calmem_handle);
1611 free_buffers();
1612 }
1613
restore_uiparm(void)1614 void restore_uiparm(void)
1615 {
1616 int i;
1617 int *uiparm;
1618 uiparm=(int*)(&ui);
1619 for(i=0; i<MAX_UIPARM; i++)uiparm[i]=uiparm_save[i];
1620 }
1621
save_uiparm(void)1622 void save_uiparm(void)
1623 {
1624 int i;
1625 int *uiparm;
1626 uiparm=(int*)(&ui);
1627 for(i=0; i<MAX_UIPARM; i++)uiparm_save[i]=uiparm[i];
1628 }
1629
set_wav_parms(void)1630 void set_wav_parms(void)
1631 {
1632 if( wav_read_flag != 0)
1633 {
1634 if(ui.rx_ad_channels == 2)
1635 {
1636 if(iqflag==1)
1637 {
1638 ui.rx_rf_channels=1;
1639 ui.rx_input_mode|=IQ_DATA;
1640 }
1641 else
1642 {
1643 ui.rx_input_mode|=TWO_CHANNELS;
1644 ui.rx_rf_channels=2;
1645 }
1646 if(dirflag == 1)
1647 {
1648 fg.passband_direction=-1;
1649 }
1650 else
1651 {
1652 fg.passband_direction=1;
1653 }
1654 }
1655 else
1656 {
1657 ui.rx_rf_channels=1;
1658 fg.passband_direction=1;
1659 }
1660 fft1_direction=fg.passband_direction;
1661 }
1662 }
1663
init_genparm(int upd)1664 void init_genparm(int upd)
1665 {
1666 char s[256],ss[80];
1667 FILE *file;
1668 int i, j, k, kmax, imin, imax;
1669 int parwrite_flag, parfile_flag;
1670 float t1;
1671 char *parinfo;
1672 parinfo=NULL;
1673 parwrite_flag=0;
1674 if(upd == TRUE) goto updparm;
1675 file=NULL;
1676 // Start by reading general parameters for the selected rx mode.
1677 // If no parameters found, go to the parameter select routine because
1678 // we can not guess what hardware will be in use so default parameters
1679 // are likely to be very far from what will be needed.
1680 parfile_flag=0;
1681 if(savefile_parname[0] != 0)
1682 {
1683 // We use disk input and there is a parameter file name supplied
1684 // for this particular recording.
1685 file = fopen(savefile_parname, "r");
1686 if (file == NULL)goto saverr;
1687 parfilnam=savefile_parname;
1688 parfile_flag=1;
1689 // First read the mode flag, an extra line in the userint par file
1690 // placed above the normal lines.
1691 // This line specifies receive mode and whether the file should be
1692 // repeated endlessly
1693 // Stereo .wav files have more flags. Whether it is two RF channels
1694 // or I and Q from direct conversion. In the latter case what
1695 // direction to use for the frequency scale.
1696 i=fread(s,1,1,file);
1697 if(i != 1)goto saverr_close;
1698 rx_mode=to_upper(s[0])-'A';
1699 if(rx_mode < 0 || rx_mode >= MAX_RX_MODE)goto saverr_close;
1700 i=fread(s,1,1,file);
1701 if(i != 1)goto saverr_close;
1702 if(s[0]=='1')
1703 {
1704 savefile_repeat_flag=1;
1705 }
1706 else
1707 {
1708 if(s[0]!='0')goto saverr_close;
1709 savefile_repeat_flag=0;
1710 }
1711 if(wav_read_flag==0)goto skip_modlin;
1712 i=fread(s,1,1,file);
1713 if(i != 1)goto saverr_close;
1714 if(s[0]=='1')
1715 {
1716 iqflag=1;
1717 ui.rx_rf_channels=ui.rx_ad_channels/2;
1718 i=fread(s,1,1,file);
1719 if(i != 1)goto saverr_close;
1720 if(s[0]=='1')
1721 {
1722 dirflag=1;
1723 }
1724 else
1725 {
1726 if(s[0]!='0')goto saverr_close;
1727 dirflag=0;
1728 }
1729 }
1730 else
1731 {
1732 if(s[0]!='0')goto saverr_close;
1733 iqflag=0;
1734 ui.rx_rf_channels=ui.rx_ad_channels;
1735 }
1736 skip_modlin:;
1737 // We use disk input and something was wrong with the first line.
1738 // Read until end of line, then ask the user for the desired mode.
1739 i=fread(s,1,1,file);
1740 if(s[0]=='\n') goto fileok;
1741 if(i==1)goto skip_modlin;
1742 saverr_close:;
1743 fclose(file);
1744 saverr:;
1745 parwrite_flag=1;
1746 }
1747 if(diskread_flag == 2)
1748 {
1749 clear_screen();
1750 for(i=0; i<MAX_RX_MODE; i++)
1751 {
1752 sprintf(s,"%c=%s",i+'A',rxmodes[i]);
1753 lir_text(0, i+2,s);
1754 }
1755 settextcolor(15);
1756 lir_text(5, MAX_RX_MODE+3, "Select Rx mode");
1757 rx_mode=-1;
1758 while(rx_mode < 0 || rx_mode > MAX_RX_MODE)
1759 {
1760 to_upper_await_keyboard();
1761 if(kill_all_flag) return;
1762 rx_mode=lir_inkey-'A';
1763 }
1764 clear_screen();
1765 lir_text(5,5,"Repeat recording endlessly (Y/N)?");
1766 savrpt:;
1767 to_upper_await_keyboard();
1768 if(kill_all_flag) return;
1769 if(lir_inkey=='Y')
1770 {
1771 savefile_repeat_flag=1;
1772 }
1773 else
1774 {
1775 if(lir_inkey != 'N')goto savrpt;
1776 savefile_repeat_flag=0;
1777 }
1778 if( wav_read_flag != 0)
1779 {
1780 if(ui.rx_ad_channels == 2)
1781 {
1782 lir_text(5,6,"Stereo recording. Interpret as I/Q data (Y/N) ?");
1783 wawiq:;
1784 to_upper_await_keyboard();
1785 if(kill_all_flag) return;
1786 if(lir_inkey=='Y')
1787 {
1788 iqflag=1;
1789 lir_text(5,7,"Invert frequency scale (Y/N) ?");
1790 diriq:;
1791 to_upper_await_keyboard();
1792 if(kill_all_flag) return;
1793 if(lir_inkey=='Y')
1794 {
1795 dirflag=1;
1796 }
1797 else
1798 {
1799 if(lir_inkey != 'N')goto diriq;
1800 dirflag=0;
1801 }
1802 }
1803 else
1804 {
1805 if(lir_inkey != 'N')goto wawiq;
1806 iqflag=0;
1807 fg.passband_center=0.000001*ui.rx_ad_speed/4;
1808 freq_from_file=TRUE;
1809 }
1810 }
1811 else
1812 {
1813 ui.rx_rf_channels=1;
1814 fg.passband_center=0.000001*ui.rx_ad_speed/4;
1815 freq_from_file=TRUE;
1816 }
1817 }
1818 if(savefile_parname[0]!=0)
1819 {
1820 file = fopen( savefile_parname, "r");
1821 if(file == NULL) parwrite_flag=1;
1822 }
1823 settextcolor(7);
1824 }
1825 set_wav_parms();
1826 if(parfile_flag == 0)parfilnam=rxpar_filenames[rx_mode];
1827 file = fopen(rxpar_filenames[rx_mode], "r");
1828 if(file == NULL)
1829 {
1830 sprintf(s,"%s file missing",rxpar_filenames[rx_mode]);
1831 prompt_reason(s);
1832 iniparm:;
1833 if(kill_all_flag) return;
1834 for(i=0; i<MAX_GENPARM; i++)
1835 {
1836 genparm[i]=genparm_default[rx_mode][i];
1837 }
1838 // The default mix1 bandwidth reduction will be fine when
1839 // the sampling rate is 96 kHz I/Q.
1840 t1=96000;
1841 if( (ui.rx_input_mode&IQ_DATA) == 0)t1*=2;
1842 t1=ui.rx_ad_speed/t1;
1843 if(t1 > 1)
1844 {
1845 while(t1>1.5)
1846 {
1847 t1*=0.5;
1848 genparm[MIX1_BANDWIDTH_REDUCTION_N]++;
1849 }
1850 }
1851 if(t1 < 1)
1852 {
1853 while(t1<0.7)
1854 {
1855 t1*=2;
1856 genparm[MIX1_BANDWIDTH_REDUCTION_N]--;
1857 }
1858 genparm[MIX1_BANDWIDTH_REDUCTION_N]-=make_power_of_two(&i);
1859 }
1860 fix_limits(&imax, &imin,MIX1_BANDWIDTH_REDUCTION_N);
1861 if(genparm[MIX1_BANDWIDTH_REDUCTION_N] > imax)
1862 genparm[MIX1_BANDWIDTH_REDUCTION_N]= imax;
1863 if(genparm[MIX1_BANDWIDTH_REDUCTION_N] < imin)
1864 genparm[MIX1_BANDWIDTH_REDUCTION_N]= imin;
1865 genparm[MAX_GENPARM]=ui.rx_ad_speed;
1866 updparm:;
1867 if(diskread_flag == 4)
1868 {
1869 if(init_diskread(-1) != 0)
1870 {
1871 lirerr(3641);
1872 return;
1873 }
1874 }
1875 set_wav_parms();
1876 set_general_parms(rxmodes[rx_mode]);
1877 if(kill_all_flag)return;
1878 genparm[MAX_GENPARM+1]=GENPARM_VERNR;
1879 if(diskread_flag == 0)save_uiparm();
1880 if(savefile_parname[0]!=0)
1881 {
1882 write_savefile_parms:;
1883 parwrite_flag=0;
1884 parfilnam=savefile_parname;
1885 file = fopen(parfilnam, "w");
1886 if(file == NULL)goto wrerr;
1887 fprintf(file,"%c%c",rx_mode+'A',savefile_repeat_flag+'0');
1888 if( wav_read_flag != 0)
1889 {
1890 fprintf(file,"%c%c", iqflag+'0', dirflag+'0');
1891 }
1892 fprintf(file,"\n");
1893 goto wrok;
1894 }
1895 file = fopen(parfilnam, "w");
1896 if(file == NULL)
1897 {
1898 wrerr:;
1899 clear_screen();
1900 could_not_create(parfilnam,0);
1901 return;
1902 }
1903 wrok:;
1904 for(i=0; i<MAX_GENPARM+2; i++)
1905 {
1906 fprintf(file,"%s [%d]\n",genparm_text[i],genparm[i]);
1907 }
1908 parfile_end(file);
1909 file=NULL;
1910 }
1911 else
1912 {
1913 parfilnam=rxpar_filenames[rx_mode];
1914 fileok:;
1915 parinfo=malloc(4096);
1916 if(parinfo == NULL)
1917 {
1918 fclose(file);
1919 lirerr(1081);
1920 return;
1921 }
1922 for(i=0; i<4096; i++)parinfo[i]=0;
1923 kmax=fread(parinfo,1,4095,file);
1924 fclose(file);
1925 file=NULL;
1926 if(kmax >= 4095)
1927 {
1928 sprintf(ss,"Excessive file size");
1929 daterr:;
1930 sprintf(s,"%s Data error in file %s",ss,parfilnam);
1931 prompt_reason(s);
1932 goto iniparm;
1933 }
1934 k=0;
1935 for(i=0; i<MAX_GENPARM+2; i++)
1936 {
1937 while(k <= kmax && (parinfo[k]==' ' || parinfo[k]== '\n' ))k++;
1938 if(k > kmax)
1939 {
1940 sprintf(ss,"Premature end of file");
1941 daterr_free:;
1942 parinfo=chk_free(parinfo);
1943 goto daterr;
1944 }
1945 j=0;
1946 while(parinfo[k]== genparm_text[i][j])
1947 {
1948 k++;
1949 j++;
1950 }
1951 sprintf(ss,"Error: %s ",genparm_text[i]);
1952 if(genparm_text[i][j] != 0 || k > kmax)
1953 {
1954 goto daterr_free;
1955 }
1956 while(k <= kmax && parinfo[k]!='[')k++;
1957 if(k > kmax)
1958 {
1959 goto daterr_free;
1960 }
1961 sscanf(&parinfo[k],"[%d]",&genparm[i]);
1962 while(k <= kmax && parinfo[k]!='\n')k++;
1963 if(k > kmax)
1964 {
1965 goto daterr_free;
1966 }
1967 }
1968 parinfo=chk_free(parinfo);
1969 if(diskread_flag == 4)
1970 {
1971 if(init_diskread(-1) != 0)
1972 {
1973 lirerr(3641);
1974 free(parinfo);
1975 return;
1976 }
1977 }
1978 else
1979 {
1980 if( fabs( (float)(genparm[MAX_GENPARM] - ui.rx_ad_speed)/
1981 (genparm[MAX_GENPARM] + ui.rx_ad_speed)) > 0.0002)
1982 {
1983 sprintf(s,"Input sampling speed changed %d (old=%d)",
1984 ui.rx_ad_speed, genparm[MAX_GENPARM]);
1985 prompt_reason(s);
1986 goto iniparm;
1987 }
1988 }
1989 set_wav_parms();
1990 if(genparm[MAX_GENPARM+1] != (int)(GENPARM_VERNR))
1991 {
1992 prompt_reason("GENPARM version changed");
1993 goto iniparm;
1994 }
1995 if(rx_mode!=MODE_WCW && rx_mode!=MODE_NCW && rx_mode!=MODE_HSMS &&
1996 genparm[CW_DECODE_ENABLE] != 0)
1997 {
1998 prompt_reason("Mode not compatible with morse decode");
1999 goto iniparm;
2000 }
2001 for(i=0; i<MAX_GENPARM; i++)
2002 {
2003 if(genparm[i] < genparm_min[i] || genparm[i] > genparm_max[i])
2004 {
2005 illegal_value:;
2006 sprintf(s,"Illegal value for %s: %d (%d to %d)",genparm_text[i],
2007 genparm[i],genparm_min[i], genparm_max[i]);
2008 prompt_reason(s);
2009 goto iniparm;
2010 }
2011 }
2012 fft1mode=(ui.rx_input_mode&(TWO_CHANNELS+IQ_DATA))/2;
2013 i=fft1_version[fft1mode][genparm[FIRST_FFT_VERNR]];
2014 if( i < 0 || i>=MAX_FFT_VERSIONS)
2015 {
2016 prompt_reason("FFT1 version incompatible with A/D mode");
2017 goto iniparm;
2018 }
2019 if(simd_present == 0)
2020 {
2021 if( fft_cntrl[i].simd != 0)
2022 {
2023 prompt_reason("Parameters say use SIMD - not supported by computer!");
2024 goto iniparm;
2025 }
2026 }
2027 if(genparm[SECOND_FFT_ENABLE] != 0)
2028 {
2029 if(mmx_present == 0)
2030 {
2031 if( fft_cntrl[i].mmx != 0)
2032 {
2033 nommx:;
2034 #if IA64 == 0
2035 prompt_reason("Parameters say use MMX - not supported by computer!");
2036 #else
2037 prompt_reason("Parameters say use MMX - not (yet?) supported on IA64!");
2038 #endif
2039 goto iniparm;
2040 }
2041 }
2042 i=fft1_back_version[ui.rx_rf_channels-1][genparm[FIRST_BCKFFT_VERNR]];
2043 if( i < 0 || i>=MAX_FFT_VERSIONS)
2044 {
2045 prompt_reason("Backwards FFT1 version incompatible with no of channels");
2046 goto iniparm;
2047 }
2048 if(mmx_present == 0)
2049 {
2050 if( fft_cntrl[i].mmx != 0)goto nommx;
2051 }
2052 i=fft2_version[ui.rx_rf_channels-1][genparm[SECOND_FFT_VERNR]];
2053 if( i < 0 || i>=MAX_FFT_VERSIONS)
2054 {
2055 prompt_reason("FFT2 version incompatible with no of channels");
2056 goto iniparm;
2057 }
2058 if(mmx_present == 0)
2059 {
2060 if( fft_cntrl[i].mmx != 0)goto nommx;
2061 }
2062 // Make sure fft1_n and fft2_n are defined.
2063 get_wideband_sizes();
2064 if(kill_all_flag) return;
2065 k=(fft1_n-4)&0xfffe;
2066 if(genparm[FIRST_BCKFFT_ATT_N]>k)
2067 {
2068 i=FIRST_BCKFFT_ATT_N;
2069 goto illegal_value;
2070 }
2071 k=fft2_n-2;
2072 if(genparm[SECOND_FFT_ATT_N]>k)
2073 {
2074 i=SECOND_FFT_ATT_N;
2075 goto illegal_value;
2076 }
2077 }
2078 if(genparm[DA_OUTPUT_SPEED] > ui.rx_max_da_speed||
2079 genparm[DA_OUTPUT_SPEED] < ui.rx_min_da_speed)
2080 {
2081 sprintf(s,"Output sampling speed out of range %d (%d to %d)",
2082 genparm[DA_OUTPUT_SPEED],ui.rx_min_da_speed,
2083 ui.rx_max_da_speed);
2084 prompt_reason(s);
2085 goto iniparm;
2086 }
2087 check_output_no_of_channels();
2088 }
2089 if( wav_read_flag != 0)
2090 {
2091 if(iqflag==1)
2092 {
2093 ui.rx_rf_channels=1;
2094 ui.rx_input_mode|=IQ_DATA;
2095 }
2096 else
2097 {
2098 ui.rx_input_mode|=TWO_CHANNELS;
2099 }
2100 if(dirflag == 1)
2101 {
2102 fg.passband_direction=-1;
2103 }
2104 else
2105 {
2106 fg.passband_direction=1;
2107 }
2108 fft1_direction=fg.passband_direction;
2109 }
2110 if(genparm[AFC_ENABLE] == 0)
2111 {
2112 genparm[CW_DECODE_ENABLE]=0;
2113 }
2114 if(parwrite_flag!=0)goto write_savefile_parms;
2115 }
2116
2117
main_menu(void)2118 void main_menu(void)
2119 {
2120 int rx_rf_channels;
2121 int first_keypress;
2122 int i, j, k;
2123 int uiupd, line;
2124 char s[256], ss[80];
2125 int message_line;
2126 FILE *file;
2127 int *uiparm;
2128 uiparm=(int*)(&ui);
2129 rx_rf_channels=ui.rx_rf_channels;
2130 lir_mutex_init();
2131 eme_flag=0;
2132 first_keypress=0;
2133 iqflag=0;
2134 dirflag=0;
2135 read_eme_database();
2136 linrad_thread_create(THREAD_SYSCALL);
2137 if(kill_all_flag) goto menu_x;
2138 // Save the ui parameters.
2139 // The user has set up the sound cards for normal operation
2140 // with his hardware but some routines, e.g. txtest may change
2141 // the A/D parameters and/or other parameters.
2142 // We will always start here with the initial ui parameters.
2143 if (ui.max_dma_rate < MIN_DMA_RATE || ui.max_dma_rate > MAX_DMA_RATE)
2144 {
2145 ui.max_dma_rate=DEFAULT_MAX_DMA_RATE;
2146 }
2147 if (ui.min_dma_rate < MIN_DMA_RATE || ui.min_dma_rate > ui.max_dma_rate)
2148 {
2149 ui.min_dma_rate=DEFAULT_MIN_DMA_RATE;
2150 }
2151 if ( ui.min_dma_rate > ui.max_dma_rate)
2152 {
2153 ui.min_dma_rate=ui.max_dma_rate;
2154 }
2155 compute_converter_parameters();
2156 verify_network(FALSE);
2157 save_uiparm();
2158 menu_loop:;
2159 if(kill_all_flag)goto menu_x;
2160 tx_setup_flag=FALSE;
2161 lir_set_title("");
2162 restore_uiparm();
2163 clear_screen();
2164 settextcolor(12);
2165 display_rx_input_source(ss);
2166 sprintf(s,"%s %s",PROGRAM_NAME, ss);
2167 lir_text(14,0,s);
2168 if((ui.network_flag&NET_RX_OUTPUT) != 0)lir_text(0,0,"NETSEND");
2169 lir_refresh_screen();
2170 if(kill_all_flag)goto menu_x;
2171 line=2;
2172 settextcolor(14);
2173 if(ui.operator_skil == OPERATOR_SKIL_NEWCOMER)
2174 {
2175 lir_text(14,1,"newcomer mode");
2176 line++;
2177 }
2178 if(ui.operator_skil == OPERATOR_SKIL_EXPERT)
2179 {
2180 lir_text(14,1,"expert mode");
2181 line++;
2182 }
2183 message_line=line;
2184 settextcolor(7);
2185 button_color=7;
2186 if(ui.rx_addev_no != DISABLED_DEVICE_CODE)
2187 {
2188 for(i=0; i<MAX_RX_MODE; i++)
2189 {
2190 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER || newcomer_rx_modes[i] != 0)
2191 {
2192 if(ui.operator_skil == OPERATOR_SKIL_EXPERT || i != MODE_TUNE)
2193 {
2194 sprintf(s,"%c=%s",i+'A',rxmodes[i]);
2195 lir_text(0, line, s);
2196 line++;
2197 }
2198 }
2199 }
2200 }
2201 if((ui.network_flag&NET_RX_INPUT) == 0)
2202 {
2203 lir_text(30,message_line,"1=Process first file named in 'adfile'");
2204 message_line++;
2205 lir_text(30,message_line,"2=Process first file named in 'adwav'");
2206 message_line++;
2207 lir_text(30,message_line,"3=Select file from 'adfile'");
2208 message_line++;
2209 lir_text(30,message_line,"4=Select file from 'adwav'");
2210 message_line++;
2211 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2212 {
2213 lir_text(30,message_line,"5=File converter .raw to .wav");
2214 message_line++;
2215 }
2216 }
2217 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2218 {
2219 lir_text(30,message_line,"T=Toggle network output");
2220 message_line++;
2221 }
2222 if(message_line > line)line=message_line;
2223 line++;
2224 settextcolor(3);
2225 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2226 {
2227 lir_text(0, line , "M=Init moon tracking and EME database");
2228 line++;
2229 lir_text(0, line, "N=Network set up");
2230 line++;
2231 }
2232 lir_text(0, line, "S=Global parms set up");
2233 line++;
2234 lir_text(0, line, "U=A/D and D/A set up for RX");
2235 line++;
2236 if(ui.operator_skil == OPERATOR_SKIL_EXPERT)
2237 {
2238 lir_text(0, line, "V=TX mode set up");
2239 line++;
2240 }
2241 lir_text(0, line, "W=Save current parameters in par_userint");
2242 line++;
2243 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER &&
2244 (ui.network_flag&NET_RX_INPUT) == 0)
2245 {
2246 switch (ui.soundcard_radio)
2247 {
2248 case SOUNDCARD_RADIO_WSE:
2249 lir_text(0, line, "Z=WSE hardware interface test");
2250 line++;
2251 break;
2252
2253 default:
2254 break;
2255 }
2256 }
2257 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2258 {
2259 lir_text(0, line, "F9=Emergency light");
2260 line++;
2261 }
2262 lir_text(0, line, "ESC=Quit program");
2263 settextcolor(14);
2264 lir_text(0, line, "F1 or !=Show keyboard commands (HELP)");
2265 line++;
2266 if(kill_all_flag)goto menu_x;
2267 message_line=line+1;
2268 if(uiparm_change_flag==TRUE)
2269 {
2270 settextcolor(15);
2271 lir_text(5,message_line+1,"PARAMETERS NOT SAVED Press ""W"" to save");
2272 }
2273 settextcolor(7);
2274 if(kill_all_flag) goto menu_x;
2275 if(ui.operator_skil == OPERATOR_SKIL_EXPERT && first_keypress == 0 &&
2276 ui.autostart >= 'A' && ui.autostart <= 'G')
2277 {
2278 lir_inkey=ui.autostart;
2279 }
2280 else
2281 {
2282 if(first_keypress > 1)
2283 {
2284 lir_inkey=first_keypress;
2285 lir_sleep(300000);
2286 }
2287 else
2288 {
2289 to_upper_await_keyboard();
2290 if(kill_all_flag) goto menu_x;
2291 }
2292 }
2293 first_keypress=1;
2294 savefile_parname[0]=0;
2295 calibrate_flag=0;
2296 diskread_flag=0;
2297 file_start_block=-1;
2298 file_stop_block=-1;
2299 diskwrite_flag=FALSE;
2300 freq_from_file=FALSE;
2301 if(ui.use_extio != 0 && ui.extio_type != 4)
2302 {
2303 rx_input_thread = THREAD_EXTIO_INPUT;
2304 }
2305 else
2306 {
2307 rx_input_thread=THREAD_RX_ADINPUT;
2308 if(ui.rx_addev_no == SDR14_DEVICE_CODE ||
2309 ui.rx_addev_no == SDRIQ_DEVICE_CODE )rx_input_thread=THREAD_SDR14_INPUT;
2310 if(ui.rx_addev_no == PERSEUS_DEVICE_CODE)rx_input_thread=THREAD_PERSEUS_INPUT;
2311 if(ui.rx_addev_no == SDRIP_DEVICE_CODE)rx_input_thread=THREAD_SDRIP_INPUT;
2312 if(ui.rx_addev_no == EXCALIBUR_DEVICE_CODE)
2313 rx_input_thread=THREAD_EXCALIBUR_INPUT;
2314 if(ui.rx_addev_no == RTL2832_DEVICE_CODE)
2315 rx_input_thread=THREAD_RTL2832_INPUT;
2316 if(ui.rx_addev_no == MIRISDR_DEVICE_CODE)
2317 rx_input_thread=THREAD_MIRISDR_INPUT;
2318 if(ui.rx_addev_no == BLADERF_DEVICE_CODE)
2319 rx_input_thread=THREAD_BLADERF_INPUT;
2320 if(ui.rx_addev_no == PCIE9842_DEVICE_CODE)
2321 rx_input_thread=THREAD_PCIE9842_INPUT;
2322 if(ui.rx_addev_no == OPENHPSDR_DEVICE_CODE)
2323 rx_input_thread=THREAD_OPENHPSDR_INPUT;
2324 if(ui.rx_addev_no == NETAFEDRI_DEVICE_CODE)rx_input_thread=THREAD_NETAFEDRI_INPUT;
2325 }
2326 if(kill_all_flag)goto menu_x;
2327 sys_func(THRFLAG_PORTAUDIO_STARTSTOP);
2328 ampinfo_reset=workload_reset_flag-1;
2329 curv_xpixel=0;
2330 flat_xpixel=0;
2331 parfilnam=NULL;
2332 lir_status=LIR_OK;
2333 wg_freq_x1=-1;
2334 wav_read_flag=0;
2335 switch ( lir_inkey )
2336 {
2337 case 'T':
2338 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2339 {
2340 if( (ui.network_flag&NET_RX_OUTPUT) == 0)
2341 {
2342 ui.network_flag|=NET_RX_OUTPUT;
2343 }
2344 else
2345 {
2346 ui.network_flag&=NET_RX_INPUT;
2347 }
2348 verify_network(FALSE);
2349 save_uiparm();
2350 uiparm_change_flag=TRUE;
2351 }
2352 break;
2353
2354 case 'M':
2355 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2356 {
2357 init_eme_database();
2358 if(kill_all_flag) goto menu_x;
2359 }
2360 break;
2361
2362 case F1_KEY:
2363 case '!':
2364 help_message(1);
2365 if(kill_all_flag) goto menu_x;
2366 break;
2367
2368 case F8_KEY:
2369 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2370 {
2371 clear_screen();
2372 lir_text(0,0,"Currently selected font (see fonts.c)");
2373 for(i=0; i<16; i++)
2374 {
2375 for(j=0; j<16; j++)
2376 {
2377 k=16*i+j;
2378 sprintf(s,"%c[%2x]",k,k);
2379 lir_text(j*8,i+2,s);
2380 }
2381 }
2382 while(!kill_all_flag)
2383 {
2384 await_keyboard();
2385 sprintf(s,"lir_inkey=%d =0x%02x",lir_inkey,lir_inkey);
2386 clear_lines(22,22);
2387 lir_text(0,22,s);
2388 }
2389 }
2390 break;
2391
2392 case F9_KEY:
2393 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2394 {
2395 lir_fillbox(0,0,screen_width,screen_height,15);
2396 await_keyboard();
2397 }
2398 break;
2399
2400 case '1':
2401 case '3':
2402 if((ui.network_flag&NET_RX_INPUT) == 0)
2403 {
2404 if(ui.rx_dadev_no == -1)goto setad;
2405 rx_input_thread=THREAD_RX_FILE_INPUT;
2406 if(init_diskread(lir_inkey-'1') == 0)
2407 {
2408 goto do_pc_radio;
2409 }
2410 }
2411 break;
2412
2413 case '2':
2414 case '4':
2415 if((ui.network_flag&NET_RX_INPUT) == 0)
2416 {
2417 if(ui.rx_dadev_no == -1)goto setad;
2418 wav_read_flag=1;
2419 rx_input_thread=THREAD_RX_FILE_INPUT;
2420 if(init_diskread(lir_inkey-'2') == 0)
2421 {
2422 goto do_pc_radio;
2423 }
2424 }
2425 break;
2426
2427 case '5':
2428 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2429 {
2430 wav_read_flag=0;
2431 raw2wav();
2432 }
2433 break;
2434
2435 case 'U':
2436 setad:;
2437 sys_func(THRFLAG_SET_RX_IO);
2438 if(kill_all_flag) goto menu_x;
2439 verify_network(FALSE);
2440 save_uiparm();
2441 uiparm_change_flag=TRUE;
2442 break;
2443
2444 case 'V':
2445 if(ui.operator_skil == OPERATOR_SKIL_EXPERT)
2446 {
2447 tx_setup_flag=TRUE;
2448 sys_func(THRFLAG_TX_SETUP);
2449 tx_setup_flag=FALSE;
2450 if(kill_all_flag) goto menu_x;
2451 save_uiparm();
2452 uiparm_change_flag=TRUE;
2453 }
2454 break;
2455
2456 case 'Z':
2457 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2458 {
2459 switch (ui.soundcard_radio)
2460 {
2461 case SOUNDCARD_RADIO_WSE:
2462 hware_interface_test();
2463 if(kill_all_flag) goto menu_x;
2464 break;
2465
2466 default:
2467 break;
2468 }
2469 }
2470 break;
2471
2472 case 'N':
2473 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
2474 {
2475 ui.network_flag=NET_RX_INPUT;
2476 verify_network(TRUE);
2477 if(kill_all_flag) goto menu_x;
2478 save_uiparm();
2479 uiparm_change_flag=TRUE;
2480 }
2481 break;
2482
2483 case 'S':
2484 switch (os_flag)
2485 {
2486 case OS_FLAG_SVGALIB:
2487 lin_global_uiparms(1);
2488 break;
2489
2490 case OS_FLAG_WINDOWS:
2491 win_global_uiparms(1);
2492 break;
2493
2494 case OS_FLAG_X:
2495 x_global_uiparms(1);
2496 break;
2497 }
2498 if(kill_all_flag) goto menu_x;
2499 save_uiparm();
2500 uiparm_change_flag=TRUE;
2501 break;
2502
2503 case 'W':
2504 file = fopen(userint_filename, "w");
2505 if (file == NULL)
2506 {
2507 lirerr(1029);
2508 goto menu_x;
2509 }
2510 ui.check=UI_VERNR;
2511 for(i=0; i<MAX_UIPARM; i++)
2512 {
2513 fprintf(file,"%s [%d]\n",uiparm_text[i],uiparm[i]);
2514 }
2515 parfile_end(file);
2516 if(kill_all_flag) goto menu_x;
2517 settextcolor(15);
2518 clear_lines(message_line+1,message_line+1);
2519 lir_text(0, message_line, "User interface setup saved");
2520 k=message_line;
2521 for(i=0; i<MAX_UIPARM-1; i+=2)
2522 {
2523 if( k < screen_last_line)
2524 {
2525 k++;
2526 sprintf(s,"%s [%d] ",uiparm_text[i],uiparm[i]);
2527 lir_text(5,k, s);
2528 sprintf(s,"%s [%d] ",uiparm_text[i+1],uiparm[i+1]);
2529 lir_text(40,k, s);
2530 }
2531 }
2532 if(i < MAX_UIPARM-1)
2533 {
2534 i++;
2535 sprintf(s,"%s [%d] ",uiparm_text[i],uiparm[i]);
2536 if( (message_line+i+1) <= screen_last_line)lir_text(5,message_line+i+1, s);
2537 }
2538 settextcolor(7);
2539 await_processed_keyboard();
2540 if(kill_all_flag) goto menu_x;
2541 first_keypress=lir_inkey;
2542 uiparm_change_flag=FALSE;
2543 goto menu_loop;
2544
2545 default:
2546 if(ui.rx_addev_no == DISABLED_DEVICE_CODE)break;
2547 if(ui.rx_addev_no == UNDEFINED_DEVICE_CODE)goto setad;
2548 rx_mode=(lir_inkey-'A');
2549 if( rx_mode < 0 || rx_mode>=MAX_RX_MODE)goto menu_loop;
2550 if(ui.operator_skil == OPERATOR_SKIL_NEWCOMER && newcomer_rx_modes[rx_mode]==0)goto menu_loop;
2551 if(ui.operator_skil != OPERATOR_SKIL_EXPERT && rx_mode == MODE_TUNE)goto menu_loop;
2552 if( (ui.network_flag&NET_RX_INPUT)==0 && ui.rx_input_mode < 0)goto setad;
2553 do_pc_radio:;
2554 if(ui.rx_dadev_no == DISABLED_DEVICE_CODE)
2555 {
2556 ui.rx_max_da_speed=1000000;
2557 ui.rx_min_da_speed=5000;
2558 ui.rx_max_da_channels=2;
2559 ui.rx_min_da_channels=2;
2560 }
2561 if(ui.rx_max_da_channels==0)goto setad;
2562 if( ui.rx_min_da_speed < 1000 ||
2563 ui.rx_max_da_speed < ui.rx_min_da_speed)
2564 {
2565 clear_screen();
2566 lir_text(3,3,"ERROR: illegal limits for Rx D/A speed");
2567 lir_text(5,5,press_any_key);
2568 await_keyboard();
2569 goto setad;
2570 }
2571 calibrate_flag=0;
2572 parfilnam=NULL;
2573 open_mouse();
2574 uiupd=FALSE;
2575 if((ui.network_flag&NET_RX_INPUT) == 0)
2576 {
2577 updparm:;
2578 init_genparm(uiupd);
2579 if(kill_all_flag) goto menu_x;
2580 }
2581 clear_screen();
2582 settextcolor(7);
2583 #if (USERS_EXTRA_PRESENT == 1)
2584 init_users_extra();
2585 #endif
2586 lir_status=LIR_OK;
2587 lir_rxout_status=LIR_OK;
2588 lir_rxin_status=LIR_OK;
2589 fft1_waterfall_flag=0;
2590 all_threads_started=FALSE;
2591 cg.oscill_on=0;
2592 first_txproc_no=tg.spproc_no;
2593 use_tx=ui.tx_enable;
2594 if(diskread_flag >= 2 ||
2595 ui.tx_addev_no == UNDEFINED_DEVICE_CODE ||
2596 ui.tx_dadev_no == UNDEFINED_DEVICE_CODE)use_tx=0;
2597 if(read_txpar_file()==FALSE)use_tx=0;
2598 if(!ftdi_library_flag)
2599 {
2600 if( ui.soundcard_radio == SOUNDCARD_RADIO_ELEKTOR ||
2601 ui.soundcard_radio == SOUNDCARD_RADIO_SOFT66)
2602 {
2603 i=load_ftdi_library();
2604 if(i != 0)goto menu_loop;
2605 }
2606 if(ui.soundcard_radio == SOUNDCARD_RADIO_SOFT66)
2607 {
2608 load_soft66_library();
2609 if(!soft66_library_flag)goto menu_loop;
2610 }
2611 }
2612 switch (rx_mode)
2613 {
2614 case MODE_WCW:
2615 case MODE_NCW:
2616 case MODE_HSMS:
2617 case MODE_SSB:
2618 case MODE_QRSS:
2619 use_bfo=1;
2620 goto do_normal_rx;
2621
2622 case MODE_FM:
2623 case MODE_AM:
2624 use_bfo=0;
2625 do_normal_rx:;
2626 i=ui.rx_ad_speed;
2627 normal_rx_routine();
2628 if(i != ui.rx_ad_speed)
2629 {
2630 save_uiparm();
2631 uiparm_change_flag=TRUE;
2632 }
2633 if(lir_status == LIR_DLL_FAILED)goto menu_loop;
2634 break;
2635
2636 case MODE_TXTEST:
2637 txtest_routine();
2638 if(lir_status == LIR_DLL_FAILED)goto menu_loop;
2639 if(kill_all_flag)goto menu_x;
2640 goto txtest_exit;
2641
2642 // Soundcard test mode
2643 case MODE_RX_ADTEST:
2644 rx_adtest_routine();
2645 if(lir_status == LIR_DLL_FAILED)goto menu_loop;
2646 break;
2647
2648 // Tune WSE hardware.
2649 case MODE_TUNE:
2650 tune_wse_routine();
2651 if(lir_status == LIR_DLL_FAILED)goto menu_loop;
2652 break;
2653
2654 case MODE_RADAR:
2655 radar_routine();
2656 if(lir_status == LIR_DLL_FAILED)goto menu_loop;
2657 break;
2658
2659 default:
2660 lirerr(436);
2661 }
2662 rx_modes_exit:;
2663 if(kill_all_flag) goto menu_x;
2664 close_network_sockets();
2665 rx_rf_channels=ui.rx_rf_channels;
2666 if( (diskread_flag&(2+4+8)) != 0)
2667 {
2668 restore_uiparm();
2669 diskread_flag=4;
2670 fclose(save_rd_file);
2671 save_rd_file=NULL;
2672 }
2673 txtest_exit:;
2674 free_buffers();
2675 // *******************************************************************
2676 // ******************* main exit from processing modes ***************
2677 if(lir_rxout_status != LIR_OK)
2678 {
2679 clear_screen();
2680 lir_text(5,5,"Soundcard for Rx output disabled");
2681 lir_text(5,6,"Could not be opened at specified speed");
2682 lir_text(5,7,"In duplex mode the same speed may be necessary for");
2683 lir_text(5,8,"output and input. The device speed may be locked");
2684 lir_text(5,9,"by Linrad input or some other application.");
2685 lir_text(10,12,press_any_key);
2686 await_keyboard();
2687 if(kill_all_flag) goto menu_x;
2688 lir_status = LIR_OK;
2689 goto menu_loop;
2690 }
2691 switch(lir_status)
2692 {
2693 case LIR_TUNEERR:
2694 goto menu_loop;
2695
2696 case LIR_SAVE_UIPARM:
2697 save_uiparm();
2698 goto menu_loop;
2699
2700 case LIR_FFT1ERR:
2701 clear_screen();
2702 lir_text(5,5,"Out of memory. Try less demanding parameters");
2703 lir_text(5,8,press_any_key);
2704 await_keyboard();
2705 if(kill_all_flag) goto menu_x;
2706 go_updparm:;
2707 uiupd=TRUE;
2708 restore_uiparm();
2709 goto updparm;
2710
2711 case LIR_NEW_POL:
2712 clear_screen();
2713 select_pol_default();
2714 if(kill_all_flag) goto menu_x;
2715 lir_status = LIR_OK;
2716 goto do_pc_radio;
2717
2718 case LIR_POWTIM:
2719 goto do_pc_radio;
2720 }
2721 if(lir_status < LIR_OK)
2722 {
2723 goto go_updparm;
2724 }
2725 fft1_waterfall_flag=0;
2726 wt_kbd:;
2727 clear_screen();
2728 line=0;
2729 settextcolor(12);
2730 lir_text(25,line,PROGRAM_NAME);
2731 if(diskread_flag >=2 )
2732 {
2733 settextcolor(14);
2734 lir_text(40,line,savefile_name);
2735 }
2736 line+=2;
2737 settextcolor(15);
2738 sprintf(s,"F1 = Info about the %s mode",rxmodes[rx_mode]);
2739 lir_text(11,line,s);
2740 line++;
2741 sprintf(s,"B = Back to %s without change",rxmodes[rx_mode]);
2742 lir_text(12,line,s);
2743 line++;
2744 lir_text(12,line,"P = Change parameters");
2745 line++;
2746 lir_text(12,line,"C = Calibrate");
2747 line++;
2748 if(rx_rf_channels == 2)
2749 {
2750 lir_text(12,line,"D = Select Pol. default");
2751 line++;
2752 }
2753 line++;
2754 settextcolor(7);
2755 sprintf(s,"Current parameters (file: %s)",parfilnam);
2756 lir_text(2,line,s);
2757 line++;
2758 for(i=0; i<MAX_GENPARM+1; i++)
2759 {
2760 sprintf(s,"%s [%d] ",genparm_text[i],genparm[i]);
2761 if( line <= screen_last_line)lir_text(2,line, s);
2762 line++;
2763 }
2764 await_processed_keyboard();
2765 if(kill_all_flag) goto menu_x;
2766 switch (lir_inkey)
2767 {
2768 case 'B':
2769 goto do_pc_radio;
2770
2771 case 'C':
2772 if((ui.network_flag&NET_RX_INPUT) == 0)
2773 {
2774 init_genparm(FALSE);
2775 if(kill_all_flag) goto menu_x;
2776 }
2777 cal_package();
2778 lir_status=LIR_OK;
2779 goto rx_modes_exit;
2780
2781 case 'D':
2782 if(rx_rf_channels == 2)select_pol_default();
2783 if(kill_all_flag) goto menu_x;
2784 break;
2785
2786 case 'P':
2787 uiupd=TRUE;
2788 goto updparm;
2789
2790 case F1_KEY:
2791 case '!':
2792 help_message(280+rx_mode);
2793 break;
2794
2795 case 'X':
2796 goto menu_loop;
2797 }
2798 goto wt_kbd;
2799 }
2800 if(!kill_all_flag)goto menu_loop;
2801 menu_x:;
2802 close_mouse();
2803 free_buffers();
2804 close_network_sockets();
2805 if(portaudio_active_flag)sys_func(THRFLAG_PORTAUDIO_STOP);
2806 linrad_thread_stop_and_join(THREAD_SYSCALL);
2807 lir_mutex_destroy();
2808 show_errmsg(1);
2809 if(lir_errcod != 0)
2810 {
2811 lir_inkey=1;
2812 while(lir_inkey == 1)
2813 {
2814 await_keyboard();
2815 }
2816 }
2817 command_extio_library(EXTIO_COMMAND_KILL_ALL);
2818 unload_ftdi_library();
2819 unload_soft66_library();
2820 }
2821
2822