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