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 <unistd.h>
25 #include <ctype.h>
26 #include <string.h>
27 #include "globdef.h"
28 #include "uidef.h"
29 #include "fft1def.h"
30 #include "fft2def.h"
31 #include "fft3def.h"
32 #include "seldef.h"
33 #include "sigdef.h"
34 #include "screendef.h"
35 #include "vernr.h"
36 #include "rusage.h"
37 #include "thrdef.h"
38 #include "conf.h"
39 #include "keyboard_def.h"
40 #include "blnkdef.h"
41 #include "caldef.h"
42 #include "txdef.h"
43 #include "options.h"
44 #include "padef.h"
45 #include "sdrdef.h"
46 #include "hwaredef.h"
47
48 #if(IA64 == 0)
49 #define QWORD long
50 #else
51 #define QWORD int
52 #endif
53
54 #if(OSNUM == OSNUM_WINDOWS)
55 #include <windows.h>
56 #include <winsock.h>
57 #define INVSOCK INVALID_SOCKET
58 #endif
59
60 #if(OSNUM == OSNUM_LINUX)
61 #define INVSOCK -1
62 #define WORD unsigned short int
63 #define DWORD u_int32_t
64
65 typedef struct _SYSTEMTIME {
66 WORD wYear;
67 WORD wMonth;
68 WORD wDayOfWeek;
69 WORD wDay;
70 WORD wHour;
71 WORD wMinute;
72 WORD wSecond;
73 WORD wMilliseconds;
74 } SYSTEMTIME;
75
76 #endif
77
78 // Define fseeko and ftello. Some old distributions, e.g. RedHat 9
79 // have the functions but not in the headers.
80 #ifndef fseeko
81 int fseeko(FILE *stream, off_t offset, int whence);
82 #endif
83 #ifndef ftello
84 off_t ftello(FILE *stream);
85 #endif
86
87
88 #define REMEMBER_UNKNOWN -1
89 #define REMEMBER_NOTHING -2
90 #define REMEMBER_PERSEUS -3
91 #define REMEMBER_SDR14 -4
92
93 int remember_proprietery_chunk[2];
94
95
96
97 #if (USERS_EXTRA_PRESENT == 1)
98 extern float users_extra_update_interval;
99 extern double users_extra_time;
100 void users_extra(void);
101 #endif
102
103 #define MAX_FILES 256
104 #define MAX_NAMLEN 36
105
106 #define DISKSAVE_X_SIZE 48*text_width
107 #define DISKSAVE_Y_SIZE 7*text_height
108 #define DISKSAVE_SCREEN_SIZE (DISKSAVE_X_SIZE*DISKSAVE_Y_SIZE)
109 #define DEBMEM 64
110
111
112 typedef struct rcvr_hdr{
113 char chunkID[4]; // ="rcvr" (chunk perseus beta0.2)
114 QWORD chunkSize; // chunk length
115 QWORD nCenterFrequencyHz; // center frequency
116 QWORD SamplingRateIdx; // 0=125K, 1=250K, 2=500K, 3=1M, 4=2M
117 QWORD timeStart; // start time of the recording (time(&timeStart))
118 unsigned short wAttenId; // 0=0dB, 1=10dB, 2=20dB, 3=30dB
119 char bAdcPresel; // 0=Presel Off, 1=Presel On
120 char bAdcPreamp; // 0=ADC Preamp Off, 1=ADC Preamp ON
121 char bAdcDither; // 0=ADC Dither Off, 1=ADC Dither ON
122 char bSpare; // for future use (default = 0)
123 char rsrvd[16]; // for future use (default = 000..0)
124 char extra[16]; // QS1R and others may use longer chunks
125 }RCVR;
126
127 // "auxi" chunk as used in the SpectraVue WAV files
128 typedef struct auxi_hdr{
129 char chunkID[4]; // ="auxi" (chunk rfspace)
130 QWORD chunkSize; // chunk length
131 SYSTEMTIME StartTime;
132 SYSTEMTIME StopTime;
133 DWORD CenterFreq; //receiver center frequency
134 DWORD ADFrequency; //A/D sample frequency before downsampling
135 DWORD IFFrequency; //IF freq if an external down converter is used
136 DWORD Bandwidth; //displayable BW if you want to limit the display to less than Nyquist band
137 DWORD IQOffset; //DC offset of the I and Q channels in 1/1000's of a count
138 DWORD Unused2;
139 DWORD Unused3;
140 DWORD Unused4;
141 DWORD Unused5;
142 char sdr_radio_nonsense[4000];
143 }AUXI;
144 RCVR perseus_hdr;
145 AUXI sdr14_hdr;
146
147
148 void write_wav_header(int begin);
149 int open_savefile(char *s);
150 fpos_t wav_wrpos;
151 int sel_parm;
152 int sel_line;
153
154
init_os_independent_globals(void)155 void init_os_independent_globals(void)
156 {
157 FD *net_fds;
158 int i;
159 wg_waterf_zero_time=0;
160 net_fds=(FD*)(&netfd);
161 allow_wse_parport=0;
162 keyboard_buffer_ptr=0;
163 keyboard_buffer_used=0;
164 mouse_flag=0;
165 lbutton_state=0;
166 rbutton_state=0;
167 new_lbutton_state=0;
168 new_rbutton_state=0;
169 // Make sure we know that no memory space is reserved yet.
170 wg_waterf=NULL;
171 bg_waterf=NULL;
172 fft3_handle=NULL;
173 hires_handle=NULL;
174 fft1_handle=NULL;
175 blanker_handle=NULL;
176 baseband_handle=NULL;
177 afc_handle=NULL;
178 calmem_handle=NULL;
179 txmem_handle=NULL;
180 vga_font=NULL;
181 dx=NULL;
182 // and that analog io is closed
183 rx_audio_in=-1;
184 rx_audio_out=-1;
185 sdr=-1;
186 snd[RXDA].block_bytes=0;
187 tx_daout_block=0;
188 tx_audio_in=-1;
189 tx_audio_out=-1;
190 tx_flag=0;
191 // Clear flags
192 workload_reset_flag=0;
193 kill_all_flag=0;
194 lir_errcod=0;
195 for(i=0; i<THREAD_MAX; i++)
196 {
197 thread_command_flag[i]=THRFLAG_NOT_ACTIVE;
198 thread_status_flag[i]=THRFLAG_NOT_ACTIVE;
199 }
200 threads_running=FALSE;
201 write_log=FALSE;
202 tx_hware_fqshift=0;
203 rx_hware_fqshift=0;
204 no_of_rx_overrun_errors=0;
205 no_of_rx_underrun_errors=0;
206 no_of_tx_overrun_errors=0;
207 no_of_tx_underrun_errors=0;
208 count_rx_underrun_flag=FALSE;
209 netstart_time=0;
210 for(i=0; i<MAX_NET_FD; i++)
211 {
212 net_fds[i]=INVSOCK;
213 }
214 portaudio_active_flag=FALSE;
215 screensave_flag=FALSE;
216 usb2lpt_flag=FALSE;
217 internal_generator_flag=0;
218 internal_generator_noise=0;
219 internal_generator_att=0;
220 truncate_flag=0;
221 extio_handle=NULL;
222 extio_running=0;
223 refresh_screen_flag=TRUE;
224 ftdi_library_flag=FALSE;
225 libusb1_library_flag=FALSE;
226 libusb0_library_flag=FALSE;
227 rtlsdr_library_flag=FALSE;
228 mirisdr_library_flag=FALSE;
229 usb2lpt_flag=FALSE;
230 }
231
skip_calibration(void)232 int skip_calibration(void)
233 {
234 int rdbuf[10], chkbuf[10];
235 int i, mm;
236 if( (save_init_flag&1) == 1)
237 {
238 // The raw file contains calibration data for fft1_filtercorr.
239 i=fread(rdbuf, sizeof(int),10,save_rd_file);
240 if(i != 10)goto exx;
241 if(rdbuf[7] == 0)
242 {
243 // The filtercorr function was saved in the frequency domain in
244 // rdbuf[1] points.
245 mm=rdbuf[1];
246 }
247 else
248 {
249 // The correction function was stored in the time domain in rdbuf[7] points
250 mm=rdbuf[7];
251 }
252 for(i=0; i<mm; i++)
253 {
254 if((int)fread(timf1_char, sizeof(float), 2*rdbuf[6]+1, save_rd_file)
255 != 2*rdbuf[6]+1)goto exx;
256 }
257 if(10 != fread(chkbuf, sizeof(int),10,save_rd_file))goto exx;
258 for(i=0; i<10; i++)
259 {
260 if(rdbuf[i]!=chkbuf[i])
261 {
262 exx:;
263 lir_text(1,7,"ERROR. File corrupted");
264 return FALSE;
265 }
266 }
267 }
268 if( (save_init_flag&2) == 2)
269 {
270 i=fread(rdbuf, sizeof(int),10,save_rd_file);
271 if(i != 10)goto exx;
272 bal_segments=rdbuf[0];
273 mm=rdbuf[3]*rdbuf[0];
274 for(i=0; i<mm; i++)
275 {
276 if(fread(timf1_char, sizeof(float), 8, save_rd_file) !=8)goto exx;
277 }
278 if(fread(chkbuf, sizeof(int),10,save_rd_file)!=10)goto exx;
279 for(i=0; i<10; i++)
280 {
281 if(rdbuf[i]!=chkbuf[i])goto exx;
282 }
283 }
284 return TRUE;
285 }
286
287
raw2wav(void)288 void raw2wav(void)
289 {
290 int amplitude_factor;
291 int j, k, bits;
292 int n;
293 int wav_wrbytes, wavfile_bytes;
294 int line;
295 char fnam[256], s[80];
296 int *samp;
297 getin:;
298 clear_screen();
299 settextcolor(14);
300 lir_text(10,1,"RAW to WAV file converter.");
301 settextcolor(7);
302 lir_text(1,2,"Input file name:");
303 j=lir_get_filename(17,2,fnam);
304 if(j==0)return;
305 j=open_savefile(fnam);
306 if(j!=0)goto getin;
307 clear_screen();
308 if(ui.rx_ad_channels != 1 && ui.rx_ad_channels != 2)
309 {
310 fclose(save_rd_file);
311 lir_text(0,0,"Can only write 1 or 2 audio channels.");
312 sprintf(s,"This file has %d channels.",ui.rx_ad_channels);
313 lir_text(0,2,s);
314 lir_text(5,3,press_any_key);
315 await_keyboard();
316 return;
317 }
318 rx_daout_channels=ui.rx_ad_channels;
319 genparm[DA_OUTPUT_SPEED]=ui.rx_ad_speed;
320 snd[RXAD].block_bytes=8192;
321 if((ui.rx_input_mode&DWORD_INPUT) != 0)
322 {
323 bits=18;
324 rx_daout_bytes=3;
325 wav_wrbytes=(3*snd[RXAD].block_bytes)/4;
326 save_rw_bytes=18*snd[RXAD].block_bytes/32;
327 }
328 else
329 {
330 bits=16;
331 rx_daout_bytes=2;
332 wav_wrbytes=snd[RXAD].block_bytes;
333 save_rw_bytes=snd[RXAD].block_bytes;
334 }
335 timf1p_pa=0;
336 rxin_isho=(short int*)timf1_char;
337 rxin_int=(int*)timf1_char;
338 rxin_char=(char*)timf1_char;
339 rx_read_bytes=snd[RXAD].block_bytes;
340 timf1_char=malloc(snd[RXAD].block_bytes);
341 if(timf1_char == NULL)lirerr(34214);
342 rawsave_tmp=malloc(save_rw_bytes);
343 if(rawsave_tmp==NULL)lirerr(34124);
344 amplitude_factor=1;
345 sprintf(s,"Input file %s uses %d bits per sample",fnam,bits);
346 lir_text(0,0,s),
347 line=1;
348 wavfile_bytes=0;
349 if(fg.passband_direction <0 && (ui.rx_input_mode&IQ_DATA)!=0)
350 {
351 lir_text(0,line,"The passband direction flag is set, I and Q will be exchanged");
352 line++;
353 }
354 if((ui.rx_input_mode&DWORD_INPUT) != 0)
355 {
356 // This file uses 18 bits per sample. Check whether more
357 // than 16 bits actually contain valid data.
358 lir_text(0,line,"Scanning file for largest sample.");
359 line++;
360 if(skip_calibration() == FALSE)goto errx;
361 k=0;
362 while(diskread_flag != 4)
363 {
364 diskread_block_counter++;
365 n=fread(rawsave_tmp,1,save_rw_bytes,save_rd_file);
366 if(n != save_rw_bytes)
367 {
368 while(n != save_rw_bytes)
369 {
370 rawsave_tmp[n]=0;
371 n++;
372 }
373 diskread_flag=4;
374 }
375 expand_rawdat();
376 for(n=0; n<snd[RXAD].block_bytes; n+=4)
377 {
378 samp=(int*)(&timf1_char[n]);
379 if(k<abs(samp[0]))k=abs(samp[0]);
380 }
381 sprintf(s,"Blk %.0f (max ampl 0x%x)",diskread_block_counter,k);
382 lir_text(1,line,s);
383 }
384 line++;
385 amplitude_factor=0x7fffffff/k;
386 sprintf(s,"Headroom to saturation is a factor %d",amplitude_factor);
387 lir_text(1,line,s);
388 line++;
389 if(amplitude_factor >= 8)
390 {
391 amplitude_factor=8;
392 lir_text(1,line,
393 "The .WAV file can be written in 16 bit format (left shifted by 2)");
394 line++;
395 goto gtfmt_a;
396 }
397 else
398 {
399 if(amplitude_factor==1)
400 {
401 j=18;
402 }
403 else
404 {
405 j=17;
406 }
407 sprintf(s,"The input file uses %d significant bits",j);
408 lir_text(1,line,s);
409 line++;
410 gtfmt_a:;
411 lir_text(1,line,"Do you wish to use 24 bit .WAV format (Y/N)?");
412 gtfmt:;
413 to_upper_await_keyboard();
414 if(lir_inkey == 'N')
415 {
416 rx_daout_bytes=2;
417 wav_wrbytes=snd[RXAD].block_bytes/2;
418 }
419 else
420 {
421 if(lir_inkey != 'Y')goto gtfmt;
422 }
423 }
424 fclose(save_rd_file);
425 j=open_savefile(fnam);
426 if(j!=0)lirerr(954362);
427 }
428 wavsave_start_stop(line+1);
429 if(wav_write_flag < 0)
430 {
431 wav_write_flag=0;
432 return;
433 }
434 if(wav_write_flag == 0)return;
435 diskread_block_counter=0;
436 wavfile_bytes=48;
437 if(skip_calibration() == FALSE)goto errx;
438 while(diskread_flag != 4)
439 {
440 diskread_block_counter++;
441 if( (ui.rx_input_mode&DWORD_INPUT) == 0)
442 {
443 rxin_isho=(short int*)(timf1_char);
444 n=fread(rxin_isho,1,snd[RXAD].block_bytes,save_rd_file);
445 if(n != snd[RXAD].block_bytes)
446 {
447 while(n != snd[RXAD].block_bytes)
448 {
449 timf1_char[n]=0;
450 n++;
451 }
452 diskread_flag=4;
453 }
454 }
455 else
456 {
457 n=fread(rawsave_tmp,1,save_rw_bytes,save_rd_file);
458 if(n != save_rw_bytes)
459 {
460 while(n != save_rw_bytes)
461 {
462 rawsave_tmp[n]=0;
463 n++;
464 }
465 diskread_flag=4;
466 }
467 expand_rawdat();
468 k=0;
469 if(rx_daout_bytes==3)
470 {
471 k=0;
472 for(n=0; n<snd[RXAD].block_bytes; n+=4)
473 {
474 timf1_char[k ]=timf1_char[n+1];
475 timf1_char[k+1]=timf1_char[n+2];
476 timf1_char[k+2]=timf1_char[n+3];
477 k+=3;
478 }
479 }
480 else
481 {
482 for(n=0; n<snd[RXAD].block_bytes; n+=4)
483 {
484 samp=(int*)(&timf1_char[n]);
485 samp[0]*=amplitude_factor;
486 timf1_char[k ]=timf1_char[n+2];
487 timf1_char[k+1]=timf1_char[n+3];
488 k+=2;
489 }
490 }
491 }
492 if(fg.passband_direction < 0 && (ui.rx_input_mode&IQ_DATA)!=0)
493 {
494 if(rx_daout_bytes==3)
495 {
496 for(j=0; j<wav_wrbytes; j+=6)
497 {
498 k=timf1_char[j];
499 timf1_char[j]=timf1_char[j+3];
500 timf1_char[j+3]=k;
501 k=timf1_char[j+1];
502 timf1_char[j+1]=timf1_char[j+4];
503 timf1_char[j+4]=k;
504 k=timf1_char[j+2];
505 timf1_char[j+2]=timf1_char[j+5];
506 timf1_char[j+5]=k;
507 }
508 }
509 else
510 {
511 for(j=0; j<wav_wrbytes; j+=4)
512 {
513 k=timf1_char[j];
514 timf1_char[j]=timf1_char[j+2];
515 timf1_char[j+2]=k;
516 k=timf1_char[j+1];
517 timf1_char[j+1]=timf1_char[j+3];
518 timf1_char[j+3]=k;
519 }
520 }
521 }
522 if(fwrite(timf1_char,wav_wrbytes,1,wav_file)!=1 ||
523 (unsigned int)(wavfile_bytes)+(unsigned int)(wav_wrbytes) > 0x7fffffff)
524 {
525 wavsave_start_stop(0);
526 lir_text(1,7,"ERROR on write. File too big?");
527 goto errbig;
528 }
529 wavfile_bytes+=wav_wrbytes;
530 sprintf(s,"%.0f ",diskread_block_counter);
531 lir_text(1,7,s);
532 }
533 errbig:;
534 wavsave_start_stop(0);
535 lir_text(1,7,"Conversion sucessful.");
536 errx:;
537 if(wavfile_bytes < 100000)
538 {
539 sprintf(s,"%d bytes written",wavfile_bytes);
540 }
541 else
542 {
543 if(wavfile_bytes < 10000000)
544 {
545 sprintf(s,"%.2f kilobytes written",0.001*wavfile_bytes);
546 }
547 else
548 {
549 sprintf(s,"%.2f megabytes written",0.000001*wavfile_bytes);
550 }
551 }
552 lir_text(1,9,s);
553 lir_text(5,11,press_any_key);
554 free(timf1_char);
555 free(rawsave_tmp);
556 fclose(save_rd_file);
557 await_keyboard();
558 }
559
open_savefile(char * s)560 int open_savefile(char *s)
561 {
562 int i;
563 i=0;
564 while(s[i] == ' ')i++;
565 if(s[i] == 0)
566 {
567 lir_text(5,4,"No file name given.");
568 goto errfile_1;
569 }
570 save_rd_file = fopen(s, "rb");
571 if (save_rd_file == NULL)
572 {
573 if(errno == EFBIG)
574 {
575 lir_text(5,3,"File too large.");
576 }
577 errfile:;
578 lir_text(5,4,"Can not open file (Corrupted?)");
579 lir_text(5,5,s);
580 errfile_1:;
581 await_keyboard();
582 return 1;
583 }
584 diskread_flag=2;
585 // Read a Linrad.raw file
586 // The original file format had ui.rx_input_mode as the first data item.
587 // Later versions use the first item as a flag to know the
588 // contents of the file.
589 i=fread(&ui.rx_input_mode,sizeof(int),1,save_rd_file);
590 if(i != 1)goto errfile;
591 // In case ui.rx_input_mode is negative the file contains more data.
592 if(ui.rx_input_mode < 0)
593 {
594 remember_proprietery_chunk[0]=ui.rx_input_mode;
595 switch (ui.rx_input_mode)
596 {
597 case REMEMBER_UNKNOWN:
598 case REMEMBER_NOTHING:
599 break;
600
601 case REMEMBER_PERSEUS:
602 i=fread(&remember_proprietery_chunk[1],sizeof(int),1,save_rd_file);
603 if(i !=1 )goto errfile;
604 i=fread(&perseus_hdr.nCenterFrequencyHz,1,
605 remember_proprietery_chunk[1],save_rd_file);
606 if(i != remember_proprietery_chunk[1])goto errfile;
607 break;
608
609 case REMEMBER_SDR14:
610 i=fread(&remember_proprietery_chunk[1],sizeof(int),1,save_rd_file);
611 if(i !=1 )goto errfile;
612 i=fread(&sdr14_hdr.StartTime,1,
613 remember_proprietery_chunk[1],save_rd_file);
614 if(i != remember_proprietery_chunk[1] )goto errfile;
615 break;
616
617 default:
618 lir_text(5,3,"This Linrad version is too old");
619 goto errfile;
620 }
621 i=fread(&diskread_time,sizeof(double),1,save_rd_file);
622 if(i!=1)goto errfile;
623 i=fread(&fg.passband_center,sizeof(double),1,save_rd_file);
624 freq_from_file=TRUE;
625 if(i!=1)goto errfile;
626 i=fread(&fg.passband_direction,sizeof(int),1,save_rd_file);
627 if(i!=1)goto errfile;
628 if(abs(fg.passband_direction) != 1)goto errfile;
629 fft1_direction=fg.passband_direction;
630 i=fread(&ui.rx_input_mode,sizeof(int),1,save_rd_file);
631 if(i!=1)goto errfile;
632 }
633 else
634 {
635 diskread_time=0;
636 fg.passband_center=0;
637 fg.passband_direction=1;
638 fft1_direction=fg.passband_direction;
639 }
640 if(ui.rx_input_mode >= MODEPARM_MAX)goto errfile;
641 i=fread(&ui.rx_rf_channels,sizeof(int),1,save_rd_file);
642 if(i!=1)goto errfile;
643 if(ui.rx_rf_channels == 2)ui.rx_input_mode|=TWO_CHANNELS;
644 i=fread(&ui.rx_ad_channels,sizeof(int),1,save_rd_file);
645 if(i!=1)goto errfile;
646 if(ui.rx_ad_channels > 4 || ui.rx_ad_channels < 1)goto errfile;
647 if(ui.rx_ad_channels != ui.rx_rf_channels &&
648 ui.rx_ad_channels != 2*ui.rx_rf_channels)goto errfile;
649 i=fread(&ui.rx_ad_speed,sizeof(int),1,save_rd_file);
650 if(i!=1)goto errfile;
651 save_init_flag=0;
652 i=fread(&save_init_flag,1,1,save_rd_file);
653 if(i!=1)goto errfile;
654 return 0;
655 }
656
could_not_create(char * filename,int line)657 void could_not_create(char *filename, int line)
658 {
659 lir_text(0,line,"Could not create file!!");
660 lir_text(0,line+1,filename);
661 lir_text(0,line+2,"Make sure directory exists and that the filename is not");
662 lir_text(0,line+3,"a diredctory name.");
663 lir_text(0,line+4,press_any_key);
664 clear_await_keyboard();
665 }
666
667
open_parfile(int type,char * mode)668 FILE *open_parfile(int type, char *mode)
669 {
670 char s[80];
671 int i,j;
672 // Find out if there is a file with parameters for the current graph.
673 // Make the default graph if no file is found, else use old data.
674 i=0;
675 if(savefile_parname[0]!=0)
676 {
677 while(savefile_parname[i]!=0)
678 {
679 s[i]=savefile_parname[i];
680 i++;
681 }
682 }
683 else
684 {
685 while(rxpar_filenames[rx_mode][i]!=0)
686 {
687 s[i]=rxpar_filenames[rx_mode][i];
688 i++;
689 }
690 }
691 s[i ]='_';
692 i++;
693 j=0;
694 while(graphtype_names[type][j] != 0)
695 {
696 s[i]=graphtype_names[type][j];
697 i++;
698 j++;
699 }
700 s[i]=0;
701 return fopen(s, mode);
702 }
703
704
read_modepar_file(int type)705 int read_modepar_file(int type)
706 {
707 int i, j, k, max_intpar, max_floatpar;
708 int *wgi;
709 float *wgf;
710 double *wgd;
711 char *parinfo;
712 FILE *wgfile;
713 wgfile = open_parfile(type,"r");
714 if (wgfile == NULL)return 0;
715 parinfo=malloc(4096);
716 if(parinfo == NULL)
717 {
718 lirerr(1082);
719 return 0;
720 }
721 for(i=0; i<4096; i++) parinfo[i]=0;
722 i=fread(parinfo,1,4095,wgfile);
723 fclose(wgfile);
724 if(i == 4095)goto txt_err;
725 wgi=(int*)(graphtype_parptr[type]);
726 k=0;
727 max_intpar = graphtype_max_intpar[type];
728 max_floatpar = graphtype_max_floatpar[type];
729 for(i=0; i<max_intpar; i++)
730 {
731 while( (parinfo[k]==' ' || parinfo[k]== '\n' ) && k<4095)k++;
732 j=0;
733 while(parinfo[k]== graphtype_partexts_int[type][i][j] && k<4095)
734 {
735 k++;
736 j++;
737 }
738 if(graphtype_partexts_int[type][i][j] != 0)
739 {
740 txt_err:;
741 free(parinfo);
742 return 0;
743 }
744 while(parinfo[k]!='[' && k<4095)k++;
745 if(k>=4095)goto txt_err;
746 sscanf(&parinfo[k],"[%d]",&wgi[i]);
747 while(parinfo[k]!='\n' && k<4095)k++;
748 if(k>=4095)goto txt_err;
749 }
750 if(max_floatpar < 0)
751 {
752 wgd=(double*)(&wgi[max_intpar]);
753 for(i=0; i<-max_floatpar; i++)
754 {
755 while(parinfo[k]==' ' ||
756 parinfo[k]== '\n' )k++;
757 j=0;
758 while(parinfo[k]== graphtype_partexts_float[type][i][j]&&k<4095)
759 {
760 k++;
761 j++;
762 }
763 if(graphtype_partexts_float[type][i][j] != 0)goto txt_err;
764 while(parinfo[k]!='[' && k<4095)k++;
765 if(k>=4095)goto txt_err;
766 sscanf(&parinfo[k],"[%lf]",&wgd[i]);
767 if(k>=4095)goto txt_err;
768 while(parinfo[k]!='\n' && k<4095)k++;
769 }
770 }
771 else
772 {
773 wgf=(float*)(&wgi[max_intpar]);
774 for(i=0; i<max_floatpar; i++)
775 {
776 while(parinfo[k]==' ' || parinfo[k]== '\n' )k++;
777 j=0;
778 while(parinfo[k]== graphtype_partexts_float[type][i][j])
779 {
780 k++;
781 j++;
782 }
783 if(graphtype_partexts_float[type][i][j] != 0)goto txt_err;
784 while(parinfo[k]!='[')k++;
785 sscanf(&parinfo[k],"[%f]",&wgf[i]);
786 while(parinfo[k]!='\n')k++;
787 }
788 }
789 free(parinfo);
790 return 1;
791 }
792
793
make_modepar_file(int type)794 void make_modepar_file(int type)
795 {
796 int i, max_intpar, max_floatpar;
797 int *wgi;
798 float *wgf;
799 double *wgd;
800 FILE *file;
801 file = open_parfile(type,"w");
802 if (file == NULL)
803 {
804 lirerr(1164);
805 return;
806 }
807 wgi=(int*)(graphtype_parptr[type]);
808 max_intpar = graphtype_max_intpar[type];
809 max_floatpar = graphtype_max_floatpar[type];
810 for(i=0; i<max_intpar; i++)
811 {
812 fprintf(file,"%s [%d]\n",graphtype_partexts_int[type][i],wgi[i]);
813 }
814 if(max_floatpar < 0)
815 {
816 wgd=(double*)(&wgi[max_intpar]);
817 for(i=0; i<-max_floatpar; i++)
818 {
819 fprintf(file,"%s [%.30f]\n",graphtype_partexts_float[type][i],wgd[i]);
820 }
821 }
822 else
823 {
824 wgf=(float*)(&wgi[max_intpar]);
825 for(i=0; i<max_floatpar; i++)
826 {
827 fprintf(file,"%s [%.15f]\n",graphtype_partexts_float[type][i],wgf[i]);
828 }
829 }
830 parfile_end(file);
831 }
832
833
select_namlin(char * s,FILE * file)834 void select_namlin(char *s,FILE *file)
835 {
836 char ch;
837 int i,k,num, line, col;
838 fpos_t fileptr[MAX_FILES];
839 clear_screen();
840 if(sel_line == -1)lir_text(10,0,"SELECT A NUMBER FROM THE LIST:");
841 num=0;
842 line=2;
843 col=0;
844 get_name:;
845 k=1;
846 sprintf(s,"%2d:",num);
847 if(fgetpos(file, &fileptr[num]))
848 {
849 lirerr(1118);
850 return;
851 }
852 i=2;
853 while(k==1 && s[i] != 10 && s[i] != ' ' && i<MAX_NAMLEN)
854 {
855 i++;
856 k=fread(&s[i],1,1,file);
857 if(s[i]==13)s[i]=10;
858 if(i==3 && s[i]==10)goto get_name;
859 }
860 ch=s[i];
861 s[i]=0;
862 if(i>3)
863 {
864 if(sel_line == -1)lir_text(col,line,s);
865 while(k==1 && ch != 10 )
866 {
867 k=fread(&ch,1,1,file);
868 if(ch==13)ch=10;
869 }
870 num++;
871 line++;
872 }
873 if(line>screen_last_line)
874 {
875 line=2;
876 col+=MAX_NAMLEN +5;
877 if( col+MAX_NAMLEN+5 > screen_last_col)goto listfull;
878 }
879 if(k == 1 && num < MAX_FILES)goto get_name;
880 listfull:;
881 if(sel_line == -1)sel_line=lir_get_integer(42, 0, 3, 0,num-1);
882 if(kill_all_flag) return;
883 if(fsetpos(file, &fileptr[sel_line]))lirerr(1119);
884 clear_screen();
885 }
886
887
get_parfile_name(char * s)888 void get_parfile_name(char *s)
889 {
890 int i, ptr, eq;
891 ptr=0;
892 while(s[ptr]!=0 && s[ptr]!=' ')
893 {
894 savefile_name[ptr]=s[ptr];
895 if(s[ptr]==10 || s[ptr]==13 )
896 {
897 savefile_parname[0]=0;
898 savefile_name[ptr]=0;
899 s[ptr]=0;
900 return;
901 }
902 ptr++;
903 if(ptr > SAVEFILE_MAX_CHARS)lirerr(1104);
904 }
905 savefile_name[ptr]=0;
906 s[ptr]=0;
907 ptr++;
908 while(s[ptr] == ' ')ptr++;
909 i=0;
910 eq=1;
911 while(s[ptr]!=0 &&
912 s[ptr]!=' ' &&
913 s[ptr] != 10 &&
914 s[ptr] != 13 &&
915 i<SAVEFILE_MAX_CHARS)
916 {
917 savefile_parname[i]=s[ptr];
918 if(s[i] != s[ptr])eq=0;
919 i++;
920 ptr++;
921 }
922 if(s[i] != ' ')eq=0;
923 if(i!=0 && eq==1)lirerr(1120);
924 if(i>= SAVEFILE_MAX_CHARS)lirerr(1115);
925 savefile_parname[i]=0;
926 }
927
init_wavread(int sel_file)928 int init_wavread(int sel_file)
929 {
930 char s[256];
931 FILE *file;
932 int i, k, n, chunk_size;
933 short int ishort, format_tag;
934 int errnr;
935 clear_screen();
936 file = fopen("adwav", "rb");
937 if (file == NULL)
938 {
939 file = fopen("adwav.txt", "rb");
940 if (file == NULL)
941 {
942 empty_error:;
943 help_message(313);
944 return 1;
945 }
946 }
947 if(sel_file != 0)
948 {
949 select_namlin(s,file);
950 if(kill_all_flag) return 1;
951 }
952 for(i=0; i<256; i++)s[i]=0;
953 k=fread(&s , 1, 256, file);
954 fclose(file);
955 if(k<2)goto empty_error;
956 i=0;
957 while( i<255 && (s[i] == ' ' || s[i] == 10 || s[i] == 13))i++;
958 get_parfile_name(&s[i]);
959 if(lir_errcod != 0)return 1;
960 for(n=i;n<256;n++)if(s[n]==10 || s[n]==13)s[n]=0;
961 save_rd_file = fopen(&s[i], "rb");
962 if (save_rd_file == NULL)
963 {
964 lir_text(5,4,"Can not open file");
965 lir_text(5,5,s);
966 rdfile_x:;
967 await_keyboard();
968 return 1;
969 }
970 diskread_time=0;
971 fg.passband_center=0;
972 // Read the WAV file header.
973 // First 4 bytes should be "RIFF"
974 k=fread(&i,sizeof(int),1,save_rd_file);
975 errnr=0;
976 if(k !=1)
977 {
978 headerr:;
979 lir_text(5,5,s);
980 sprintf(s,"Error in .wav file header [%d]",errnr);
981 lir_text(5,4,s);
982 goto rdfile_x;
983 }
984 if(i != 0x46464952)
985 {
986 errnr=1;
987 goto headerr;
988 }
989 // Read file size (we do not need it)
990 k=fread(&i,sizeof(int),1,save_rd_file);
991 if(k!=1)
992 {
993 errnr=2;
994 goto headerr;
995 }
996 // Now we should read "WAVE"
997 k=fread(&i,sizeof(int),1,save_rd_file);
998 errnr=2;
999 if(k !=1 || i != 0x45564157)goto headerr;
1000 // Now we should read "fmt "
1001 k=fread(&i,sizeof(int),1,save_rd_file);
1002 errnr=3;
1003 if(k !=1 || i != 0x20746d66)goto headerr;
1004 // read the size of the format chunk.
1005 k=fread(&chunk_size,sizeof(int),1,save_rd_file);
1006 errnr=4;
1007 if(k !=1 )goto headerr;
1008 // read the type of data (Format Tag). We only recognize PCM data!
1009 k=fread(&format_tag,sizeof(short int),1,save_rd_file);
1010 errnr=5;
1011 if(k !=1 || (format_tag != 1 && format_tag != 3))
1012 {
1013 lir_text(5,3,"Unknown wFormatTag.");
1014 goto headerr;
1015 }
1016 // Read no of channels
1017 k=fread(&ishort,sizeof(short int),1,save_rd_file);
1018 errnr=6;
1019 if(k !=1 || ishort < 1 || ishort > 2)goto headerr;
1020 ui.rx_ad_channels=ishort;
1021 // Read the sampling speed.
1022 k=fread(&ui.rx_ad_speed,sizeof(int),1,save_rd_file);
1023 errnr=7;
1024 if(k !=1 )goto headerr;
1025 // Read average bytes per second (do not care what it is)
1026 errnr=8;
1027 k=fread(&i,sizeof(int),1,save_rd_file);
1028 if(k !=1 )goto headerr;
1029 // Read block align to get 8 or 16 bit format.
1030 k=fread(&ishort,sizeof(short int),1,save_rd_file);
1031 errnr=9;
1032 if(k !=1 )goto headerr;
1033 ishort/=ui.rx_ad_channels;
1034 switch (ishort)
1035 {
1036 case 1:
1037 // byte int input
1038 errnr=10;
1039 if(format_tag != 1)goto headerr;
1040 ui.rx_input_mode=BYTE_INPUT;
1041 break;
1042
1043 case 2:
1044 // 16 bit int input
1045 errnr=11;
1046 if(format_tag != 1)goto headerr;
1047 ui.rx_input_mode=0;
1048 break;
1049
1050 case 3:
1051 // 24 bit int input
1052 errnr=12;
1053 if(format_tag != 1)goto headerr;
1054 ui.rx_input_mode=BYTE_INPUT+DWORD_INPUT;
1055 break;
1056
1057 case 4:
1058 errnr=13;
1059 if(format_tag == 1)
1060 {
1061 // 32 bit int input
1062 ui.rx_input_mode=QWORD_INPUT+DWORD_INPUT;
1063 break;
1064 }
1065 if(format_tag != 3)goto headerr;
1066 // 32 bit float input
1067 ui.rx_input_mode=FLOAT_INPUT+DWORD_INPUT;
1068 break;
1069
1070 default:
1071 goto headerr;
1072 }
1073 // Skip extra bytes if present.
1074 chunk_size-=14;
1075 skip_chunk:;
1076 errnr=11;
1077 while(chunk_size != 0)
1078 {
1079 k=fread(&i,1,1,save_rd_file);
1080 if(k !=1 )goto headerr;
1081 chunk_size--;
1082 }
1083 // Read chunks until we encounter the "data" string (=0x61746164).
1084 // Look for Perseus or SDR-14 headers.
1085 errnr=12;
1086 remember_proprietery_chunk[0]=REMEMBER_NOTHING;
1087 next_chunk:;
1088 k=fread(&i,sizeof(int),1,save_rd_file);
1089 if(k !=1 )goto headerr;
1090 errnr=13;
1091 // test for "rcvr"
1092 if(i==0x72766372)
1093 {
1094 if(remember_proprietery_chunk[0]!=REMEMBER_NOTHING)
1095 {
1096 lirerr(1522318);
1097 return 98;
1098 }
1099 remember_proprietery_chunk[0]=REMEMBER_PERSEUS;
1100 k=fread(&chunk_size,sizeof(int),1,save_rd_file);
1101 if(k !=1 )goto headerr;
1102 if(chunk_size > (int)sizeof(RCVR) )goto headerr;
1103 remember_proprietery_chunk[1]=chunk_size;
1104 k=fread(&perseus_hdr.nCenterFrequencyHz,1,chunk_size,save_rd_file);
1105 if(k != chunk_size)goto headerr;
1106 diskread_time=perseus_hdr.timeStart;
1107 fg.passband_center=0.000001*perseus_hdr.nCenterFrequencyHz;
1108 freq_from_file=TRUE;
1109 goto next_chunk;
1110 }
1111 errnr=14;
1112 // test for "auxi"
1113 if(i==0x69787561)
1114 {
1115 if(remember_proprietery_chunk[0]!=REMEMBER_NOTHING)
1116 {
1117 lirerr(1522319);
1118 return 99;
1119 }
1120 remember_proprietery_chunk[0]=REMEMBER_SDR14;
1121 k=fread(&chunk_size,sizeof(int),1,save_rd_file);
1122 if(chunk_size > (int)sizeof(AUXI)) goto headerr;
1123 remember_proprietery_chunk[1]=chunk_size;
1124 if(k !=1 )goto headerr;
1125 k=fread(&sdr14_hdr.StartTime,1,chunk_size,save_rd_file);
1126 if(k != chunk_size)goto headerr;
1127 diskread_time=sdr14_hdr.StartTime.wHour*3600.+
1128 sdr14_hdr.StartTime.wMinute*60.+
1129 sdr14_hdr.StartTime.wSecond;
1130 fg.passband_center=0.000001*sdr14_hdr.CenterFreq;
1131
1132 /*
1133 // for the file 160iq_50k.wav by EI6IZ öööö
1134 fg.passband_center=1.83223;
1135 */
1136
1137 freq_from_file=TRUE;
1138 goto next_chunk;
1139 }
1140 errnr=25;
1141 // Look for DATA
1142 if(i != 0x61746164)
1143 {
1144 // Unknown. Get the size and skip.
1145 k=fread(&chunk_size,sizeof(int),1,save_rd_file);
1146 if(k !=1 )goto headerr;
1147 goto skip_chunk;
1148 }
1149 // Read how much data we have ( do not care)
1150 k=fread(&i,sizeof(int),1,save_rd_file);
1151 if(k !=1 )goto headerr;
1152 diskread_flag=2;
1153 save_init_flag=0;
1154 fg.passband_direction=0;
1155 fft1_direction=fg.passband_direction;
1156 return 0;
1157 }
1158
parfile_end(FILE * file)1159 void parfile_end(FILE *file)
1160 {
1161 fprintf(file,"\nChange only between brackets.");
1162 fprintf(file,"\nIf file has errors, Linrad will ignore file and use defaults");
1163 fprintf(file,"\nor prompt for a complete set of new parameters\n");
1164 fprintf(file,"\n%s",PROGRAM_NAME);
1165 fclose(file);
1166 }
1167
1168
init_diskread(int sel_file)1169 int init_diskread(int sel_file)
1170 {
1171 char s[256];
1172 FILE *file;
1173 int i, n, kk;
1174 if(sel_file != -1)
1175 {
1176 sel_parm=sel_file;
1177 sel_line=-1;
1178 }
1179 kk=sel_parm;
1180 if( wav_read_flag != 0)
1181 {
1182 i=init_wavread(kk);
1183 return i;
1184 }
1185 clear_screen();
1186 file = fopen("adfile", "rb");
1187 if (file == NULL)
1188 {
1189 file = fopen("adfile.txt", "rb");
1190 if (file == NULL)
1191 {
1192 emptyerror:;
1193 help_message(314);
1194 return 1;
1195 }
1196 }
1197 if(kk != 0)
1198 {
1199 select_namlin(s,file);
1200 if(kill_all_flag) return 1;
1201 }
1202 for(i=0; i<256; i++)s[i]=0;
1203 i=fread(&s , 1, 256, file);
1204 fclose(file);
1205 if(i < 2)goto emptyerror;
1206 i=0;
1207 while( i<255 && (s[i] == ' ' || s[i] == 10 || s[i] == 13))i++;
1208 get_parfile_name(&s[i]);
1209 if(lir_errcod != 0)return 1;
1210 for(n=i;n<256;n++)if(s[n]==10 || s[n]==13)s[n]=0;
1211 return open_savefile(&s[i]);
1212 }
1213
complete_filename(int i,char * s,char * fxt,char * dir,char * fnm)1214 void complete_filename(int i, char *s, char *fxt, char *dir, char *fnm)
1215 {
1216 #if(OSNUM == OSNUM_WINDOWS)
1217 int j, k;
1218 j=0;
1219 k=0;
1220 #endif
1221 if( i <= 4 || (i > 4 && strcmp(&s[i-4],fxt) !=0))
1222 {
1223 strcpy(&s[i],fxt);
1224 }
1225 #if(OSNUM == OSNUM_LINUX)
1226 if(s[0] != '/' && s[0]!= '.')
1227 #endif
1228 #if(OSNUM == OSNUM_WINDOWS)
1229 while(s[k]!=0)
1230 {
1231 if(s[k]==':')j=1;
1232 k++;
1233 }
1234 if(j==0)
1235 #endif
1236 {
1237 sprintf(fnm,"%s%s",dir,s);
1238 }
1239 else
1240 {
1241 strcpy(fnm,s);
1242 }
1243 }
1244
update_indicator(unsigned char color)1245 void update_indicator(unsigned char color)
1246 {
1247 char s[3];
1248 int i;
1249 s[2]=0;
1250 if(diskwrite_flag == TRUE)
1251 {
1252 s[0]='S';
1253 }
1254 else
1255 {
1256 s[0]=' ';
1257 }
1258 if(wav_write_flag == 1)
1259 {
1260 s[1]='W';
1261 }
1262 else
1263 {
1264 s[1]=' ';
1265 }
1266 settextcolor(color);
1267 i=wg.xright-2*text_width-2;
1268 if(i<2)i=2;
1269 lir_pixwrite(i,wg.yborder+2,s);
1270 if(numinput_flag != 0)
1271 {
1272 if(color == 12)settextcolor(15);
1273 lir_pixwrite(numinput_xpix,numinput_ypix,numinput_txt);
1274 }
1275 settextcolor(7);
1276 }
1277
disksave_start(void)1278 void disksave_start(void)
1279 {
1280 // Open or close save_rd_file or save_wr_file.
1281 // If mode=TRUE, we operate on save_wr_file.
1282 FILE *fc_file, *iq_file;
1283 int i, k;
1284 int wrbuf[10];
1285 double dt1;
1286 char raw_filename[160];
1287 char s[160];
1288 char *disksave_screencopy;
1289 if(diskwrite_flag == 0)
1290 {
1291 pause_thread(THREAD_SCREEN);
1292 disksave_screencopy=malloc(DISKSAVE_SCREEN_SIZE);
1293 if(disksave_screencopy == NULL)
1294 {
1295 lirerr(1047);
1296 return;
1297 }
1298 lir_getbox(0,0,DISKSAVE_X_SIZE,DISKSAVE_Y_SIZE,(MEMREF_T*)disksave_screencopy);
1299 lir_fillbox(0,0,DISKSAVE_X_SIZE,DISKSAVE_Y_SIZE,10);
1300 lir_text(0,0,"Enter file name for raw data.");
1301 lir_text(0,1,"ENTER to skip.");
1302 lir_text(0,2,"=>");
1303 i=lir_get_filename(2,2,s);
1304 if(kill_all_flag) return;
1305 if(i==0)
1306 {
1307 diskwrite_flag=FALSE;
1308 }
1309 else
1310 {
1311 complete_filename(i, s, ".raw", RAWDIR, raw_filename);
1312 save_wr_file = fopen( raw_filename, "wb");
1313 if(save_wr_file == NULL)
1314 {
1315 errx:;
1316 could_not_create(raw_filename,3);
1317 if(kill_all_flag) return;
1318 diskwrite_flag=FALSE;
1319 }
1320 else
1321 {
1322 // Write REMEMBER_UNKNOWN as a flag telling what version number of
1323 // Linrad raw data file we are writing.
1324 if(diskread_flag < 2)
1325 {
1326 remember_proprietery_chunk[0]=REMEMBER_UNKNOWN;
1327 }
1328 i=fwrite(&remember_proprietery_chunk[0],sizeof(int),1,save_wr_file);
1329 if(i != 1)
1330 {
1331 wrerr:;
1332 fclose(save_wr_file);
1333 goto errx;
1334 }
1335 switch(remember_proprietery_chunk[0])
1336 {
1337 case REMEMBER_NOTHING:
1338 case REMEMBER_UNKNOWN:
1339 break;
1340
1341
1342 case REMEMBER_PERSEUS:
1343 i=fwrite(&remember_proprietery_chunk[1],sizeof(int),1,save_wr_file);
1344 if(i !=1 )goto wrerr;
1345 i=fwrite(&perseus_hdr.nCenterFrequencyHz,1,
1346 remember_proprietery_chunk[1],save_wr_file);
1347 if(i != remember_proprietery_chunk[1] )goto wrerr;
1348 break;
1349
1350 case REMEMBER_SDR14:
1351 i=fwrite(&remember_proprietery_chunk[1],sizeof(int),1,save_wr_file);
1352 if(i !=1 )goto wrerr;
1353 i=fwrite(&sdr14_hdr.StartTime,1,
1354 remember_proprietery_chunk[1],save_wr_file);
1355 if(i != remember_proprietery_chunk[1] )goto wrerr;
1356 break;
1357
1358 default:
1359 lirerr(3850232);
1360 goto wrerr;
1361 }
1362 if(diskread_flag < 2)
1363 {
1364 i=lir_get_epoch_seconds();
1365 dt1=i;
1366 i%=24*3600;
1367 }
1368 else
1369 {
1370 i=diskread_time+diskread_block_counter*
1371 snd[RXAD].block_frames/ui.rx_ad_speed;
1372 i%=24*3600;
1373 dt1=i;
1374 }
1375 i=fwrite(&dt1,sizeof(double),1,save_wr_file);
1376 if(i != 1)goto wrerr;
1377 i=fwrite(&fg.passband_center,sizeof(double),1,save_wr_file);
1378 if(i != 1)goto wrerr;
1379 i=fwrite(&fg.passband_direction,sizeof(int),1,save_wr_file);
1380 if(i != 1)goto wrerr;
1381 // Write mode info so we know how to process data when reading
1382 k=ui.rx_input_mode&(TWO_CHANNELS+DWORD_INPUT+IQ_DATA+DIGITAL_IQ);
1383 i=fwrite(&k,sizeof(int),1,save_wr_file);
1384 if(i != 1)goto wrerr;
1385 i=fwrite(&ui.rx_rf_channels,sizeof(int),1,save_wr_file);
1386 if(i != 1)goto wrerr;
1387 i=fwrite(&ui.rx_ad_channels,sizeof(int),1,save_wr_file);
1388 if(i != 1)goto wrerr;
1389 i=fwrite(&ui.rx_ad_speed,sizeof(int),1,save_wr_file);
1390 if(i != 1)goto wrerr;
1391 save_init_flag=0;
1392 iq_file=NULL;
1393 fc_file=NULL;
1394 if( (fft1_calibrate_flag&CALAMP) == CALAMP)
1395 {
1396 make_filfunc_filename(s);
1397 fc_file = fopen(s, "rb");
1398 save_init_flag=1;
1399 }
1400 if( (ui.rx_input_mode&IQ_DATA) != 0 &&
1401 (fft1_calibrate_flag&CALIQ) == CALIQ)
1402 {
1403 make_iqcorr_filename(s);
1404 iq_file = fopen(s, "rb");
1405 save_init_flag+=2;
1406 }
1407 i=fwrite(&save_init_flag,1,1,save_wr_file);
1408 if(i != 1)goto wrerr;
1409
1410 if( (save_init_flag & 1) == 1)
1411 {
1412 if(fc_file != NULL)
1413 {
1414 rd1:;
1415 i=fread(&s,1,1,fc_file);
1416 if(i != 0)
1417 {
1418 i=fwrite(&s,1,1,save_wr_file);
1419 if(i != 1)goto wrerr;
1420 goto rd1;
1421 }
1422 fclose(fc_file);
1423 fc_file=NULL;
1424 }
1425 else
1426 {
1427 wrbuf[0]=fft1_n;
1428 wrbuf[1]=fft1_size;
1429 wrbuf[2]=rx_mode;
1430 wrbuf[3]=ui.rx_input_mode;
1431 wrbuf[4]=genparm[FIRST_FFT_VERNR];
1432 wrbuf[5]=ui.rx_ad_speed;
1433 wrbuf[6]=ui.rx_rf_channels;
1434 wrbuf[7]=fft1_size;
1435 for(i=8; i<10; i++)wrbuf[i]=0;
1436 i=fwrite(wrbuf, sizeof(int),10,save_wr_file);
1437 if(i != 10)goto wrerr;
1438 i=fwrite(fft1_filtercorr, twice_rxchan*sizeof(float),
1439 fft1_size, save_wr_file);
1440 if(i != fft1_size)goto wrerr;
1441 i=fwrite(fft1_desired,sizeof(float),fft1_size,save_wr_file);
1442 if(i != fft1_size)goto wrerr;
1443 i=fwrite(wrbuf, sizeof(int),10,save_wr_file);
1444 if(i!=10)goto wrerr;
1445 }
1446 }
1447 if( (save_init_flag & 2) == 2)
1448 {
1449 if(iq_file != NULL)
1450 {
1451 rd2:;
1452 i=fread(&s,1,1,iq_file);
1453 if(i != 0)
1454 {
1455 i=fwrite(&s,1,1,save_wr_file);
1456 if(i != 1)goto wrerr;
1457 goto rd2;
1458 }
1459 fclose(iq_file);
1460 iq_file=NULL;
1461 }
1462 else
1463 {
1464 wrbuf[0]=fft1_size;
1465 wrbuf[1]=ui.rx_input_mode&IQ_DATA;
1466 wrbuf[2]=ui.rx_ad_speed;
1467 wrbuf[3]=ui.rx_rf_channels;
1468 wrbuf[4]=FOLDCORR_VERNR;
1469 for(i=5; i<10; i++)wrbuf[i]=0;
1470 i=fwrite(wrbuf, sizeof(int),10,save_wr_file);
1471 if(i!=10)goto wrerr;
1472 i=fwrite(fft1_foldcorr, twice_rxchan*sizeof(float),
1473 4*fft1_size, save_wr_file);
1474 // We write four times too much data for foldcorr. ööööööööö
1475 // make a new FOLDCORR_VERNR and write future files in the öööö
1476 // proper size. öööö
1477 if(i != 4*fft1_size)goto wrerr;
1478 i=fwrite(wrbuf, sizeof(int),10,save_wr_file);
1479 if(i!=10)goto wrerr;
1480 }
1481 }
1482 diskwrite_flag=TRUE;
1483 // Create a separate thread for disk writes. They can take very
1484 // long time particularly under Windows.
1485 lir_init_event(EVENT_WRITE_RAW_FILE);
1486 linrad_thread_create(THREAD_WRITE_RAW_FILE);
1487
1488 }
1489 }
1490 lir_putbox(0,0,DISKSAVE_X_SIZE,DISKSAVE_Y_SIZE,(MEMREF_T*)disksave_screencopy);
1491 free(disksave_screencopy);
1492 resume_thread(THREAD_SCREEN);
1493 }
1494 //update_indicator();
1495 }
1496
disksave_stop(void)1497 void disksave_stop(void)
1498 {
1499 // Open or close save_rd_file or save_wr_file.
1500 // If mode=TRUE, we operate on save_wr_file.
1501 if(diskwrite_flag != 0)
1502 {
1503 diskwrite_flag=0;
1504 linrad_thread_stop_and_join(THREAD_WRITE_RAW_FILE);
1505 lir_close_event(EVENT_WRITE_RAW_FILE);
1506 }
1507 //update_indicator();
1508 }
1509
wavsave_start_stop(int line)1510 void wavsave_start_stop(int line)
1511 {
1512 int i;
1513 char s[160],wav_filename[160];
1514 char *wav_write_screencopy;
1515 if( wav_write_flag == 0)
1516 {
1517 pause_thread(THREAD_SCREEN);
1518 wav_write_screencopy=malloc(DISKSAVE_SCREEN_SIZE);
1519 if(wav_write_screencopy == NULL)
1520 {
1521 lirerr(1031);
1522 return;
1523 }
1524 lir_getbox(0,line*text_height,DISKSAVE_X_SIZE,
1525 DISKSAVE_Y_SIZE,(MEMREF_T*)wav_write_screencopy);
1526 lir_fillbox(0,line*text_height,DISKSAVE_X_SIZE,DISKSAVE_Y_SIZE,10);
1527 lir_text(0,line,"Enter name for audio output file");
1528 lir_text(0,line+1,"ENTER to skip.");
1529 lir_text(0,line+2,"=>");
1530 i=lir_get_filename(2,line+2,s);
1531 if(kill_all_flag) return;
1532 if(i != 0)
1533 {
1534 complete_filename(i, s, ".wav", WAVDIR, wav_filename);
1535 wav_file = fopen( wav_filename, "wb");
1536 if(wav_file == NULL)
1537 {
1538 could_not_create(wav_filename, line+2);
1539 wav_write_flag = -1;
1540 }
1541 else
1542 {
1543 // Write the .wav header, but make the file size gigantic
1544 // We will write the correct size when closing, but if
1545 // system crashes we can fix the header and recover data.
1546 // Speed, channels and bits will be ok. Size will indicate loss of data.
1547 write_wav_header(TRUE);
1548 fflush(wav_file);
1549 lir_sync();
1550 wav_write_flag=1;
1551 }
1552 }
1553 lir_putbox(0,line*text_height,DISKSAVE_X_SIZE,
1554 DISKSAVE_Y_SIZE,(MEMREF_T*)wav_write_screencopy);
1555 free(wav_write_screencopy);
1556 resume_thread(THREAD_SCREEN);
1557 }
1558 else
1559 {
1560 wav_write_flag = 0;
1561 lir_sleep(200000);
1562 write_wav_header(FALSE);
1563 fclose(wav_file);
1564 lir_sync();
1565 }
1566 lir_refresh_screen();
1567 //update_indicator();
1568 }
1569
write_wav_header(int begin)1570 void write_wav_header(int begin)
1571 {
1572 int i;
1573 // Write the header for a .wav file using the current output
1574 // settings.
1575 // First point to start of file.
1576 off_t filesize;
1577 if(begin == TRUE)
1578 {
1579 if(fgetpos(wav_file, &wav_wrpos))
1580 {
1581 lirerr(1114);
1582 return;
1583 }
1584 filesize=0x7fffffff;
1585 }
1586 else
1587 {
1588 fseek(wav_file, 0, SEEK_END);
1589 #if OSNUM == OSNUM_LINUX
1590 filesize=ftello(wav_file);
1591 #endif
1592 #if OSNUM == OSNUM_WINDOWS
1593 filesize=ftell(wav_file);
1594 #endif
1595 if(fsetpos(wav_file, &wav_wrpos) != 0)
1596 {
1597 lirerr(1111);
1598 return;
1599 }
1600 }
1601 // First 4 bytes should be "RIFF"
1602 if(fwrite("RIFF",sizeof(int),1,wav_file)!= 1)
1603 {
1604 headerr:;
1605 lirerr(1112);
1606 return;
1607 }
1608 // Now file size in bytes -8
1609 // The format chunk uses 16 bytes.
1610 i=filesize-8;
1611 if(fwrite(&i,sizeof(int),1,wav_file)!= 1)goto headerr;
1612 // The next code word pair is "WAVEfmt "
1613 if(fwrite("WAVEfmt ",sizeof(int),2,wav_file)!= 2)goto headerr;
1614 // Write the size of the format chunk = 16
1615 // ******************************************************
1616 // pos 16-19
1617 i=16;
1618 if(fwrite(&i,sizeof(int),1,wav_file)!= 1)goto headerr;
1619 // ******************************************************
1620 // pos 20-21
1621 // Write the type of data (Format Tag = 1 for PCM data)
1622 i=1;
1623 if(fwrite(&i,sizeof(short int),1,wav_file)!=1)goto headerr;
1624 // ******************************************************
1625 // pos 22-23
1626 // Write no of channels
1627 if(fwrite(&rx_daout_channels,sizeof(short int),1,wav_file)!=1)goto headerr;
1628 // ******************************************************
1629 // pos 24-27
1630 // Write the output speed.
1631 if(fwrite(&genparm[DA_OUTPUT_SPEED],sizeof(int),1,wav_file)!=1)goto headerr;
1632 // ******************************************************
1633 // pos 28-31
1634 // Write average bytes per second.
1635 i=genparm[DA_OUTPUT_SPEED]*rx_daout_bytes*rx_daout_channels;
1636 if(fwrite(&i,sizeof(int),1,wav_file)!=1)goto headerr;
1637 // ******************************************************
1638 // pos 32-33
1639 // Write block align.
1640 i=rx_daout_channels*rx_daout_bytes;
1641 if(fwrite(&i,sizeof(short int),1,wav_file)!=1)goto headerr;
1642 // ******************************************************
1643 // pos 34-35
1644 // Write bits per sample
1645 i=8*rx_daout_bytes;
1646 if(fwrite(&i,sizeof(short int),1,wav_file)!=1)goto headerr;
1647 // ******************************************************
1648 // Write the proprietary chunk for Perseus, SDR-14 etc.
1649 if(diskread_flag != 0)
1650 {
1651 switch(remember_proprietery_chunk[0])
1652 {
1653 case REMEMBER_NOTHING:
1654 case REMEMBER_UNKNOWN:
1655 break;
1656
1657 case REMEMBER_PERSEUS:
1658 if(fwrite("rcvr",sizeof(int),1,wav_file)!=1)goto headerr;
1659 if(fwrite(&remember_proprietery_chunk[1],sizeof(int),1,wav_file)!=1)
1660 goto headerr;
1661 i=fwrite(&perseus_hdr.nCenterFrequencyHz,1,
1662 remember_proprietery_chunk[1],wav_file);
1663 if(i != remember_proprietery_chunk[1]) goto headerr;
1664 break;
1665
1666 case REMEMBER_SDR14:
1667 if(fwrite("auxi",sizeof(int),1,wav_file)!=1)goto headerr;
1668 if(fwrite(&remember_proprietery_chunk[1],sizeof(int),1,wav_file)!=1)
1669 goto headerr;
1670 i=fwrite(&sdr14_hdr.StartTime,1, remember_proprietery_chunk[1], wav_file);
1671 if(i != remember_proprietery_chunk[1]) goto headerr;
1672 break;
1673
1674 default:
1675 lirerr(5699231);
1676 return;
1677 }
1678 }
1679 // Now write the code word "data"
1680 if(fwrite("data",sizeof(int),1,wav_file)!=1)goto headerr;
1681 // And finally the size of the data block
1682 i= filesize-44;
1683 if(fwrite(&i,sizeof(int),1,wav_file)!=1)goto headerr;
1684 }
1685
init_memalloc(MEM_INF * mm,MEMREF_T max)1686 void init_memalloc(MEM_INF *mm, MEMREF_T max)
1687 {
1688 memalloc_no=0;
1689 memalloc_max=max;
1690 memalloc_mem=mm;
1691 }
1692
mem(int num,void * pointer,unsigned int size,int scratch_size)1693 void mem(int num, void *pointer, unsigned int size, int scratch_size)
1694 {
1695 if(lir_errcod !=0)return;
1696 // Skip if outside array. Error code will come on return from memalloc.
1697 if(memalloc_no<0 || memalloc_no>=memalloc_max)goto skip;
1698 memalloc_mem[memalloc_no].pointer=pointer;
1699 memalloc_mem[memalloc_no].size=(size+15)&((MEMREF_T)-16);
1700 memalloc_mem[memalloc_no].scratch_size=((scratch_size+15)&((MEMREF_T)-16));
1701 memalloc_mem[memalloc_no].num=num;
1702 skip:;
1703 memalloc_no++;
1704 }
1705
1706
1707 // Declare this function MEMREF_T if really big arrays become needed.
memalloc(MEMREF_T ** hh,char * s)1708 MEMREF_T memalloc( MEMREF_T **hh, char *s)
1709 {
1710 int i, j;
1711 MEMREF_T totbytes;
1712 MEMREF_T k, mask;
1713 char *x;
1714 MEMREF_T *ptr;
1715 MEMREF_T *handle;
1716 double dt;
1717 handle=(MEMREF_T*)hh;
1718 if(memalloc_no<0 || memalloc_no >= memalloc_max)
1719 {
1720 DEB"memalloc_no=%d %s",memalloc_no,s);
1721 lirerr(1136);
1722 }
1723 if(lir_errcod != 0)return 0;
1724 memalloc_mem[memalloc_no].pointer=s;
1725 memalloc_mem[memalloc_no].size=-1;
1726 totbytes=16+DEBMEM;
1727 dt=totbytes;
1728 for(i=0; i<memalloc_no; i++)
1729 {
1730 totbytes+=memalloc_mem[i].size+memalloc_mem[i].scratch_size+DEBMEM;
1731 dt+=memalloc_mem[i].size+memalloc_mem[i].scratch_size+DEBMEM;
1732 }
1733 if(fabs(dt-totbytes) > 100)return 0;
1734 DEB"%s: %3.1f Megabytes(%d arrays)\n",s,
1735 totbytes*0.000001,memalloc_no);
1736 handle[0]=(MEMREF_T)(malloc(totbytes+16));
1737 if(handle[0] == 0)return 0;
1738 mask=(MEMREF_T)-16;
1739 k=((MEMREF_T)(handle[0])+15)&mask;
1740 for(i=0; i<memalloc_no; i++)
1741 {
1742 x=(char*)(k);
1743 k+=DEBMEM;
1744 for (j=0; j<DEBMEM; j++)x[j]=j&0xff;
1745 k+=memalloc_mem[i].scratch_size;
1746 ptr=memalloc_mem[i].pointer;
1747 ptr[0]=k;
1748 k+=memalloc_mem[i].size;
1749 }
1750 x=(char*)(k);
1751 k+=DEBMEM;
1752 for (j=0; j<DEBMEM; j++)x[j]=j&0xff;
1753 return totbytes;
1754 }
1755
memcheck(int callno,MEM_INF * mm,MEMREF_T ** hh)1756 void memcheck(int callno, MEM_INF *mm, MEMREF_T **hh)
1757 {
1758 char s[80];
1759 int fl, i, j, errflag;
1760 unsigned char *x;
1761 MEMREF_T k, mask;
1762 MEMREF_T *handle;
1763 handle=(MEMREF_T*)hh;
1764 mask=(MEMREF_T)-16;
1765 k=(handle[0]+15)&mask;
1766 i=0;
1767 errflag=0;
1768 fl=mm[i].size;
1769 while(fl != -1)
1770 {
1771 x=(unsigned char*)(k);
1772 k+=DEBMEM;
1773 for (j=0; j<DEBMEM; j++)
1774 {
1775 if( x[j] != (j&0xff) )
1776 {
1777 errflag=1;
1778 DEB"\nMEMORY ERROR mm=%d[%d] data is%d(%d) Call no %d",
1779 mm[i].num,j,x[j],j&0xff,callno);
1780 printf("\nMEMORY ERROR mm=%d[%d] data is%d (%d) Call no %d",
1781 mm[i].num,j,x[j],j&0xff,callno);
1782 }
1783 }
1784 fl=mm[i].size;
1785 k+=mm[i].size;
1786 k+=mm[i].scratch_size;
1787 i++;
1788 }
1789 if(errflag != 0)
1790 {
1791 if(fl!=-1)
1792 {
1793 sprintf(s,"\nUnknown");
1794 }
1795 else
1796 {
1797 sprintf(s,"%s",(char*)mm[i-1].pointer);
1798 }
1799 DEB"\nError in %s\n",s);
1800 printf("\nError in %s\n",s);
1801 lirerr(1240);
1802 }
1803 }
1804
show_name_and_size(void)1805 void show_name_and_size(void)
1806 {
1807 int i,imax;
1808 char s[120];
1809 float fftx_,base_,afc_,hires_,fft3_;
1810 if(wg.yborder-3.5*text_height<wg.ytop)return;
1811 fftx_=0.000001*fftx_totmem;
1812 base_=0.000001*baseband_totmem;
1813 afc_= 0.000001*afc_totmem;
1814 fft3_=0.000001*fft3_totmem;
1815 hires_=0.000001*hires_totmem;
1816 sprintf(s,"%s %.1f Mbytes. fft1,fft2=%.1f hires %.1f \
1817 fft3=%.1f afc=%.1f bas=%.1f)",
1818 PROGRAM_NAME,(fftx_+base_+afc_+hires_+fft3_),
1819 fftx_,hires_,fft3_,afc_,base_);
1820 imax=(wg.xright-wg.xleft)/text_width-6;
1821 if(imax > 120)imax=120;
1822 i=0;
1823 while(s[i]!=0 && i<imax)i++;
1824 s[i]=0;
1825 settextcolor(15);
1826 lir_pixwrite(wg.xleft+4*text_width,wg.yborder-2*text_height,s);
1827 settextcolor(7);
1828 }
1829
welcome_msg(void)1830 void welcome_msg(void)
1831 {
1832 printf("\nUse W to create a new %s file after setup.\n",userint_filename);
1833 printf("\nNote that the following keys have a special meaning in Linrad:");
1834 printf("\nESC = terminate Linrad");
1835 printf("\n X = Skip whatever process you are in and get one level");
1836 printf("\n upwards in Linrads menu tree.(Not everywhere!!)");
1837 printf("\n G = Make a .gif file with a screen dump of your current screen.");
1838 printf("\n\n\n ----------- GLOBAL PARAMETERS SETUP -------------");
1839 printf("\n (You might want to edit %s instead)", userint_filename);
1840 printf("\nPress N for NEWCOMER mode.");
1841 printf("\nPress S for normal mode.");
1842 printf("\nPress E for expert mode.");
1843 printf("\nThen press enter\n\n=>");
1844 }
1845
read_sdrpar(char * file_name,int max_parm,char ** parm_text,int * par)1846 int read_sdrpar(char *file_name, int max_parm, char **parm_text, int *par)
1847 {
1848 char *testbuff;
1849 FILE *file;
1850 int i, j, k;
1851 file=fopen(file_name,"r");
1852 // Read control parameters from par_xxxxxx
1853 if(file == NULL)return -1;
1854 testbuff = malloc(4096);
1855 if(testbuff == NULL)
1856 {
1857 fclose(file);
1858 lirerr(1003);
1859 return -99;
1860 }
1861 for(i=0; i<4096; i++)testbuff[i]=0;
1862 i=fread(testbuff,1,4095,file);
1863 fclose(file);
1864 if(i >= 4095)
1865 {
1866 free(testbuff);
1867 return -2;
1868 }
1869 k=0;
1870 for(i=0; i<max_parm; i++)
1871 {
1872 while( (testbuff[k]==' ' || testbuff[k]== '\n' ) && k<4095)k++;
1873 j=0;
1874 while(testbuff[k]== parm_text[i][j] && k<4095)
1875 {
1876 k++;
1877 j++;
1878 }
1879 if(parm_text[i][j] != 0)goto lineerr;
1880 while(testbuff[k]!='[' && k<4095)k++;
1881 if(k>=4095)goto lineerr;
1882 sscanf(&testbuff[k],"[%d]",&par[i]);
1883 while(testbuff[k]!='\n' && k<4095)k++;
1884 if(k>=4095)goto lineerr;
1885 }
1886 free(testbuff);
1887 return 0;
1888 lineerr:;
1889 free(testbuff);
1890 return i+1;
1891 }
1892
show_specific_dev(char * name_string,int * line)1893 void show_specific_dev(char *name_string, int *line)
1894 {
1895 char s[80];
1896 sprintf(s,"SDR DEVICE = %s",name_string);
1897 lir_text(24,line[0],s);
1898 line[0]++;
1899 SNDLOG"\n%s\n",s);
1900 }
1901
netin_txt(void)1902 char *netin_txt(void)
1903 {
1904 char *netin;
1905 switch (ui.network_flag & NET_RX_INPUT)
1906 {
1907 case NET_RXIN_RAW16:
1908 netin="RAW16";
1909 break;
1910
1911 case NET_RXIN_RAW18:
1912 netin="RAW18";
1913 break;
1914
1915 case NET_RXIN_RAW24:
1916 netin="RAW24";
1917 break;
1918
1919 case NET_RXIN_FFT1:
1920 netin="FFT1";
1921 break;
1922
1923 case NET_RXIN_BASEB:
1924 netin="BASEB16";
1925 break;
1926
1927 case NET_RXIN_BASEBRAW:
1928 netin="BASEB24";
1929 break;
1930
1931 case NET_RXIN_TIMF2:
1932 netin="TIMF2";
1933 break;
1934
1935 default:
1936 netin="ERROR";
1937 break;
1938 }
1939 return netin;
1940 }
1941
show_rx_input_settings(int * line)1942 int show_rx_input_settings(int *line)
1943 {
1944 char *netw="NETWORK";
1945 char s[80],ss[80];
1946 char *specific_dev;
1947 int retcode;
1948 lir_text(2,line[0],"Linrad RX input from:");
1949 SNDLOG"\nSETUP FOR RX INPUT IS NOW:\n");
1950 settextcolor(10);
1951 //check for SDR devices
1952 specific_dev=NULL;
1953 retcode=0;
1954 switch (ui.rx_addev_no)
1955 {
1956 case SDR14_DEVICE_CODE:
1957 show_specific_dev(sdr14_name_string, line);
1958 retcode=display_sdr14_parm_info(line);
1959 specific_dev=sdr14_name_string;
1960 break;
1961
1962 case SDRIQ_DEVICE_CODE:
1963 show_specific_dev(sdriq_name_string, line);
1964 retcode=display_sdr14_parm_info(line);
1965 specific_dev=sdriq_name_string;
1966 break;
1967
1968 case SDRIP_DEVICE_CODE:
1969 show_specific_dev(sdrip_name_string, line);
1970 retcode=display_sdrip_parm_info(line);
1971 specific_dev=sdrip_name_string;
1972 break;
1973
1974 case PERSEUS_DEVICE_CODE:
1975 show_specific_dev(perseus_name_string, line);
1976 retcode=display_perseus_parm_info(line);
1977 specific_dev=perseus_name_string;
1978 break;
1979
1980 case EXCALIBUR_DEVICE_CODE:
1981 show_specific_dev(excalibur_name_string, line);
1982 retcode=display_excalibur_parm_info(line);
1983 specific_dev=excalibur_name_string;
1984 break;
1985
1986 case RTL2832_DEVICE_CODE:
1987 show_specific_dev(rtl2832_name_string, line);
1988 retcode=display_rtl2832_parm_info(line);
1989 specific_dev=rtl2832_name_string;
1990 break;
1991
1992 case MIRISDR_DEVICE_CODE:
1993 show_specific_dev(mirics_name_string, line);
1994 retcode=display_mirics_parm_info(line);
1995 specific_dev=mirics_name_string;
1996 break;
1997
1998 case BLADERF_DEVICE_CODE:
1999 show_specific_dev(bladerf_name_string, line);
2000 retcode=display_bladerf_parm_info(line);
2001 specific_dev=bladerf_name_string;
2002 break;
2003
2004 case PCIE9842_DEVICE_CODE:
2005 show_specific_dev(pcie9842_name_string, line);
2006 retcode=display_pcie9842_parm_info(line);
2007 specific_dev=pcie9842_name_string;
2008 break;
2009
2010 case OPENHPSDR_DEVICE_CODE:
2011 show_specific_dev(openhpsdr_name_string, line);
2012 retcode=display_openhpsdr_parm_info(line);
2013 specific_dev=openhpsdr_name_string;
2014 break;
2015
2016 case NETAFEDRI_DEVICE_CODE:
2017 show_specific_dev(netafedri_name_string, line);
2018 retcode=display_netafedri_parm_info(line);
2019 specific_dev=netafedri_name_string;
2020 break;
2021
2022 case DISABLED_DEVICE_CODE:
2023 sprintf(s,"DISABLED (Input from hard disk only)");
2024 lir_text(24,line[0],s);
2025 line[0]++;
2026 SNDLOG"\n%s\n",s);
2027 return TRUE;
2028
2029 case NETWORK_DEVICE_CODE:
2030 lir_text(24,line[0],netw);
2031 line[0]++;
2032 SNDLOG"\n%s",netw);
2033 settextcolor(7);
2034 sprintf(ss,"receive format = %s",netin_txt());
2035 lir_text(24,line[0],ss);
2036 SNDLOG"\n%s\n",ss);
2037 return TRUE;
2038 break;
2039
2040 default:
2041 if(ui.rx_addev_no >= SPECIFIC_DEVICE_CODES)
2042 {
2043 specific_dev="UNKNOWN SDR DEVICE";
2044 retcode=-99;
2045 settextcolor(12);
2046 }
2047 break;
2048 }
2049 if(kill_all_flag)return TRUE;
2050 if(retcode != 0)
2051 {
2052 sprintf(s,"%s defined for Rx input (in %s)",
2053 specific_dev, userint_filename);
2054 lir_text(24,line[0],s);
2055 line[0]++;
2056 SNDLOG"\n%s\n",s);
2057 s[0]=0;
2058 if(retcode == -1)
2059 {
2060 sprintf(s,"parameter file not found.");
2061 }
2062 else
2063 {
2064 if(retcode == -2)
2065 {
2066 sprintf(s,"parameter file error: file too big.");
2067 }
2068 else
2069 {
2070 if(retcode > 0)sprintf(s,"parameter file error on line %d",retcode);
2071 }
2072 }
2073 if(s[0] != 0)
2074 {
2075 settextcolor(12);
2076 lir_text(24,line[0],s);
2077 line[0]++;
2078 SNDLOG"\n%s\n",s);
2079 }
2080 settextcolor(7);
2081 }
2082 if(specific_dev != NULL)return TRUE;
2083 return FALSE;
2084 }
2085
display_rx_input_source(char * retmsg)2086 void display_rx_input_source(char *retmsg)
2087 {
2088 char *sdrnam;
2089 char ss[80], st[80];
2090 sdrnam=NULL;
2091 ss[0]=0;
2092 switch(ui.rx_addev_no)
2093 {
2094 case SDR14_DEVICE_CODE:
2095 sdrnam=sdr14_name_string;
2096 break;
2097
2098 case SDRIQ_DEVICE_CODE:
2099 sdrnam=sdriq_name_string;
2100 break;
2101
2102 case PERSEUS_DEVICE_CODE:
2103 sdrnam=perseus_name_string;
2104 break;
2105
2106 case SDRIP_DEVICE_CODE:
2107 sdrnam=sdrip_name_string;
2108 break;
2109
2110 case EXCALIBUR_DEVICE_CODE:
2111 sdrnam=excalibur_name_string;
2112 break;
2113
2114 case RTL2832_DEVICE_CODE:
2115 sdrnam=rtl2832_name_string;
2116 break;
2117
2118 case MIRISDR_DEVICE_CODE:
2119 sdrnam=mirics_name_string;
2120 break;
2121
2122 case BLADERF_DEVICE_CODE:
2123 sdrnam=bladerf_name_string;
2124 break;
2125
2126 case PCIE9842_DEVICE_CODE:
2127 sdrnam=pcie9842_name_string;
2128 break;
2129
2130 case OPENHPSDR_DEVICE_CODE:
2131 sdrnam=openhpsdr_name_string;
2132 break;
2133
2134 case NETAFEDRI_DEVICE_CODE:
2135 sdrnam=netafedri_name_string;
2136 break;
2137
2138 case DISABLED_DEVICE_CODE:
2139 sdrnam="Hardware disabled";
2140 break;
2141
2142 case UNDEFINED_DEVICE_CODE:
2143 sdrnam="Not defined";
2144 break;
2145
2146 case NETWORK_DEVICE_CODE:
2147 sdrnam="NETWORK";
2148 sprintf(ss,"%s",netin_txt());
2149 break;
2150
2151 default:
2152 sdrnam="Soundcard";
2153 if(ui.use_extio != 0)
2154 {
2155 get_extio_name(&ss[0]);
2156 if( (ui.use_extio&EXTIO_USE_SOUNDCARD) == 0)
2157 {
2158 sdrnam="Callback";
2159 }
2160 }
2161 else
2162 {
2163 switch (ui.soundcard_radio)
2164 {
2165 case SOUNDCARD_RADIO_WSE:
2166 sdrnam="WSE";
2167 read_wse_parameters();
2168 if(wse.parport == 0)
2169 {
2170 allow_wse_parport=FALSE;
2171 sprintf(ss,"Disabled (port=0 illegal)");
2172 }
2173 else
2174 {
2175 if(lir_parport_permission(wse.parport)==TRUE)
2176 {
2177 wse_parport_status=wse.parport+1;
2178 wse_parport_control=wse.parport+2;
2179 wse_parport_ack_sign=0;
2180 switch (wse.parport_pin)
2181 {
2182 case 15:
2183 wse_parport_ack=8;
2184 break;
2185
2186 case 13:
2187 wse_parport_ack=16;
2188 break;
2189
2190 case 10:
2191 wse_parport_ack=64;
2192 break;
2193
2194 case 11:
2195 wse_parport_ack=128;
2196 wse_parport_ack_sign=128;
2197 break;
2198 }
2199 allow_wse_parport=TRUE;
2200 if (wse.parport==USB2LPT16_PORT_NUMBER)
2201 {
2202 strcpy(st,"USB2LPT");
2203 }
2204 else
2205 {
2206 sprintf(st,"%d",wse.parport);
2207 }
2208 sprintf(ss,"Parport %s:%d",st,wse.parport_pin);
2209 }
2210 else
2211 {
2212 allow_wse_parport=FALSE;
2213 sprintf(ss,"WSE Parport disabled");
2214 }
2215 }
2216 break;
2217
2218 case SOUNDCARD_RADIO_SI570:
2219 sprintf(ss,"Si570");
2220 break;
2221
2222 case SOUNDCARD_RADIO_SOFT66:
2223 sprintf(ss,"Soft66");
2224 break;
2225
2226 case SOUNDCARD_RADIO_ELEKTOR:
2227 sprintf(ss,"Elektor");
2228 break;
2229
2230 case SOUNDCARD_RADIO_FCDPROPLUS:
2231 sprintf(ss,"Funcube Pro+");
2232 break;
2233
2234 case SOUNDCARD_RADIO_AFEDRI_USB:
2235 sprintf(ss,"Afedri USB");
2236 break;
2237
2238 default:
2239 break;
2240 }
2241 }
2242 }
2243 sprintf(retmsg,"%s %s",sdrnam,ss);
2244 }
2245