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 #define YWF 4
25 #define YBO 4
26 #define DA_GAIN_RANGE 8.
27 #define DA_GAIN_REF 1.
28 #define BG_MINYCHAR 8
29 #define BG_MIN_WIDTH (36*text_width)
30 
31 
32 #define BG_BFO    1
33 #define BG_BFO10  2
34 #define BG_BFO100 3
35 #define BG_FLAT   4
36 #define BG_CURV   5
37 #define BG_VOLUME 6
38 
39 #include <unistd.h>
40 #include <string.h>
41 #include "globdef.h"
42 #include "uidef.h"
43 #include "fft3def.h"
44 #include "fft2def.h"
45 #include "fft1def.h"
46 #include "sigdef.h"
47 #include "seldef.h"
48 #include "vernr.h"
49 #include "screendef.h"
50 #include "graphcal.h"
51 #include "rusage.h"
52 #include "thrdef.h"
53 #include "options.h"
54 
55 int binshape_points;
56 int binshape_total;
57 int reinit_baseb;
58 int baseband_graph_scro;
59 int bg_old_x1;
60 int bg_old_x2;
61 int bg_old_y1;
62 int bg_old_y2;
63 int new_bg_agc_flag;
64 int new_bg_fm_mode;
65 int new_bg_fm_subtract;
66 int new_bg_ch2_phase;
67 
68 int new_daout_channels;
69 int new_daout_bytes;
70 
71 int new_bg_delay;
72 int new_bg_coherent;
73 int new_bg_twopol;
74 
75 float make_interleave_ratio(int nn);
76 void prepare_mixer(MIXER_VARIABLES *m, int nn);
77 
78 static int ch2_signs[3]={1,-1,0};
79 
80 
iir5_c4(float fq)81 float iir5_c4(float fq)
82 {
83 double f, dt1;
84 f=fq;
85 f+=(double)1.09997;
86 dt1=(double)-8180.447687211407;
87 dt1+=(double)7606.001654061646/f;
88 dt1+=(double)4911.238063416248*f;
89 dt1+=(double)-3722.590923768796/(f*f);
90 dt1+=(double)-1563.849845278449*f*f;
91 dt1+=(double)752.161694907701/(f*f*f);
92 dt1+=(double)204.513728752513*f*f*f;
93 return (float)dt1;
94 }
95 
iir5_c3(float fq)96 float iir5_c3(float fq)
97 {
98 double f, dt1;
99 f=fq;
100 f+=(double).486;
101 dt1=(double)1216.739279441632;
102 dt1+=(double)-498.037837421718/f;
103 dt1+=(double)-1605.884219112067*f;
104 dt1+=(double)98.522399169193/(f*f);
105 dt1+=(double)1163.334654719262*f*f;
106 dt1+=(double)-8.037391363636/(f*f*f);
107 dt1+=(double)-378.207481959566*f*f*f;
108 dt1+=(double)0.460060792302*f*f*f*f;
109 return (float)dt1;
110 }
111 
iir5_c2(float fq)112 float iir5_c2(float fq)
113 {
114 double f, dt1;
115 f=fq;
116 f+=(double).373;
117 dt1=(double)-1367.817993435964;
118 dt1+=(double)321.426710716263/f;
119 dt1+=(double)3143.873042678646*f;
120 dt1+=(double)-33.921164217429/(f*f);
121 dt1+=(double)-4207.054014954479*f*f;
122 dt1+=(double)1.474943544810/(f*f*f);
123 dt1+=(double)3173.210883130213*f*f*f;
124 dt1+=(double)-1061.231815380881*f*f*f*f;
125 return (float)dt1;
126 }
127 
iir5_c1(float fq)128 float iir5_c1(float fq)
129 {
130 double f, dt1;
131 f=fq;
132 f+=(double).13607;
133 dt1=(double)44.536544420484;
134 dt1+=(double)-6.546900527778/f;
135 dt1+=(double)-135.019183000212*f;
136 dt1+=(double)0.298668662095/(f*f);
137 dt1+=(double)185.556866049127*f*f;
138 dt1+=(double)-0.006124743273/(f*f*f);
139 dt1+=(double)-66.083966540342*f*f*f;
140 dt1+=(double)-56.694842234911*f*f*f*f;
141 return (float)dt1;
142 }
143 
iir5_c0(float fq)144 float iir5_c0(float fq)
145 {
146 double f, dt1;
147 f=fq;
148 f=f+(double)0.25;
149 f=pow(f,(double)1.02);
150 dt1= (double)36.927768658067;
151 dt1+=(double)-70.589472628117*f;
152 dt1+=(double)72.191321694731*f*f;
153 dt1+=(double)-31.339811219801*f*f*f;
154 dt1+=(double)-10.505632906345/f;
155 dt1+=(double)1.399038105205/(f*f);
156 dt1+=(double)-0.043679124720/(f*f*f);
157 return (float)dt1;
158 }
159 
iir5_gain(float fq)160 float iir5_gain(float fq)
161 {
162 double f, dt1;
163 // fq is the corner frequency divided by the sampling frequency
164 f=fq;
165 dt1=(double)0.147800765172*pow(f,-3);
166 dt1+=(double)0.03169658430080*pow(f,-4);
167 dt1+=(double)0.0032849456565132*pow(f,-5);
168 dt1+=(double)-0.1237864623*pow(f,-2);
169 return (float)dt1;
170 }
171 
make_iir5(float fq,IIR5_PARMS * iir5)172 void make_iir5(float fq, IIR5_PARMS *iir5)
173 {
174 iir5[0].gain=iir5_gain(fq);
175 iir5[0].c0=iir5_c0(fq);
176 iir5[0].c1=iir5_c1(fq);
177 iir5[0].c2=iir5_c2(fq);
178 iir5[0].c3=iir5_c3(fq);
179 iir5[0].c4=iir5_c4(fq);
180 }
181 
halt_rx_output(void)182 void halt_rx_output(void)
183 {
184 int i;
185 i=0;
186 await_semclear:;
187 if(all_threads_started &&
188          thread_status_flag[THREAD_RX_OUTPUT]!=THRFLAG_SEMCLEAR)
189   {
190   if(new_baseb_flag != 0)
191     {
192     i++;
193     lir_sleep(20000);
194     if(i<60)goto await_semclear;
195     lirerr(564292);
196     return;
197     }
198 // The output is running. Stop it now!
199   pause_thread(THREAD_RX_OUTPUT);
200   thread_command_flag[THREAD_RX_OUTPUT]=THRFLAG_SEMCLEAR;
201   lir_sched_yield();
202   while(thread_status_flag[THREAD_RX_OUTPUT] != THRFLAG_SEMCLEAR)
203     {
204     lir_sleep(1000);
205     }
206   baseb_reset_counter++;
207   }
208 }
209 
clear_baseb_arrays(int nn,int k)210 void clear_baseb_arrays(int nn,int k)
211 {
212 memset(&baseb_raw[2*nn],0,2*k*sizeof(float));
213 memset(&baseb_raw_orthog[2*nn],0,2*k*sizeof(float));
214 memset(&baseb[2*nn],0,2*k*sizeof(float));
215 memset(&baseb_carrier[2*nn],0,2*k*sizeof(float));
216 memset(&baseb_carrier_ampl[nn],0,k*sizeof(float));
217 memset(&baseb_totpwr[nn],0,k*sizeof(float));
218 if(bg.agc_flag != 0)
219   {
220   memset(&baseb_agc_level[nn],0,k*sizeof(float));
221   memset(&baseb_agc_det[nn],0,k*sizeof(float));
222   memset(&baseb_threshold[bg.agc_flag*nn],0,bg.agc_flag*k*sizeof(float));
223   memset(&baseb_upthreshold[bg.agc_flag*nn],0,bg.agc_flag*k*sizeof(float));
224   }
225 lir_sched_yield();
226 if(genparm[CW_DECODE_ENABLE] != 0)
227   {
228   if(bg.agc_flag == 0)
229     {
230     memset(&baseb_threshold[nn],0,k*sizeof(float));
231     memset(&baseb_upthreshold[nn],0,k*sizeof(float));
232     }
233   memset(&baseb_ramp[nn],-cg_code_unit,k*sizeof(short int));
234   memset(&baseb_wb_raw[2*nn],0,2*k*sizeof(float));
235   memset(&baseb_fit[2*nn],0,2*k*sizeof(float));
236   memset(&baseb_tmp[2*nn],0,2*k*sizeof(float));
237   memset(&baseb_sho1[2*nn],0,2*k*sizeof(float));
238   memset(&baseb_sho2[2*nn],0,2*k*sizeof(float));
239   memset(&baseb_envelope[2*nn],0,2*k*sizeof(float));
240   }
241 lir_sched_yield();
242 }
243 
filcur_pixel(int points)244 int filcur_pixel(int points)
245 {
246 float t1;
247 t1=(float)(2*points)/fft3_size;
248 t1=sqrt(t1);
249 return bg_first_xpixel+t1*bg_xpixels;
250 //return bg_first_xpixel+(bg_xpixels*2*points)/fft3_size;
251 }
252 
filcur_points(void)253 int filcur_points(void)
254 {
255 float t1;
256 t1=(float)(mouse_x-bg_first_xpixel+1)/bg_xpixels;
257 t1=t1*t1;
258 return 0.5*fft3_size*t1;
259 }
260 
make_bg_waterf_cfac(void)261 void make_bg_waterf_cfac(void)
262 {
263 bg_waterf_cfac=bg.waterfall_gain*0.1;
264 bg_waterf_czer=10*bg.waterfall_zero;
265 }
266 
make_bg_yfac(void)267 void make_bg_yfac(void)
268 {
269 if(genparm[SECOND_FFT_ENABLE]==0)
270   {
271   bg.yfac_power=FFT1_BASEBAND_FACTOR;
272   bg.yfac_power*=ui.rx_rf_channels*ui.rx_rf_channels;
273   }
274 else
275   {
276   bg.yfac_power=FFT2_BASEBAND_FACTOR*
277                 (float)(1<<genparm[FIRST_BCKFFT_ATT_N])/fft2_size;
278   if(fft_cntrl[FFT2_CURMODE].mmx != 0)
279     {
280     bg.yfac_power*=1.4*(1<<(genparm[SECOND_FFT_ATT_N]));
281     }
282   bg.yfac_power*=bg.yfac_power;
283   bg.yfac_power*=(float)(1<<genparm[MIX1_BANDWIDTH_REDUCTION_N]);
284   }
285 bg.yfac_power*=(1 + 1/(0.5+genparm[FIRST_FFT_SINPOW]))/(float)(fft1_size);
286 bg.yfac_power/=fft3_size;
287 baseband_pwrfac=10*bg.yfac_power/fft3_size;
288 bg_waterf_yfac=20*baseband_pwrfac/bg.waterfall_avgnum;
289 bg.yfac_power/=bg.yzero*bg.yzero;
290 bg.yfac_log=10/bg.db_per_pixel;
291 }
292 
make_daout_gain(void)293 void make_daout_gain(void)
294 {
295 float t1;
296 if(daout_gain_y>bg_y0)daout_gain_y=bg_y0;
297 if(daout_gain_y<bg_ymax)daout_gain_y=bg_ymax;
298 t1=(float)((bg_y0+bg_ymax)/2-daout_gain_y)/(bg_y0-bg_ymax);
299 bg.output_gain=pow(10.,t1*DA_GAIN_RANGE)/DA_GAIN_REF;
300 if(rx_mode == MODE_FM && bg_coherent < 2)
301   {
302   daout_gain=5*bg.output_gain;
303   }
304 else
305   {
306   daout_gain=0.5*bg.output_gain/fft3_size;
307   if(genparm[SECOND_FFT_ENABLE]!=0)
308     {
309     daout_gain/=fft2_size;
310     daout_gain*=1<<genparm[FIRST_BCKFFT_ATT_N];
311     if(fft_cntrl[FFT2_CURMODE].mmx != 0)
312       {
313       daout_gain*=1<<(genparm[SECOND_FFT_ATT_N]);
314       }
315     }
316   daout_gain*=sqrt((1 + 1/(0.5+genparm[FIRST_FFT_SINPOW]))/
317                                                    (float)(fft1_size));
318   }
319 if(rx_daout_bytes == 2)
320   {
321   daout_gain*=256;
322   }
323 }
324 
make_daout_gainy(void)325 void make_daout_gainy(void)
326 {
327 int old;
328 float t1;
329 old=daout_gain_y;
330 t1=log10(bg.output_gain*DA_GAIN_REF)/DA_GAIN_RANGE;
331 daout_gain_y=(bg_y0+bg_ymax)/2-t1*(bg_y0-bg_ymax);
332 make_daout_gain();
333 update_bar(bg_vol_x1,bg_vol_x2,bg_y0,daout_gain_y,old,
334                                                  BG_GAIN_COLOR,bg_volbuf);
335 }
336 
make_new_daout_upsamp(void)337 void make_new_daout_upsamp(void)
338 {
339 int k, new;
340 float t1;
341 t1=da_resample_ratio;
342 new=1;
343 daout_upsamp_n=0;
344 if( (ui.network_flag & NET_RXOUT_BASEB) == 0)
345   {
346   k=genparm[DA_OUTPUT_SPEED];
347   while(t1 > 5 && k > 16000 && new < 32)
348     {
349     daout_upsamp_n++;
350     k/=2;
351     t1/=2;
352     new*=2;
353     }
354   }
355 if(new != daout_upsamp)
356   {
357   halt_rx_output();
358   daout_upsamp=new;
359   }
360 }
361 
make_bfo(void)362 void make_bfo(void)
363 {
364 float bforef, bfooff, t1;
365 if(rx_mode == MODE_SSB)sc[SC_FREQ_READOUT]++;
366 if(use_bfo == 0)
367   {
368   rx_daout_cos=1;
369   rx_daout_sin=0;
370   rx_daout_phstep_sin=0;
371   rx_daout_phstep_cos=1;
372   bfo_xpixel=-1;
373   bfo10_xpixel=-1;
374   bfo100_xpixel=-1;
375   return;
376   }
377 if(bfo_xpixel > 0)
378   {
379   if(bg_filterfunc_y[bfo_xpixel] > 0)
380                      lir_setpixel(bfo_xpixel,bg_filterfunc_y[bfo_xpixel],14);
381   if(bg_filterfunc_y[bfo10_xpixel] > 0)
382                  lir_setpixel(bfo10_xpixel,bg_filterfunc_y[bfo10_xpixel],14);
383   if(bg_filterfunc_y[bfo100_xpixel] > 0)
384                lir_setpixel(bfo100_xpixel,bg_filterfunc_y[bfo100_xpixel],14);
385   if(bg_carrfilter_y[bfo_xpixel] > 0)
386                      lir_setpixel(bfo_xpixel,bg_carrfilter_y[bfo_xpixel],14);
387   if(bg_carrfilter_y[bfo10_xpixel] > 0)
388                  lir_setpixel(bfo10_xpixel,bg_carrfilter_y[bfo10_xpixel],14);
389   if(bg_carrfilter_y[bfo100_xpixel] > 0)
390                lir_setpixel(bfo100_xpixel,bg_carrfilter_y[bfo100_xpixel],14);
391   }
392 // When we arrive here only bg.bfo_freq is defined.
393 // Set up the other variables we need that depend on it.
394 make_new_daout_upsamp();
395 t1=(2*PI_L*bg.bfo_freq)/genparm[DA_OUTPUT_SPEED];
396 rx_daout_phstep_cos=cos(t1);
397 rx_daout_phstep_sin=sin(t1);
398 bforef=bg_first_xpixel+0.5+bg.pixels_per_point*(fft3_size/2-bg_first_xpoint);
399 bfooff=bg.pixels_per_point*bg.bfo_freq/bg_hz_per_pixel;
400 bfo_xpixel=bforef+bfooff;
401 if(bfo_xpixel < bg_first_xpixel)bfo_xpixel=bg_first_xpixel;
402 if(bfo_xpixel > bg_last_xpixel)bfo_xpixel=bg_last_xpixel;
403 bfo10_xpixel=bforef+0.1*bfooff;
404 if(bfo10_xpixel < bg_first_xpixel)bfo10_xpixel=bg_first_xpixel;
405 if(bfo10_xpixel > bg_last_xpixel)bfo10_xpixel=bg_last_xpixel;
406 bfo100_xpixel=bforef+0.01*bfooff;
407 if(bfo100_xpixel < bg_first_xpixel)bfo100_xpixel=bg_first_xpixel;
408 if(bfo100_xpixel > bg_last_xpixel)bfo100_xpixel=bg_last_xpixel;
409 lir_line(bfo100_xpixel, bg_y0,bfo100_xpixel,bg_y1,12);
410 if(kill_all_flag) return;
411 lir_line(bfo10_xpixel, bg_y1-1,bfo10_xpixel,bg_y2,12);
412 if(kill_all_flag) return;
413 lir_line(bfo_xpixel, bg_y2-1,bfo_xpixel,bg_y3,12);
414 }
415 
chk_bg_avgnum(void)416 void chk_bg_avgnum(void)
417 {
418 if(fft3_blocktime*bg.fft_avgnum > genparm[BASEBAND_STORAGE_TIME])
419            bg.fft_avgnum=genparm[BASEBAND_STORAGE_TIME]/fft3_blocktime;
420 if(bg.fft_avgnum >9999)bg.fft_avgnum=9999;
421 if(bg.fft_avgnum <1)bg.fft_avgnum=1;
422 }
423 
clear_agc(void)424 void clear_agc(void)
425 {
426 // The AGC attack is operated from two series connected low pass filters.
427 // followed by a peak detector.
428 // The AGC is in mix2.c
429 rx_agc_factor1=1;
430 rx_agc_factor2=1;
431 rx_agc_sumpow1=0;
432 rx_agc_sumpow2=0;
433 rx_agc_sumpow3=0;
434 rx_agc_sumpow4=0;
435 rx_agc_fastsum1=0;
436 rx_agc_fastsum2=0;
437 rx_agc_fast_factor1=pow(0.5,2000./baseband_sampling_speed);
438 rx_agc_fast_factor2=1-rx_agc_fast_factor1;
439 agc_attack_factor1=pow(0.5,1000./(baseband_sampling_speed*(1<<bg.agc_attack)));
440 agc_release_factor=pow(0.5,500./(baseband_sampling_speed*(1<<bg.agc_release)));
441 agc_attack_factor2=1-agc_attack_factor1;
442 bg_agc_hang_pts=0.01*baseband_sampling_speed*pow(1.7,(float)(bg.agc_hang));
443 if(bg_agc_hang_pts > baseband_size/2)bg_agc_hang_pts=baseband_size/2;
444 }
445 
446 /*void construct_fir(int win, int siz, int n, int *points, int ct,
447                                               float *fir, float small)
448 */
construct_fir(int win,int siz,int n,int * points,int ct,float * fir,float zsmall)449 void construct_fir(int win, int siz, int n, int *points, int ct,
450                                               float *fir, float zsmall)
451 
452 {
453 int i,j,k,ib,ic,ja,jb,cutoff;
454 float t1,t2;
455 float *firbuf;
456 float *fir_window;
457 unsigned short int *fir_permute;
458 COSIN_TABLE *fir_tab;
459 cutoff=ct;
460 if(cutoff < 1)cutoff=1;
461 if(cutoff>=siz/2)cutoff=siz/2-1;
462 // Construct a FIR filter of size siz with a cut-off frequency cutoff.
463 // The array of FIR filter coefficients is the pulse response of a FIR
464 // filter. Get it by taking the FFT.
465 // We use only the real half of a complex FFT.
466 firbuf=malloc(siz*(3*sizeof(float)+sizeof(short int)+sizeof(COSIN_TABLE)/2));
467 if(firbuf == NULL)
468   {
469   lirerr(493367);
470   return;
471   }
472 fir_window=&firbuf[siz*2];
473 fir_permute=(void*)(&fir_window[siz]);
474 fir_tab=(void*)(&fir_permute[siz]);
475 init_fft(1,n, siz, fir_tab, fir_permute);
476 make_window(1,siz, win, fir_window);
477 firbuf[0]=1;
478 firbuf[1]=0;
479 jb=siz-1;
480 for(ja=1; ja<cutoff; ja++)
481   {
482   firbuf[2*ja  ]=1;
483   firbuf[2*jb  ]=1;
484   firbuf[2*ja+1]=0;
485   firbuf[2*jb+1]=0;
486   jb--;
487   }
488 for(ja=cutoff; ja<siz/2; ja++)
489   {
490   firbuf[2*ja  ]=0;
491   firbuf[2*jb  ]=0;
492   firbuf[2*ja+1]=0;
493   firbuf[2*jb+1]=0;
494   jb--;
495   }
496 firbuf[2*jb  ]=0;
497 firbuf[2*jb+1]=0;
498 for( i=0; i<siz/2; i++)
499   {
500   t1=firbuf[2*i  ];
501   t2=firbuf[siz+2*i  ];
502   firbuf[2*i  ]=t1+t2;
503   firbuf[siz+2*i  ]=fir_tab[i].cos*(t1-t2);
504   firbuf[siz+2*i+1]=fir_tab[i].sin*(t1-t2);
505   }
506 #if IA64 == 0 && CPU == CPU_INTEL
507 asmbulk_of_dif(siz, n, firbuf, fir_tab, yieldflag_ndsp_fft3);
508 #else
509 bulk_of_dif(siz, n, firbuf, fir_tab, yieldflag_ndsp_fft3);
510 #endif
511 for(i=0; i < siz; i+=2)
512   {
513   ib=fir_permute[i];
514   ic=fir_permute[i+1];
515   fir[ib]=firbuf[2*i  ]+firbuf[2*i+2];
516   fir[ic]=firbuf[2*i  ]-firbuf[2*i+2];
517   }
518 // Now take the effects of our window into account.
519 // Note the order in which fir_window is stored.
520 for(i=0; i<siz/2; i++)
521   {
522   fir[i]*=fir_window[2*i];
523   fir[siz/2+i]*=fir_window[2*i+1];
524   }
525 free(firbuf);
526 // The FIR filter must be symmetric. Actually forcing symmetry
527 // might reduce rounding errors slightly.
528 for(i=1; i<siz/2; i++)
529   {
530   fir[i]=0.5*(fir[i]+fir[siz-i]);
531   fir[siz-i]=fir[i];
532   }
533 // There is no reason to make the FIR filter extend outside
534 // the range where the coefficients are below zsmall (supplied parameter).
535 t1=zsmall*fir[siz/2];
536 k=0;
537 while(fabs(fir[k]) < t1)k++;
538 j=k;
539 points[0]=0;
540 while(k<=siz-j-1)
541   {
542   fir[points[0]]=fir[k];
543   k++;
544   points[0]++;
545   }
546 k=points[0];
547 if(k<siz)memset(&fir[k],0,siz-k);
548 // Normalize the FIR filter.
549 t1=0;
550 for(i=0; i<points[0]; i++)
551   {
552   t1+=fir[i];
553   }
554 t1=1/t1;
555 for(i=0; i<points[0]; i++)
556   {
557   fir[i]*=t1;
558   }
559 }
560 
561 
562 
init_basebmem(void)563 void init_basebmem(void)
564 {
565 float t1, t2;
566 int i, k, clr_size;
567 // Sampling rate for baseband has changed.
568 // Set flag to flush old data and reinit output.
569 reinit_baseb=FALSE;
570 lir_sched_yield();
571 if( (cg.oscill_on&6) != 0)
572   {
573   clear_cg_traces();
574   cg.oscill_on=1;
575   cg_osc_ptr=0;
576   }
577 halt_rx_output();
578 if(kill_all_flag)return;
579 if(baseband_handle != NULL)
580   {
581   baseband_handle=chk_free(baseband_handle);
582   }
583 // Make the daout buffer big enough to hold data for at least 6
584 // times longer than the rate at which the wideband thread posts
585 // to the narrowband thread.
586 t1=(6*fftx_size)/ui.rx_ad_speed;
587 // Make sure minimum is 0.5 seconds
588 if(t1<0.5)t1=0.5;
589 t1*=genparm[DA_OUTPUT_SPEED];
590 // and make sure we can hold 8192 samples
591 if(t1 < 8192)t1=8192;
592 daout_size=t1;
593 if(daout_size < 8*snd[RXDA].block_frames)daout_size=8*snd[RXDA].block_frames;
594 // Do not use snd[RXDA].framesize since bytes or channels may have changed.
595 daout_size*=rx_daout_bytes*rx_daout_channels*2;
596 make_power_of_two(&daout_size);
597 t1=3*(float)(daout_size)/genparm[DA_OUTPUT_SPEED];
598 if(t1<genparm[BASEBAND_STORAGE_TIME])t1=genparm[BASEBAND_STORAGE_TIME];
599 // Allocate memory for transformation from fft3 to the baseband.
600 // We are already in the baseband but the filter in use may allow
601 // a reduction of the sampling speed.
602 baseband_size=t1*baseband_sampling_speed;
603 make_power_of_two(&baseband_size);
604 daout_bufmask=daout_size-1;
605 cg_size=2+(COH_SIDE*text_width)/3;
606 cg_size&=0xfffffffe;
607 k=2+bg_flatpoints+2*bg_curvpoints;
608 if(genparm[THIRD_FFT_SINPOW] > 3)k+=2;
609 if(genparm[THIRD_FFT_SINPOW] == 8)k+=2;
610 cg_code_unit=0.5*(float)(mix2.size)/k;
611 cg_decay_factor=pow(0.5,0.2/cg_code_unit);
612 cw_waveform_max=14*cg_code_unit;
613 if(cw_waveform_max >= (int)(fftn_tmp_bytes/(2*sizeof(float))))
614   {
615   cw_waveform_max=fftn_tmp_bytes/(2*sizeof(float))-1;
616   }
617 cg_osc_offset=mix2.size+50*cg_code_unit;
618 while(baseband_size < 4*cg_osc_offset)baseband_size*=2;
619 if(baseband_size < 8*(int)mix2.size)baseband_size=8*mix2.size;
620 reduce:;
621 if(baseband_size < 4*cg_osc_offset)
622   {
623   cg_osc_offset=baseband_size/4;
624   }
625 cg_osc_offset_inc=cg_osc_offset/2;
626 max_cwdat=MAX_CW_PARTS*baseband_size/cg_code_unit;
627 baseband_mask=baseband_size-1;
628 baseband_neg=(7*baseband_size)>>3;
629 baseband_sizhalf=baseband_size>>1;
630 // The time stored in the baseband buffers is
631 // baseband_size/baseband_sampling_speed, the same time is contained in
632 // the basblock buffers in mix2.size/2 fewer points.
633 // Find out the number of basblock points that correspond to
634 // 5 seconds, the time constant for dB meter peak hold.
635 basblock_size=2*baseband_size/mix2.size;
636 basblock_mask=basblock_size-1;
637 basblock_hold_points=5*basblock_size*baseband_sampling_speed/baseband_size;
638 if(basblock_hold_points<3)basblock_hold_points=3;
639 if(basblock_hold_points>basblock_mask)basblock_hold_points=basblock_mask;
640 // When listening to wideband signals, the time between basblock
641 // points may become short.
642 // Make sure we do not update the coherent graph too often,
643 // graphics may be rather slow.
644 cg_update_interval=basblock_hold_points/20;
645 cg_update_count=0;
646 clear_agc();
647 fft3_interleave_ratio=make_interleave_ratio(THIRD_FFT_SINPOW);
648 // We get signals from back transformation of fft3.
649 // We must use an interleave ratio that makes the interleave points
650 // go even up in mix2.size.
651 mix2.interleave_points=fft3_interleave_ratio*mix2.size;
652 mix2.interleave_points&=0xfffffffe;
653 mix2.new_points=mix2.size-mix2.interleave_points;
654 fft3_interleave_points=mix2.interleave_points*(fft3_size/mix2.size);
655 fft3_interleave_ratio=(float)(fft3_interleave_points)/fft1_size;
656 fft3_new_points=fft3_size-fft3_interleave_points;
657 fft3_blocktime=(float)(fft3_new_points)/timf3_sampling_speed;
658 if( rx_mode == MODE_FM )
659   {
660 // ******************  fm_audiofil  ***************************
661 // We need a low pass filter with cut-off as specified by the user.
662 // Make the cross-over region 250 Hz, but degrade the steepness
663 // in case the baseband sampling speed is very high.
664   fm_audiofil_size=baseband_sampling_speed/250;
665   if(fm_audiofil_size > 512)fm_audiofil_size=512;
666   fm_audiofil_n=make_power_of_two(&fm_audiofil_size);
667   }
668 if( rx_mode == MODE_FM && baseband_sampling_speed > 105000)
669   {
670 // ******************  fmfil70  ************************
671 // We need a low pass filter with cut-off at about 70 kHz.
672 // Construct a FIR filter that will allow the cross-over region
673 // to be about 5 kHz.
674 // This filter will attenuate by about 100 dB above 80 kHz so we
675 // can resample the output if the baseband sampling rate is above 160kHz.
676 // For FM processing we have no reason to keep data in memory for
677 // a long time. Make the buffer one second.
678 #if NET_BASEBRAW_MODE == WFM_FM_FIRST_LOWPASS || \
679     NET_BASEBRAW_MODE == WFM_AM_FIRST_LOWPASS || \
680     NET_BASEBRAW_MODE == WFM_SYNTHETIZED_FROM_FIRST_LOWPASS || \
681     NET_BASEBRAW_MODE == WFM_SUBTRACT_FROM_FIRST_LOWPASS
682   fmfil70_size=baseband_sampling_speed/2500;
683 #else
684   fmfil70_size=baseband_sampling_speed/5000;
685 #endif
686   fmfil70_n=make_power_of_two(&fmfil70_size);
687   fm1_resample_ratio=baseband_sampling_speed/160000;
688   fm1_sampling_speed=baseband_sampling_speed/fm1_resample_ratio;
689   fm1_size=fm1_sampling_speed;
690   make_power_of_two(&fm1_size);
691   fm1_mask=fm1_size-1;
692 // ******************  fmfil55  ************************
693 // We need a low pass filter with cut-off at 55 kHz.
694 // Construct a FIR filter that will allow the cross-over region
695 // to be about 2 kHz.
696   fmfil55_size=baseband_sampling_speed/2000;
697   fmfil55_n=make_power_of_two(&fmfil55_size);
698 // ******************  fmfil  ***************************
699 // We need a low pass filter with cut-off at about 17 kHz
700 // for wideband FM.
701   fmfil_size=baseband_sampling_speed/2000;
702   fmfil_n=make_power_of_two(&fmfil_size);
703 // ******************************************************
704 // ******************  fmfil_rds  ***************************
705 // We need a low pass filter with cut-off at 1.8 kHz for RDS.
706 // Construct a FIR filter that will allow the cross-over region
707 // to be about 1 kHz.
708   fmfil_rds_size=baseband_sampling_speed/1000;
709   fmfil_rds_n=make_power_of_two(&fmfil_rds_size);
710 // ******************************************************
711 // For wideband FM we look for a pilot tone at 19 kHz.
712 // Make a filter with a bandwidth of about 100 Hz
713   fm_pilot_size=0.01*baseband_sampling_speed;
714   }
715 else
716   {
717   fm_pilot_size=0;
718   }
719 // ********************************************************
720 init_memalloc(basebmem, MAX_BASEB_ARRAYS);
721 mem(1,&baseb_out,baseband_size*2*baseb_channels*sizeof(float),0);
722 mem(2,&baseb_carrier,baseband_size*2*sizeof(float),0);
723 mem(3,&baseb_raw,baseband_size*2*sizeof(float),0);
724 mem(4,&baseb_raw_orthog,baseband_size*2*sizeof(float),0);
725 mem(5,&baseb,baseband_size*2*sizeof(float),0);
726 mem(6,&baseb_totpwr,baseband_size*sizeof(float),0);
727 mem(7,&baseb_carrier_ampl,baseband_size*sizeof(float),0);
728 mem(8,&mix2.permute,mix2.size*sizeof(short int),0);
729 mem(9,&mix2.table,mix2.size*sizeof(COSIN_TABLE)/2,0);
730 mem(10,&daout,daout_size,0);
731 mem(11,&cg_map,cg_size*cg_size*sizeof(float),0);
732 mem(13,&cg_traces,CG_MAXTRACE*MAX_CG_OSCW*sizeof(short int),0);
733 mem(16,&basblock_maxpower,basblock_size*sizeof(float),0);
734 mem(17,&basblock_avgpower,basblock_size*sizeof(float),0);
735 mem(171,&mix2.window,(mix2.size/2+1)*sizeof(float),0);
736 mem(172,&mix2.cos2win,mix2.new_points*sizeof(float),0);
737 mem(173,&mix2.sin2win,mix2.new_points*sizeof(float),0);
738 if(bg.agc_flag != 0)
739   {
740   mem(18,&baseb_agc_level,bg.agc_flag*baseband_size*sizeof(float),0);
741   mem(1892,&baseb_agc_det,bg.agc_flag*baseband_size*sizeof(float),0);
742   mem(14,&baseb_upthreshold,bg.agc_flag*baseband_size*sizeof(float),0);
743   mem(15,&baseb_threshold,bg.agc_flag*baseband_size*sizeof(float),0);
744   }
745 if(genparm[CW_DECODE_ENABLE] != 0)
746   {
747   if(bg.agc_flag == 0)
748     {
749     mem(14,&baseb_upthreshold,baseband_size*sizeof(float),0);
750     mem(15,&baseb_threshold,baseband_size*sizeof(float),0);
751     }
752   mem(27,&baseb_ramp,baseband_size*sizeof(short int),0);
753   keying_spectrum_size=mix2.size/cg_code_unit;
754   if(keying_spectrum_size > (int)mix2.size/2)keying_spectrum_size=mix2.size/2;
755   mem(19,&baseb_envelope,baseband_size*2*sizeof(float),0);
756   mem(21,&dash_waveform,cw_waveform_max*2*sizeof(float),0);
757   mem(215,&dash_wb_waveform,cw_waveform_max*2*sizeof(float),0);
758   mem(225,&dot_wb_waveform,cw_waveform_max*sizeof(float),0);
759   mem(23,&baseb_fit,baseband_size*2*sizeof(float),0);
760   mem(24,&cw_carrier_window,mix2.size*sizeof(float),0);
761   mem(25,&mix2_tmp,2*mix2.size*sizeof(float),0);
762   mem(26,&mix2_pwr,mix2.size*sizeof(float),0);
763   mem(28,&baseb_tmp,baseband_size*2*sizeof(float),0);
764   mem(281,&baseb_sho1,baseband_size*2*sizeof(float),0);
765   mem(282,&baseb_sho2,baseband_size*2*sizeof(float),0);
766   mem(283,&baseb_wb_raw,baseband_size*2*sizeof(float),0);
767   mem(30,&cw,max_cwdat*sizeof(MORSE_DECODE_DATA),0);
768   mem(31,&keying_spectrum,keying_spectrum_size*sizeof(float),0);
769   mem(285,&baseb_clock,baseband_size*sizeof(float),0);
770   }
771 if(rx_mode == MODE_FM)
772   {
773   mem(311,&baseb_fm_demod,baseband_size*2*baseb_channels*sizeof(float),0);
774   mem(1311,&fm_audiofil_fir,fm_audiofil_size*sizeof(float),0);
775     mem(314,&baseb_fm_phase,baseband_size*baseb_channels*sizeof(float),0);
776   if(fm_pilot_size > 0)
777     {
778     if(baseb_channels != 1)
779       {
780       lirerr(873105);
781       return;
782       }
783     mem(312,&baseb_fm_demod_low,baseband_size*baseb_channels*sizeof(float),0);
784     mem(313,&baseb_fm_demod_high,baseband_size*baseb_channels*sizeof(float),0);
785     mem(320,&fm_pilot_tone,2*fm_pilot_size*sizeof(float),0);
786     mem(321,&baseb_fm_pil2,baseband_size*baseb_channels*sizeof(float),0);
787     mem(322,&baseb_fm_pil3,baseband_size*2*baseb_channels*sizeof(float),0);
788     mem(324,&fmfil55_fir,fmfil55_size*sizeof(float),0);
789     mem(325,&baseb_fm_pil2det,baseband_size*baseb_channels*sizeof(float),0);
790     mem(326,&baseb_fm_pil3det,baseband_size*2*baseb_channels*sizeof(float),0);
791     mem(327,&baseb_fm_sumchan,baseband_size*baseb_channels*sizeof(float),0);
792     mem(328,&baseb_fm_diffchan,baseband_size*baseb_channels*sizeof(float),0);
793     mem(329,&baseb_fm_rdsraw,2*baseband_size*baseb_channels*sizeof(float),0);
794     mem(330,&fmfil_fir,fmfil_size*sizeof(float),0);
795     mem(331,&fmfil_rds_fir,fmfil_rds_size*sizeof(float),0);
796     mem(332,&baseb_fm_composite,baseband_size*baseb_channels*sizeof(float),0);
797     mem(333,&fmfil70_fir,fmfil70_size*sizeof(float),0);
798     mem(334,&fm1_all,fm1_size*sizeof(float),0);
799     }
800   }
801 if( (ui.network_flag&NET_RXOUT_BASEBRAW) != 0)
802   {
803 #if NET_BASEBRAW_MODE == WFM_FM_FIRST_LOWPASS || \
804     NET_BASEBRAW_MODE == WFM_AM_FIRST_LOWPASS || \
805     NET_BASEBRAW_MODE == WFM_FM_FULL_BANDWIDTH || \
806     NET_BASEBRAW_MODE == WFM_FM_FIRST_LOWPASS_UPSAMP || \
807     NET_BASEBRAW_MODE == WFM_STEREO_LOW || \
808     NET_BASEBRAW_MODE == WFM_STEREO_HIGH
809 
810   basebraw_sampling_speed=baseband_sampling_speed;
811   basebraw_ad_channels=1;
812   basebraw_rf_channels=1;
813   basebraw_mode=DWORD_INPUT;
814   basebraw_passband_direction=1;
815 #endif
816 #if NET_BASEBRAW_MODE == WFM_FM_FIRST_LOWPASS_RESAMP
817   basebraw_sampling_speed=fm1_sampling_speed;
818   basebraw_ad_channels=1;
819   basebraw_rf_channels=1;
820   basebraw_mode=DWORD_INPUT;
821   basebraw_passband_direction=1;
822 #endif
823 #if NET_BASEBRAW_MODE == BASEBAND_IQ || \
824     NET_BASEBRAW_MODE == WFM_SYNTHETIZED_FROM_FIRST_LOWPASS || \
825     NET_BASEBRAW_MODE == WFM_SUBTRACT_FROM_FIRST_LOWPASS
826   basebraw_sampling_speed=baseband_sampling_speed;
827   basebraw_ad_channels=2*ui.rx_rf_channels;
828   basebraw_rf_channels=ui.rx_rf_channels;
829   basebraw_mode=DWORD_INPUT+IQ_DATA+DIGITAL_IQ;
830   basebraw_passband_direction=-1;
831 #endif
832 #if NET_BASEBRAW_MODE == WFM_AM_FULL_BANDWIDTH
833   basebraw_sampling_speed=baseband_sampling_speed;
834   basebraw_ad_channels=1;
835   basebraw_rf_channels=1;
836   basebraw_mode=DWORD_INPUT;
837   basebraw_passband_direction=1;
838 #endif
839 
840 
841 
842 
843   basebrawnet_block_bytes=(basebraw_ad_channels*basebraw_rf_channels*
844                                     basebraw_sampling_speed)/ui.max_dma_rate;
845   make_power_of_two(&basebrawnet_block_bytes);
846 // Allocate space for 0.3 seconds of data.
847   basebrawnet_size=0.3*basebraw_sampling_speed*2*
848                                       ui.rx_rf_channels*sizeof(int);
849   make_power_of_two(&basebrawnet_size);
850   if(basebrawnet_size/basebrawnet_block_bytes < 8)
851                                  basebrawnet_size=8*basebrawnet_block_bytes ;
852   basebrawnet_mask=basebrawnet_size-1;
853   mem(7578,&basebraw_netsend_buffer,basebrawnet_size,0);
854   }
855 baseband_totmem=memalloc(&baseband_handle,"baseband");
856 if(baseband_totmem == 0)
857   {
858   lir_status=LIR_OK;
859   baseband_size/=2;
860   lir_pixwrite(bg.xleft+text_width,bg.ybottom-4*text_height,"BUFFERS REDUCED");
861   goto reduce;
862   }
863 k=fft3_size/mix2.size;
864 mix2.n=fft3_n;
865 while(k>1)
866   {
867   mix2.n--;
868   k/=2;
869   }
870 if(mix2.n > 12)
871   {
872   yieldflag_ndsp_mix2=TRUE;
873   }
874 else
875   {
876   yieldflag_ndsp_mix2=FALSE;
877   }
878 if(genparm[SECOND_FFT_ENABLE] == 0)
879   {
880   if(ui.max_blocked_cpus > 1)yieldflag_ndsp_mix2=FALSE;
881   }
882 else
883   {
884   if(ui.max_blocked_cpus > 3)yieldflag_ndsp_mix2=FALSE;
885   }
886 prepare_mixer(&mix2, THIRD_FFT_SINPOW);
887 if(genparm[CW_DECODE_ENABLE] != 0)
888   {
889   make_window(4,mix2.size, genparm[THIRD_FFT_SINPOW], cw_carrier_window);
890   }
891 memset(basblock_maxpower,0,basblock_size*sizeof(float));
892 memset(basblock_avgpower,0,basblock_size*sizeof(float));
893 clr_size=4*mix2.size;
894 if(clr_size > baseband_size)clr_size=baseband_size;
895 lir_sched_yield();
896 clear_baseb_arrays(0,clr_size);
897 if(genparm[CW_DECODE_ENABLE] != 0)
898   {
899   for(i=0; i<max_cwdat; i++)
900     {
901     cw[i].tmp=-1;
902     cw[i].unkn=-1;
903     }
904   lir_sched_yield();
905   memset(keying_spectrum,0,keying_spectrum_size*sizeof(float));
906   }
907 memset(baseb_out,0,clr_size*2*baseb_channels*sizeof(float));
908 baseb_pa=0;
909 baseb_py=0;
910 baseb_wts=0;
911 baseb_fx=0;
912 baseb_pf=0;
913 fm1_pa=0;
914 fm1_px=0;
915 rx_daout_cos=1;
916 rx_daout_sin=0;
917 if(kill_all_flag)return;
918 am_dclevel1=0;
919 am_dclevel2=0;
920 am_dclevel_factor1=pow(0.5,2000./(baseband_sampling_speed*(1<<bg.agc_release)));
921 am_dclevel_factor2=1-am_dclevel_factor1;
922 baseb_indicator_block=(baseband_mask+1)/INDICATOR_SIZE;
923 daout_indicator_block=(daout_bufmask+1)/INDICATOR_SIZE;
924 // *********************** pilot tone filter *****************************
925 if(fm_pilot_size > 0)
926   {
927   t1=0;
928   t2=2*PI_L*19000./baseband_sampling_speed;
929   for(i=0; i<fm_pilot_size; i++)
930     {
931     fm_pilot_tone[2*i  ]=cos(t1);
932     fm_pilot_tone[2*i+1]=sin(t1);
933     t1+=t2;
934     }
935 // *********************** fmfil70 *********************************
936 #if NET_BASEBRAW_MODE == WFM_FM_FIRST_LOWPASS || \
937     NET_BASEBRAW_MODE == WFM_AM_FIRST_LOWPASS || \
938     NET_BASEBRAW_MODE == WFM_SYNTHETIZED_FROM_FIRST_LOWPASS
939   i=fmfil70_size*65000/baseband_sampling_speed;
940 #else
941   i=fmfil70_size*68000/baseband_sampling_speed;
942 
943 
944 #endif
945   construct_fir(7,fmfil70_size, fmfil70_n,
946                                  &fmfil70_points, i, fmfil70_fir, 0.00001);
947 // *********************** fmfil55 *********************************
948   i=fmfil55_size*53000/baseband_sampling_speed;
949   construct_fir(7,fmfil55_size, fmfil55_n,
950                                  &fmfil55_points, i, fmfil55_fir, 0.00001);
951 // *********************** fmfil *********************************
952   t1=15000;
953   if(genparm[DA_OUTPUT_SPEED] < 40000)
954     {
955     t1*=genparm[DA_OUTPUT_SPEED]/40000.;
956     }
957   i=fmfil_size*t1/baseband_sampling_speed;
958   construct_fir(7,fmfil_size, fmfil_n,
959                                  &fmfil_points, i, fmfil_fir, 0.00001);
960 // *********************** fmfil_rds ********************************
961   i=fmfil_rds_size*4000/baseband_sampling_speed;
962   construct_fir(7,fmfil_rds_size, fmfil_rds_n,
963                                &fmfil_rds_points, i, fmfil_rds_fir, 0.0001);
964 // *****************************************************************
965 // collect the RDS phase in a leaky integrator of about 0.01 second.
966   rds_f1=pow(0.5,100/baseband_sampling_speed);
967   rds_f2=1-rds_f1;
968   rds_phase=0;
969   rds_power=0;
970   }
971 DEB"\nbaseband_sampling_speed=%f",baseband_sampling_speed);
972 }
973 
update_squelch_buttons(void)974 void update_squelch_buttons(void)
975 {
976 int colour;
977 char s[40];
978 if(bg_filter_points > 5 && 2*bg_filter_points < bg_xpoints)
979   {
980   colour=BG_ACTIVE_BUTTON_COLOR;
981   }
982 else
983   {
984   colour=BG_INACTIVE_BUTTON_COLOR;
985   }
986 settextcolor(colour);
987 sprintf(s,"%2d",bg.squelch_level);
988 show_button(&bgbutt[BG_SQUELCH_LEVEL],s);
989 if(bg.squelch_level == 0)colour=3;
990 settextcolor(colour);
991 sprintf(s,"%d",bg.squelch_time);
992 show_button(&bgbutt[BG_SQUELCH_TIME],s);
993 sprintf(s,"%2d",bg.squelch_point);
994 show_button(&bgbutt[BG_SQUELCH_POINT],s);
995 settextcolor(7);
996 }
997 
998 
make_bg_filter(void)999 void make_bg_filter(void)
1000 {
1001 int i,k,max,mm;
1002 int j, iy;
1003 int ja, jb, m;
1004 float t1,t2,t3,t4;
1005 int ib,ic;
1006 // Set up the filter function in the baseband for
1007 // the main signal and show it on the screen.
1008 // bg.filter_flat is the size of the flat region
1009 // of the filter in Hz (divided by 2)
1010 // bg.filter_curv is the curvature expressed as ten times the distance
1011 // in Hz to the 6dB point from the end of the flat region.
1012 // The filter response is a flat center region with parabolic fall off.
1013 //
1014 // The filter is applied to the fft3 transforms with a symmetric
1015 // function which is flat over 2*bg_flatpoints and falls off over
1016 // bg_curvpoints at each end.
1017 if(flat_xpixel > 0)
1018   {
1019   for(i=bg_ymax; i<=bg_y4; i++)lir_setpixel(flat_xpixel, i,bg_background[i]);
1020   }
1021 if(curv_xpixel > 0)
1022   {
1023   for(i=bg_y4; i<bg_y3; i++)lir_setpixel(curv_xpixel, i,bg_background[i]);
1024   }
1025 if(rx_mode != MODE_FM)
1026   {
1027 // We should not generate frequencies above the Nyquist frequency
1028 // of our output.
1029   max=(float)(fft3_size)*genparm[DA_OUTPUT_SPEED]/(2*timf3_sampling_speed);
1030   if( (ui.network_flag & NET_RXOUT_BASEB) != 0)max*=2;
1031 // We must make bg_filter_points smaller than fft3_size/2.
1032   if(max > MAX_BASEBFILTER_WIDTH*fft3_size/2-2)max=MAX_BASEBFILTER_WIDTH*fft3_size/2-2;
1033   }
1034 else
1035   {
1036   max=MAX_BASEBFILTER_WIDTH*fft3_size/2-2;
1037   }
1038 bg_flatpoints=bg.filter_flat/bg_hz_per_pixel;
1039 if(bg_flatpoints < 1)bg_flatpoints=1;
1040 bg_curvpoints=0.1*bg.filter_curv/bg_hz_per_pixel;
1041 if( genparm[CW_DECODE_ENABLE] != 0)
1042   {
1043   k=bg_xpixels/(2*bg.pixels_per_point)-NOISE_SEP-
1044                                 NOISE_FILTERS*(NOISE_POINTS+NOISE_SEP)-1;
1045   if(max>k)max=k;
1046   k=bg_flatpoints+2*bg_curvpoints-max;
1047   if(k>0)
1048     {
1049     k/=2;
1050     bg_flatpoints-=k;
1051     if(bg_flatpoints<1)bg_flatpoints=1;
1052     bg_curvpoints=(max-bg_flatpoints-1)/2;
1053     if(bg_curvpoints < 0)
1054       {
1055       k=1+2*bg_curvpoints;
1056       bg_flatpoints+=k;
1057       bg_curvpoints=0;
1058       }
1059     }
1060   }
1061 else
1062   {
1063   k=bg_flatpoints+bg_curvpoints-max;
1064   if(k>0)
1065     {
1066     k=(k+1)/2;
1067     bg_flatpoints-=k;
1068     if(bg_flatpoints<1)bg_flatpoints=1;
1069     bg_curvpoints=max-bg_flatpoints-1;
1070     if(bg_curvpoints < 0)
1071       {
1072       bg_flatpoints+=bg_curvpoints;
1073       bg_curvpoints=0;
1074       }
1075     }
1076   }
1077 bg.filter_flat=bg_hz_per_pixel*bg_flatpoints;
1078 bg.filter_curv=10*bg_hz_per_pixel*bg_curvpoints;
1079 bg_curvpoints=0.1*bg.filter_curv/bg_hz_per_pixel;
1080 bg_flatpoints=bg.filter_flat/bg_hz_per_pixel;
1081 if(bg_flatpoints < 1)bg_flatpoints=1;
1082 bgfil_weight=1;
1083 bg_filterfunc[fft3_size/2]=1;
1084 for(i=1; i<bg_flatpoints; i++)
1085   {
1086   bg_filterfunc[fft3_size/2+i]=1;
1087   bg_filterfunc[fft3_size/2-i]=1;
1088   bgfil_weight+=2;
1089   }
1090 bg_filter_points=bg_flatpoints;
1091 if(bg_curvpoints > 0)
1092   {
1093   t1=.5/bg_curvpoints;
1094   t2=1;
1095   t3=t1;
1096   t2=1-t3*t3;
1097   t3+=t1;
1098   while(t2 > 0 && bg_filter_points<fft3_size/2)
1099     {
1100     bg_filterfunc[fft3_size/2+bg_filter_points]=t2;
1101     bg_filterfunc[fft3_size/2-bg_filter_points]=t2;
1102     bgfil_weight+=2*t2*t2;
1103     t2=1-t3*t3;
1104     t3+=t1;
1105     bg_filter_points++;
1106     }
1107   }
1108 for(i=bg_filter_points; i<fft3_size/2; i++)
1109   {
1110   bg_filterfunc[fft3_size/2+i]=0;
1111   bg_filterfunc[fft3_size/2-i]=0;
1112   }
1113 bg_filterfunc[0]=0;
1114 // The filter we just specified determines the bandwidth of
1115 // the signal we recover when backtransforming from fft3.
1116 // Find out by what factor we should reduce the sampling speed
1117 // for further processing
1118 k=bg_filter_points+binshape_points;
1119 k=(0.4*(fft3_size+0.5*k))/k;
1120 make_power_of_two(&k);
1121 if(genparm[CW_DECODE_ENABLE] != 0)k/=2;
1122 if(k > 2)
1123   {
1124   baseband_sampling_speed=2*timf3_sampling_speed/k;
1125   if((int)mix2.size != 2*fft3_size/k ||
1126      (reinit_baseb && mouse_active_flag==0))
1127     {
1128     mix2.size=2*fft3_size/k;
1129     init_basebmem();
1130     baseb_reset_counter++;
1131     }
1132   }
1133 else
1134   {
1135   baseband_sampling_speed=timf3_sampling_speed;
1136   if((int)mix2.size != fft3_size ||
1137      (reinit_baseb && mouse_active_flag==0))
1138     {
1139     mix2.size=fft3_size;
1140     init_basebmem();
1141     baseb_reset_counter++;
1142     }
1143   }
1144 timf1_to_baseband_speed_ratio=rint(timf1_sampling_speed/baseband_sampling_speed);
1145 timf2_blockpower_block=4*ui.rx_rf_channels*timf1_to_baseband_speed_ratio;
1146 if((int)mix2.size>fft3_size)
1147   {
1148   lirerr(88888);
1149   return;
1150   }
1151 carrfil_weight=1;
1152 bg_carrfilter[fft3_size/2]=1;
1153 mm=1;
1154 k=bg.coh_factor;
1155 while(mm < fft3_size/2)
1156   {
1157   if(k<fft3_size/2)
1158     {
1159     t2=bg_filterfunc[fft3_size/2+k];
1160     }
1161   else
1162     {
1163     t2=0;
1164     }
1165   bg_carrfilter[fft3_size/2+mm]=t2;
1166   bg_carrfilter[fft3_size/2-mm]=t2;
1167   carrfil_weight+=2*t2*t2;
1168   mm++;
1169   k+=bg.coh_factor;
1170   }
1171 bg_carrfilter[0]=0;
1172 bg_filtershift_points=bg.filter_shift*(fft3_size/4+8)/999;
1173 // Shift bg_filterfunc as specified by bg_filtershift_points
1174 // But do it only if the mixer mode is back transformation
1175 // and Rx mode is AM
1176 if(bg.mixer_mode == 1 && rx_mode == MODE_AM)
1177   {
1178   if(bg_filtershift_points > 0)
1179     {
1180     k=0;
1181     for(i=bg_filtershift_points; i< fft3_size; i++)
1182       {
1183       bg_filterfunc[k]=bg_filterfunc[i];
1184       k++;
1185       }
1186     while(k < fft3_size)
1187       {
1188       bg_filterfunc[k]=0;
1189       k++;
1190       }
1191     }
1192   if(bg_filtershift_points < 0)
1193     {
1194     k=fft3_size-1;
1195     for(i=fft3_size+bg_filtershift_points; i>=0; i--)
1196       {
1197       bg_filterfunc[k]=bg_filterfunc[i];
1198       k--;
1199       }
1200     while(k >= 0)
1201       {
1202       bg_filterfunc[k]=0;
1203       k--;
1204       }
1205     }
1206   }
1207 // **************************************************************
1208 // Place the current filter function on the screen.
1209 // First remove any curve that may exist on the screen.
1210 for(i=bg_first_xpixel; i<=bg_last_xpixel; i+=bg.pixels_per_point)
1211   {
1212   if(bg_filterfunc_y[i] < bg.ybottom && bg_filterfunc_y[i] >bg_ymax-2)
1213     {
1214     lir_setpixel(i,bg_filterfunc_y[i],bg_background[bg_filterfunc_y[i]]);
1215     }
1216   if(bg_carrfilter_y[i] < bg.ybottom && bg_carrfilter_y[i] >bg_ymax-2)
1217     {
1218     lir_setpixel(i,bg_carrfilter_y[i],bg_background[bg_carrfilter_y[i]]);
1219     }
1220   }
1221 // Slide the bin filter shape over our carrier filter and accumulate
1222 // to take the widening due to the fft window into account.
1223 for(i=0; i<fft3_size; i++)
1224   {
1225   ja=i-fft3_size/2;
1226   jb=i+fft3_size/2;
1227   m=0;
1228   if(ja<0)
1229     {
1230     m=-ja;
1231     ja=0;
1232     }
1233   j=(fft3_size/2-binshape_total)-m;
1234   if(j>0)
1235     {
1236     ja+=j;
1237     m+=j;
1238     }
1239   if(jb > fft3_size)jb=fft3_size;
1240   if(jb-ja > 2*binshape_total+1)jb=ja+2*binshape_total+1;
1241   t1=0;
1242   for(j=ja; j<jb; j++)
1243     {
1244     t1+=bg_carrfilter[j]*bg_binshape[m];
1245     m++;
1246     }
1247   bg_ytmp[i]=t1;
1248   }
1249 if(fft3_size > 16384)lir_sched_yield();
1250 t1=0;
1251 for(i=0; i<fft3_size; i++)
1252   {
1253   if(bg_ytmp[i]>t1)t1=bg_ytmp[i];
1254   }
1255 for(i=0; i<fft3_size; i++)
1256   {
1257   bg_ytmp[i]/=t1;
1258   }
1259 j=bg_first_xpoint;
1260 for(i=bg_first_xpixel; i<=bg_last_xpixel; i+=bg.pixels_per_point)
1261   {
1262   if(bg_ytmp[j] > 0.000000001)
1263     {
1264     iy=2*bg.yfac_log*log10(1./bg_ytmp[j]);
1265     iy=bg_ymax-1+iy;
1266     if(iy>bg_y0)iy=bg_y0+1;
1267     lir_setpixel(i,iy,58);
1268     }
1269   else
1270     {
1271     iy=-1;
1272     }
1273   bg_carrfilter_y[i]=iy;
1274   j++;
1275   }
1276 if(bg.mixer_mode == 1)
1277   {
1278   for(i=0; i<bg_no_of_notches; i++)
1279     {
1280     j=fft3_size/2-bg_notch_pos[i]*bg_filter_points/1000;
1281     k=bg_notch_width[i]*bg_filter_points/1000;
1282     ja=j-k;
1283     jb=j+k;
1284     if(ja < 0)ja=0;
1285     if(jb >= fft3_size)jb=fft3_size-1;
1286     for(j=ja; j<=jb; j++)
1287       {
1288       bg_filterfunc[j]=0;
1289       }
1290     }
1291   }
1292 // Slide the bin filter shape over our filter function and accumulate
1293 // to take the widening due to the fft window into account.
1294 for(i=0; i<fft3_size; i++)
1295   {
1296   ja=i-fft3_size/2;
1297   jb=i+fft3_size/2;
1298   m=0;
1299   if(ja<0)
1300     {
1301     m=-ja;
1302     ja=0;
1303     }
1304   j=(fft3_size/2-binshape_total)-m;
1305   if(j>0)
1306     {
1307     ja+=j;
1308     m+=j;
1309     }
1310   if(jb > fft3_size)jb=fft3_size;
1311   if(jb-ja > 2*binshape_total+1)jb=ja+2*binshape_total+1;
1312   t1=0;
1313   for(j=ja; j<jb; j++)
1314     {
1315     t1+=bg_filterfunc[j]*bg_binshape[m];
1316     m++;
1317     }
1318   bg_ytmp[i]=t1;
1319   }
1320 t1=0;
1321 for(i=0; i<fft3_size; i++)
1322   {
1323   if(bg_ytmp[i]>t1)t1=bg_ytmp[i];
1324   }
1325 for(i=0; i<fft3_size; i++)
1326   {
1327   bg_ytmp[i]/=t1;
1328   }
1329 bg_120db_points=fft3_size;
1330 while(bg_ytmp[bg_120db_points-1] < 0.000001 &&
1331                                       bg_120db_points >0)bg_120db_points--;
1332 bg_60db_points=bg_120db_points;
1333 while(bg_ytmp[bg_60db_points-1] < 0.001 &&
1334                                         bg_60db_points >0)bg_60db_points--;
1335 bg_6db_points=bg_60db_points;
1336 while(bg_ytmp[bg_6db_points-1] < 0.5 && bg_6db_points >0)bg_6db_points--;
1337 if(bg_6db_points == 0)
1338   {
1339   lirerr(287553);
1340   return;
1341   }
1342 i=0;
1343 while(bg_ytmp[i+1] < 0.000001)i++;
1344 bg_120db_points-=i;
1345 while(bg_ytmp[i+1] < 0.001)i++;
1346 bg_60db_points-=i;
1347 while(bg_ytmp[i+1] < 0.5)i++;
1348 bg_6db_points-=i;
1349 baseband_bw_hz=bg_6db_points*bg_hz_per_pixel;
1350 baseband_bw_fftxpts=baseband_bw_hz*fftx_points_per_hz;
1351 j=bg_first_xpoint;
1352 for(i=bg_first_xpixel; i<=bg_last_xpixel; i+=bg.pixels_per_point)
1353   {
1354   if(j>0 && j<fft3_size && bg_ytmp[j] > 0.000000001)
1355     {
1356     iy=2*bg.yfac_log*log10(1./bg_ytmp[j]);
1357     iy=bg_ymax-1+iy;
1358     if(iy>bg_y0)iy=bg_y0+1;
1359     lir_setpixel(i,iy,14);
1360     }
1361   else
1362     {
1363     iy=-1;
1364     }
1365   bg_filterfunc_y[i]=iy;
1366   j++;
1367   }
1368 // We apply a filter in the frequency domain when picking a subset
1369 // of fft1 or fft2 for back-transformation.
1370 // That filter, mix1_fqwin, affects our frequency response when wide
1371 // filters are used. Compensate for mix1_fqwin by multiplying with
1372 // its inverse in fft3 points.
1373 for(i=0; i<fft3_size;i++)bg_filterfunc[i]*=sqrt(fft3_fqwin_inv[i]);
1374 // Construct a FIR filter of size fft3 with a frequency response like the
1375 // baseband filter we have set up.
1376 // The array of FIR filter coefficients is the pulse response of a FIR
1377 // filter. Get it by taking the FFT.
1378 // Since we use a complex FFT we can use the real side for the
1379 // baseband filter and the imaginary part for the carrier filter.
1380 fft3_tmp[0]=1;
1381 fft3_tmp[1]=1;
1382 i=fft3_size/2+1;
1383 jb=fft3_size-1;
1384 for(ja=1; ja<fft3_size/2; ja++)
1385   {
1386   fft3_tmp[2*ja  ]=bg_filterfunc[i];
1387   fft3_tmp[2*jb  ]=bg_filterfunc[i];
1388   fft3_tmp[2*ja+1]=bg_carrfilter[i];
1389   fft3_tmp[2*jb+1]=bg_carrfilter[i];
1390   i++;
1391   jb--;
1392   }
1393 fft3_tmp[2*jb  ]=0;
1394 fft3_tmp[2*jb+1]=0;
1395 for( i=0; i<fft3_size/2; i++)
1396   {
1397   t1=fft3_tmp[2*i  ];
1398   t2=fft3_tmp[fft3_size+2*i  ];
1399   t3=fft3_tmp[2*i+1];
1400   t4=fft3_tmp[fft3_size+2*i+1];
1401   fft3_tmp[2*i  ]=t1+t2;
1402   fft3_tmp[2*i+1]=t3+t4;
1403   fft3_tmp[fft3_size+2*i  ]=fft3_tab[i].cos*(t1-t2)+fft3_tab[i].sin*(t4-t3);
1404   fft3_tmp[fft3_size+2*i+1]=fft3_tab[i].sin*(t1-t2)-fft3_tab[i].cos*(t4-t3);
1405   }
1406 if(fft3_size > 2*8192)lir_sched_yield();
1407 #if IA64 == 0 && CPU == CPU_INTEL
1408 asmbulk_of_dif(fft3_size, fft3_n, fft3_tmp, fft3_tab, yieldflag_ndsp_fft3);
1409 #else
1410 bulk_of_dif(fft3_size, fft3_n, fft3_tmp, fft3_tab, yieldflag_ndsp_fft3);
1411 #endif
1412 if(fft3_size > 8192)lir_sched_yield();
1413 for(i=0; i < fft3_size; i+=2)
1414   {
1415   ib=fft3_permute[i];
1416   ic=fft3_permute[i+1];
1417   basebraw_fir[ib]=fft3_tmp[2*i  ]+fft3_tmp[2*i+2];
1418   basebraw_fir[ic]=fft3_tmp[2*i  ]-fft3_tmp[2*i+2];
1419   basebcarr_fir[ib]=fft3_tmp[2*i+1]+fft3_tmp[2*i+3];
1420   basebcarr_fir[ic]=fft3_tmp[2*i+1]-fft3_tmp[2*i+3];
1421   }
1422 // Now take the effects of our window into account.
1423 // Note the order in which fft3_window is stored.
1424 for(i=0; i<fft3_size/2; i++)
1425   {
1426   basebraw_fir[i]*=fft3_window[2*i];
1427   basebcarr_fir[i]*=fft3_window[2*i];
1428   basebraw_fir[fft3_size/2+i]*=fft3_window[2*i+1];
1429   basebcarr_fir[fft3_size/2+i]*=fft3_window[2*i+1];
1430   }
1431 // The FIR filter must be symmetric. Actually forcing symmetry
1432 // might reduce rounding errors slightly.
1433 for(i=1; i<fft3_size/2; i++)
1434   {
1435   basebraw_fir[i]=0.5*(basebraw_fir[i]+basebraw_fir[fft3_size-i]);
1436   basebcarr_fir[i]=0.5*(basebcarr_fir[i]+basebcarr_fir[fft3_size-i]);
1437   basebraw_fir[fft3_size-i]=basebraw_fir[i];
1438   basebcarr_fir[fft3_size-i]=basebcarr_fir[i];
1439   }
1440 // The fft1 algorithms use float variables with 24 bit accuracy.
1441 // the associated spur level is -140 dB.
1442 // There is no reason to make the FIR filter extend outside
1443 // the range where the coefficients are below -150 dB.
1444 t1=0.00000003*basebraw_fir[fft3_size/2];
1445 k=0;
1446 while(fabs(basebraw_fir[k]) < t1)
1447   {
1448   k++;
1449   }
1450 j=k;
1451 basebraw_fir_pts=0;
1452 while(k <= fft3_size-j-1)
1453   {
1454   basebraw_fir[basebraw_fir_pts]=basebraw_fir[k];
1455   k++;
1456   basebraw_fir_pts++;
1457   }
1458 k=basebraw_fir_pts;
1459 memset(&basebraw_fir[k],0,(fft3_size-k)*sizeof(float));
1460 // Normalize the FIR filter so it gives the same amplitude as we have
1461 // with the back transformation of fft3 in mix2.
1462 t1=0;
1463 for(i=0; i<basebraw_fir_pts; i++)
1464   {
1465   t1+=basebraw_fir[i];
1466   }
1467 t1=2.65*fft3_size/t1;
1468 for(i=0; i<basebraw_fir_pts; i++)
1469   {
1470   basebraw_fir[i]*=t1;
1471   }
1472 t1=0.00000003*basebcarr_fir[fft3_size/2];
1473 k=0;
1474 while(fabs(basebcarr_fir[k]) < t1)k++;
1475 j=k;
1476 basebcarr_fir_pts=0;
1477 while(k<fft3_size-j-1)
1478   {
1479   basebcarr_fir[basebcarr_fir_pts]=basebcarr_fir[k];
1480   k++;
1481   basebcarr_fir_pts++;
1482   }
1483 k=basebcarr_fir_pts;
1484 memset(&basebcarr_fir[k],0,(fft3_size-k)*sizeof(float));
1485 // Normalize the FIR filter so it gives the same amplitude as we have
1486 // with the back transformation of fft3 in mix2.
1487 t1=0;
1488 for(i=0; i<basebcarr_fir_pts; i++)
1489   {
1490   t1+=basebcarr_fir[i];
1491   }
1492 t1=2.65*fft3_size/t1;
1493 for(i=0; i<basebcarr_fir_pts; i++)
1494   {
1495   basebcarr_fir[i]*=t1;
1496   }
1497 if(fft3_size > 4096)lir_sched_yield();
1498 flat_xpixel=filcur_pixel(bg_flatpoints);
1499 lir_line(flat_xpixel, bg_ymax,flat_xpixel,bg_y4-1,14);
1500 curv_xpixel=filcur_pixel(bg_curvpoints);
1501 lir_line(curv_xpixel, bg_y4,curv_xpixel,bg_y3-1,14);
1502 da_resample_ratio=genparm[DA_OUTPUT_SPEED]/baseband_sampling_speed;
1503 make_new_daout_upsamp();
1504 // Place the BFO line on the screen and make bfo related stuff.
1505 make_bfo();
1506 // Set up a 5th order IIR low pass filter to apply after the
1507 // fractional resampler in make_audio_signal (rxout.c)
1508 // The resampler produces aliases that this filter will remove.
1509 t1=0.25*(bg_60db_points+bg_6db_points)*daout_upsamp*
1510                                bg_hz_per_pixel/genparm[DA_OUTPUT_SPEED];
1511 if(t1 > 0.25)
1512   {
1513   enable_resamp_iir5=FALSE;
1514   }
1515 else
1516   {
1517   if(t1<0.011)t1=0.011;
1518   make_iir5(t1, &iir_a);
1519   for(i=0; i<6; i++)
1520     {
1521     xva1[i]=0;
1522     yva1[i]=0;
1523     xvb1[i]=0;
1524     yvb1[i]=0;
1525     xva2[i]=0;
1526     yva2[i]=0;
1527     xvb2[i]=0;
1528     yvb2[i]=0;
1529     }
1530   enable_resamp_iir5=TRUE;
1531   }
1532 out1=0;
1533 out2=0;
1534 out3=0;
1535 out4=0;
1536 for(i=0; i<4; i++)
1537   {
1538   xv1[i]=0;
1539   yv1[i]=0;
1540   xv2[i]=0;
1541   yv2[i]=0;
1542   xv3[i]=0;
1543   yv3[i]=0;
1544   xv4[i]=0;
1545   yv4[i]=0;
1546   }
1547 update_squelch_buttons();
1548 }
1549 
check_bg_cohfac(void)1550 void check_bg_cohfac(void)
1551 {
1552 int j;
1553 j=0.8*bg_6db_points;
1554 if(j>9999)j=9999;
1555 if(bg.coh_factor > j)bg.coh_factor=j;
1556 if(use_bfo != 0)
1557   {
1558   if(bg.coh_factor < 3)bg.coh_factor=3;
1559   }
1560 else
1561   {
1562   if(bg.coh_factor < 1)bg.coh_factor=1;
1563   }
1564 }
1565 
check_bg_fm_audio_bw(void)1566 void check_bg_fm_audio_bw(void)
1567 {
1568 if(bg.fm_audio_bw < 1)bg.fm_audio_bw=1;
1569 if(bg.fm_audio_bw > 96)bg.fm_audio_bw=96;
1570 if(bg.fm_audio_bw > genparm[DA_OUTPUT_SPEED]/1990.)
1571   {
1572   bg.fm_audio_bw=0.8*genparm[DA_OUTPUT_SPEED]/2000.;
1573   }
1574 if( baseband_sampling_speed > genparm[DA_OUTPUT_SPEED] &&
1575           bg.fm_audio_bw>0.8*genparm[DA_OUTPUT_SPEED]/1990.)
1576   {
1577   bg.fm_audio_bw=0.8*genparm[DA_OUTPUT_SPEED]/2000.;
1578   }
1579 }
1580 
new_bg_cohfac(void)1581 void new_bg_cohfac(void)
1582 {
1583 bg.coh_factor=numinput_int_data;
1584 check_bg_cohfac();
1585 init_baseband_sizes();
1586 make_baseband_graph(TRUE);
1587 }
1588 
new_bg_fm_audio_bw(void)1589 void new_bg_fm_audio_bw(void)
1590 {
1591 bg.fm_audio_bw=numinput_int_data;
1592 check_bg_fm_audio_bw();
1593 init_baseband_sizes();
1594 make_baseband_graph(TRUE);
1595 }
1596 
new_bg_filter_shift(void)1597 void new_bg_filter_shift(void)
1598 {
1599 int i;
1600 i=numinput_int_data;
1601 // i has to be between -999 and 9999 because we allocate 4 characters
1602 // for this parameter button.
1603 if(i > 999)i=999;
1604 bg.filter_shift=i;
1605 make_baseband_graph(TRUE);
1606 }
1607 
new_bg_delpnts(void)1608 void new_bg_delpnts(void)
1609 {
1610 bg.delay_points=numinput_int_data;
1611 if(bg.delay_points < 1)bg.delay_points=1;
1612 if(bg.delay_points > 999)bg.delay_points=999;
1613 sc[SC_BG_BUTTONS]++;
1614 }
1615 
1616 
new_bg_agc_attack(void)1617 void new_bg_agc_attack(void)
1618 {
1619 bg.agc_attack=numinput_int_data;
1620 sc[SC_BG_BUTTONS]++;
1621 make_modepar_file(GRAPHTYPE_BG);
1622 clear_agc();
1623 }
1624 
new_bg_agc_release(void)1625 void new_bg_agc_release(void)
1626 {
1627 bg.agc_release=numinput_int_data;
1628 am_dclevel_factor1=pow(0.5,2000./(baseband_sampling_speed*(1<<bg.agc_release)));
1629 am_dclevel_factor2=1-am_dclevel_factor1;
1630 sc[SC_BG_BUTTONS]++;
1631 make_modepar_file(GRAPHTYPE_BG);
1632 clear_agc();
1633 }
1634 
new_bg_agc_hang(void)1635 void new_bg_agc_hang(void)
1636 {
1637 bg.agc_hang=numinput_int_data;
1638 sc[SC_BG_BUTTONS]++;
1639 make_modepar_file(GRAPHTYPE_BG);
1640 clear_agc();
1641 }
1642 
new_bg_waterfall_gain(void)1643 void new_bg_waterfall_gain(void)
1644 {
1645 bg.waterfall_gain=numinput_float_data;
1646 sc[SC_BG_BUTTONS]++;
1647 make_bg_waterf_cfac();
1648 make_modepar_file(GRAPHTYPE_BG);
1649 sc[SC_BG_WATERF_REDRAW]++;
1650 }
1651 
new_bg_waterfall_zero(void)1652 void new_bg_waterfall_zero(void)
1653 {
1654 bg.waterfall_zero=numinput_float_data;
1655 sc[SC_BG_BUTTONS]++;
1656 make_bg_waterf_cfac();
1657 make_modepar_file(GRAPHTYPE_BG);
1658 sc[SC_BG_WATERF_REDRAW]++;
1659 }
1660 
help_on_baseband_graph(void)1661 void help_on_baseband_graph(void)
1662 {
1663 int msg_no;
1664 int event_no;
1665 // Set msg invalid in case we are not in any select area.
1666 msg_no=-1;
1667 if(mouse_y < bg_y0)
1668   {
1669   if(mouse_x < bg_first_xpixel)
1670     {
1671     if(mouse_x >= bg_vol_x1 &&
1672        mouse_x <= bg_vol_x2 &&
1673        mouse_y >= bg_ymax)
1674       {
1675       msg_no=33;
1676       }
1677     }
1678   else
1679     {
1680     if(mouse_x < bg.xright-text_width-6)
1681       {
1682       msg_no=34;
1683       }
1684     }
1685   }
1686 for(event_no=0; event_no<MAX_BGBUTT; event_no++)
1687   {
1688   if( bgbutt[event_no].x1 <= mouse_x &&
1689       bgbutt[event_no].x2 >= mouse_x &&
1690       bgbutt[event_no].y1 <= mouse_y &&
1691       bgbutt[event_no].y2 >= mouse_y)
1692     {
1693     switch (event_no)
1694       {
1695       case BG_TOP:
1696       case BG_BOTTOM:
1697       case BG_LEFT:
1698       case BG_RIGHT:
1699       case BG_YBORDER:
1700       msg_no=100;
1701       break;
1702 
1703       case BG_YSCALE_EXPAND:
1704       msg_no=35;
1705       break;
1706 
1707       case BG_YSCALE_CONTRACT:
1708       msg_no=36;
1709       break;
1710 
1711       case BG_YZERO_DECREASE:
1712       msg_no=37;
1713       break;
1714 
1715       case BG_YZERO_INCREASE:
1716       msg_no=38;
1717       break;
1718 
1719       case BG_RESOLUTION_DECREASE:
1720       msg_no=39;
1721       break;
1722 
1723       case BG_RESOLUTION_INCREASE:
1724       msg_no=40;
1725       break;
1726 
1727       case BG_OSCILLOSCOPE:
1728       msg_no=41;
1729       break;
1730 
1731       case BG_OSC_INCREASE:
1732       msg_no=42;
1733       break;
1734 
1735       case BG_OSC_DECREASE:
1736       msg_no=43;
1737       break;
1738 
1739       case BG_PIX_PER_PNT_INC:
1740       msg_no=44;
1741       break;
1742 
1743       case BG_PIX_PER_PNT_DEC:
1744       msg_no=45;
1745       break;
1746 
1747       case BG_TOGGLE_EXPANDER:
1748       msg_no=46;
1749       break;
1750 
1751       case  BG_TOGGLE_COHERENT:
1752       msg_no=47;
1753       break;
1754 
1755       case  BG_TOGGLE_PHASING:
1756       msg_no=48;
1757       break;
1758 
1759       case BG_TOGGLE_TWOPOL:
1760       msg_no=49;
1761       break;
1762 
1763       case  BG_TOGGLE_CHANNELS:
1764       msg_no=50;
1765       break;
1766 
1767       case BG_TOGGLE_CH2_PHASE:
1768       msg_no=328;
1769       break;
1770 
1771       case  BG_TOGGLE_BYTES:
1772       msg_no=51;
1773       break;
1774 
1775       case BG_SEL_COHFAC:
1776       msg_no=52;
1777       break;
1778 
1779       case BG_SEL_DELPNTS:
1780       msg_no=53;
1781       break;
1782 
1783       case BG_SEL_FFT3AVGNUM:
1784       msg_no=63;
1785       break;
1786 
1787       case BG_WATERF_AVGNUM:
1788       msg_no=61;
1789       break;
1790 
1791       case BG_SEL_AGC_ATTACK:
1792       msg_no=80;
1793       break;
1794 
1795       case BG_TOGGLE_AGC:
1796       msg_no=79;
1797       break;
1798 
1799       case BG_SEL_AGC_RELEASE:
1800       msg_no=81;
1801       break;
1802 
1803       case BG_SEL_AGC_HANG:
1804       msg_no=331;
1805       break;
1806 
1807       case BG_WATERF_ZERO:
1808       msg_no=64;
1809       break;
1810 
1811       case BG_WATERF_GAIN:
1812       msg_no=66;
1813       break;
1814 
1815       case BG_HORIZ_ARROW_MODE:
1816       msg_no=319;
1817       break;
1818 
1819       case BG_MIXER_MODE:
1820       msg_no=88;
1821       break;
1822 
1823       case BG_FILTER_SHIFT:
1824       msg_no=329;
1825       break;
1826 
1827       case BG_NOTCH_NO:
1828       msg_no=320;
1829       break;
1830 
1831       case BG_NOTCH_WIDTH:
1832       msg_no=321;
1833       break;
1834 
1835       case BG_NOTCH_POS:
1836       msg_no=322;
1837       break;
1838 
1839       case BG_TOGGLE_FM_MODE:
1840       msg_no=326;
1841       break;
1842 
1843       case BG_TOGGLE_FM_SUBTRACT:
1844       msg_no=330;
1845       break;
1846 
1847       case BG_SEL_FM_AUDIO_BW:
1848       msg_no=327;
1849       break;
1850 
1851       case BG_SQUELCH_LEVEL:
1852       msg_no=336;
1853       break;
1854 
1855       case BG_SQUELCH_TIME:
1856       msg_no=338;
1857       break;
1858 
1859       case BG_SQUELCH_POINT:
1860       msg_no=337;
1861       break;
1862 
1863       }
1864     }
1865   }
1866 help_message(msg_no);
1867 }
1868 
change_fft3_avgnum(void)1869 void change_fft3_avgnum(void)
1870 {
1871 int j,k;
1872 bg.fft_avgnum=numinput_int_data;
1873 chk_bg_avgnum();
1874 make_modepar_file(GRAPHTYPE_BG);
1875 if(sw_onechan)
1876   {
1877   for(k=bg_first_xpixel; k<=bg_last_xpixel; k++)
1878     {
1879     lir_setpixel(k,fft3_spectrum[k],bg_background[fft3_spectrum[k]]);
1880     fft3_spectrum[k]=bg_y0;
1881     }
1882   }
1883 else
1884   {
1885   for(k=bg_first_xpixel; k<=bg_last_xpixel; k++)
1886     {
1887     for(j=2*k; j<2*k+2; j++)
1888       {
1889       lir_setpixel(k,fft3_spectrum[j],bg_background[fft3_spectrum[j]]);
1890       fft3_spectrum[j]=bg_y0;
1891       }
1892     }
1893   }
1894 init_baseband_sizes();
1895 make_baseband_graph(TRUE);
1896 }
1897 
1898 
1899 
change_bg_waterf_avgnum(void)1900 void change_bg_waterf_avgnum(void)
1901 {
1902 bg.waterfall_avgnum=numinput_int_data;
1903 make_modepar_file(GRAPHTYPE_BG);
1904 make_bg_yfac();
1905 sc[SC_BG_BUTTONS]++;
1906 }
1907 
make_agc_amplimit(void)1908 void make_agc_amplimit(void)
1909 {
1910 bg_agc_amplimit=bg_amplimit*0.18;
1911 if(rx_mode==MODE_AM)
1912   {
1913   bg_agc_amplimit*=1.2;
1914   if(bg_coherent != 0) bg_agc_amplimit*=.75;
1915   }
1916 }
1917 
new_bg_no_of_notches(void)1918 void new_bg_no_of_notches(void)
1919 {
1920 if(numinput_int_data > bg_no_of_notches)
1921   {
1922   if(bg_no_of_notches < MAX_BG_NOTCHES)
1923     {
1924     bg_notch_pos[bg_no_of_notches]=0;
1925     bg_notch_width[bg_no_of_notches]=0;
1926     bg_no_of_notches++;
1927     }
1928   }
1929 bg_current_notch=numinput_int_data;
1930 if(bg_current_notch > bg_no_of_notches)bg_current_notch=bg_no_of_notches;
1931 if(bg_current_notch <= 0)
1932   {
1933   bg_current_notch=0;
1934   bg_no_of_notches=0;
1935   }
1936 //sc[SC_BG_BUTTONS]++;
1937 make_baseband_graph(TRUE);
1938 }
1939 
new_bg_notch_width(void)1940 void new_bg_notch_width(void)
1941 {
1942 int i;
1943 if(bg_current_notch > 0)
1944   {
1945   if(numinput_int_data < 0)
1946     {
1947     if(bg_no_of_notches > 0)
1948       {
1949       i=bg_current_notch-1;
1950       while(i+1 < bg_no_of_notches)
1951         {
1952         bg_notch_pos[i]=bg_notch_pos[i+1];
1953         bg_notch_width[i]=bg_notch_width[i+1];
1954         i++;
1955         }
1956       bg_no_of_notches--;
1957       }
1958     }
1959   else
1960     {
1961     bg_notch_width[bg_current_notch-1]=numinput_int_data;
1962     }
1963   }
1964 //sc[SC_BG_BUTTONS]++;
1965 make_baseband_graph(TRUE);
1966 }
1967 
1968 
new_bg_notch_pos(void)1969 void new_bg_notch_pos(void)
1970 {
1971 if(bg_current_notch > 0)
1972   {
1973   bg_notch_pos[bg_current_notch-1]=numinput_int_data;
1974   if(bg_notch_pos[bg_current_notch-1] > 999)
1975                                   bg_notch_pos[bg_current_notch-1]=999;
1976   }
1977 //sc[SC_BG_BUTTONS]++;
1978 make_baseband_graph(TRUE);
1979 }
1980 
new_bg_squelch_point(void)1981 void new_bg_squelch_point(void)
1982 {
1983 bg.squelch_point=numinput_int_data;
1984 if(bg.squelch_point < 0)bg.squelch_point=0;
1985 make_modepar_file(GRAPHTYPE_BG);
1986 update_squelch_buttons();
1987 }
1988 
new_bg_squelch_time(void)1989 void new_bg_squelch_time(void)
1990 {
1991 bg.squelch_time=numinput_int_data;
1992 make_modepar_file(GRAPHTYPE_BG);
1993 update_squelch_buttons();
1994 }
1995 
new_bg_squelch_level(void)1996 void new_bg_squelch_level(void)
1997 {
1998 bg.squelch_level=numinput_int_data;
1999 if(bg.squelch_level < 0)bg.squelch_level=0;
2000 make_modepar_file(GRAPHTYPE_BG);
2001 update_squelch_buttons();
2002 }
2003 
mouse_continue_baseband_graph(void)2004 void mouse_continue_baseband_graph(void)
2005 {
2006 int j;
2007 switch (mouse_active_flag-1)
2008   {
2009   case BG_TOP:
2010   if(bg.ytop!=mouse_y)
2011     {
2012     pause_screen_and_hide_mouse();
2013     dual_graph_borders((void*)&bg,0);
2014     bg.ytop=mouse_y;
2015     j=bg.ybottom-BG_MINYCHAR*text_height;
2016     if(bg.ytop > j)bg.ytop=j;
2017     if(bg_old_y1 > bg.ytop)bg_old_y1=bg.ytop;
2018     dual_graph_borders((void*)&bg,15);
2019     resume_thread(THREAD_SCREEN);
2020     }
2021   break;
2022 
2023   case BG_BOTTOM:
2024   if(bg.ybottom!=mouse_y)
2025     {
2026     pause_screen_and_hide_mouse();
2027     dual_graph_borders((void*)&bg,0);
2028     bg.ybottom=mouse_y;
2029     j=bg.yborder+BG_MINYCHAR*text_height;
2030     if(bg.ybottom < j)bg.ybottom=j;
2031     if(bg.ybottom >= screen_height)bg.ybottom=screen_height-1;
2032     if(bg_old_y2 < bg.ybottom)bg_old_y2=bg.ybottom;
2033     dual_graph_borders((void*)&bg,15);
2034     resume_thread(THREAD_SCREEN);
2035     }
2036   break;
2037 
2038   case BG_LEFT:
2039   if(bg.xleft!=mouse_x)
2040     {
2041     pause_screen_and_hide_mouse();
2042     dual_graph_borders((void*)&bg,0);
2043     bg.xleft=mouse_x;
2044     j=bg.xright-BG_MIN_WIDTH;
2045     if(j<0)j=0;
2046     if(bg.xleft > j)bg.xleft=j;
2047     if(bg_old_x1 > bg.xleft)bg_old_x1=bg.xleft;
2048     dual_graph_borders((void*)&bg,15);
2049     resume_thread(THREAD_SCREEN);
2050     }
2051   break;
2052 
2053   case BG_RIGHT:
2054   if(bg.xright!=mouse_x)
2055     {
2056     pause_screen_and_hide_mouse();
2057     dual_graph_borders((void*)&bg,0);
2058     bg.xright=mouse_x;
2059     j=bg.xleft+BG_MIN_WIDTH;
2060     if(j>=screen_width)j=screen_width-1;
2061     if(bg.xright < j)bg.xright=j;
2062     if(bg_old_x2 < bg.xright)bg_old_x2=bg.xright;
2063     dual_graph_borders((void*)&bg,15);
2064     resume_thread(THREAD_SCREEN);
2065     }
2066   break;
2067 
2068   case BG_YBORDER:
2069   if(bg.yborder!=mouse_y)
2070     {
2071     pause_screen_and_hide_mouse();
2072     dual_graph_borders((void*)&bg,0);
2073     bg.yborder=mouse_y;
2074     if(bg.yborder < bg_yborder_min)bg.yborder = bg_yborder_min;
2075     if(bg.yborder > bg_yborder_max)bg.yborder = bg_yborder_max;
2076     dual_graph_borders((void*)&bg,15);
2077     resume_thread(THREAD_SCREEN);
2078     }
2079   break;
2080 
2081   default:
2082   goto await_release;
2083   }
2084 if(leftpressed == BUTTON_RELEASED)goto finish;
2085 return;
2086 await_release:;
2087 if(leftpressed != BUTTON_RELEASED) return;
2088 switch (mouse_active_flag-1)
2089   {
2090   case BG_YSCALE_EXPAND:
2091   bg.yrange/=1.5;
2092   break;
2093 
2094   case BG_YSCALE_CONTRACT:
2095   bg.yrange*=1.5;
2096   break;
2097 
2098   case BG_YZERO_DECREASE:
2099   bg.yzero/=1.5;
2100   break;
2101 
2102   case BG_YZERO_INCREASE:
2103   bg.yzero*=1.5;
2104   break;
2105 
2106   case BG_RESOLUTION_DECREASE:
2107   bg.bandwidth/=2;
2108   reinit_baseb=TRUE;
2109   break;
2110 
2111   case BG_RESOLUTION_INCREASE:
2112   bg.bandwidth*=2;
2113   reinit_baseb=TRUE;
2114   break;
2115 
2116   case BG_OSCILLOSCOPE:
2117   if(ui.operator_skil == OPERATOR_SKIL_EXPERT)
2118     {
2119     bg.oscill_on^=1;
2120     }
2121   break;
2122 
2123   case BG_OSC_INCREASE:
2124   if(bg.oscill_on != 0)
2125     {
2126     bg.oscill_gain*=5;
2127     }
2128   break;
2129 
2130   case BG_OSC_DECREASE:
2131   if(bg.oscill_on != 0)
2132     {
2133     bg.oscill_gain*=0.25;
2134     }
2135   break;
2136 
2137   case BG_PIX_PER_PNT_INC:
2138   bg.pixels_per_point++;
2139   if(bg.pixels_per_point > 16)bg.pixels_per_point=16;
2140   break;
2141 
2142   case BG_PIX_PER_PNT_DEC:
2143   bg.pixels_per_point--;
2144   if(bg.pixels_per_point < 1)bg.pixels_per_point=1;
2145   break;
2146 
2147   case BG_TOGGLE_EXPANDER:
2148   bg_expand++;
2149   if(bg_expand > 2)bg_expand=0;
2150   break;
2151 
2152   case  BG_TOGGLE_COHERENT:
2153   if(bg_twopol == 0 && bg_delay == 0)
2154     {
2155     new_bg_coherent=bg_coherent+1;
2156     }
2157   break;
2158 
2159   case  BG_TOGGLE_PHASING:
2160   if(bg_coherent == 0)
2161     {
2162     new_bg_twopol=0;
2163     new_bg_delay=(bg_delay^1)&1;
2164     if(new_bg_delay == 0)new_daout_channels=1+((genparm[OUTPUT_MODE]>>1)&1);
2165     }
2166   break;
2167 
2168   case BG_TOGGLE_TWOPOL:
2169   if(bg_coherent == 0)
2170     {
2171     new_bg_delay=0;
2172     new_bg_twopol=(bg_twopol^1)&1;
2173     if(new_bg_twopol == 0)new_daout_channels=1+((genparm[OUTPUT_MODE]>>1)&1);
2174     }
2175   break;
2176 
2177   case  BG_TOGGLE_CHANNELS:
2178   new_daout_channels=rx_daout_channels+1;
2179   if(new_daout_channels>ui.rx_max_da_channels)
2180                                      new_daout_channels=ui.rx_min_da_channels;
2181   break;
2182 
2183   case BG_TOGGLE_CH2_PHASE:
2184   if(  baseb_channels == 1  &&
2185        rx_daout_channels == 2  &&
2186        bg_delay == 0 &&
2187        bg_twopol == 0)
2188     {
2189     new_bg_ch2_phase=bg.ch2_phase+1;
2190     }
2191   break;
2192 
2193   case  BG_TOGGLE_BYTES:
2194   new_daout_bytes=rx_daout_bytes+1;
2195   if(new_daout_bytes>ui.rx_max_da_bytes)new_daout_bytes=ui.rx_min_da_bytes;
2196   break;
2197 
2198   case BG_TOGGLE_AGC:
2199   if(genparm[CW_DECODE_ENABLE] == 0)
2200     {
2201     new_bg_agc_flag=bg.agc_flag+1;
2202     }
2203   break;
2204 
2205   case BG_SEL_COHFAC:
2206   mouse_active_flag=1;
2207   numinput_xpix=bgbutt[BG_SEL_COHFAC].x1+7*text_width/2-1;
2208   numinput_ypix=bgbutt[BG_SEL_COHFAC].y1+2;
2209   numinput_chars=4;
2210   erase_numinput_txt();
2211   numinput_flag=FIXED_INT_PARM;
2212   par_from_keyboard_routine=new_bg_cohfac;
2213   return;
2214 
2215   case BG_SEL_DELPNTS:
2216   mouse_active_flag=1;
2217   numinput_xpix=bgbutt[BG_SEL_DELPNTS].x1+3*text_width/2-1;
2218   numinput_ypix=bgbutt[BG_SEL_DELPNTS].y1+2;
2219   numinput_chars=2;
2220   erase_numinput_txt();
2221   numinput_flag=FIXED_INT_PARM;
2222   par_from_keyboard_routine=new_bg_delpnts;
2223   return;
2224 
2225   case BG_SEL_FFT3AVGNUM:
2226   mouse_active_flag=1;
2227   numinput_xpix=bgbutt[BG_SEL_FFT3AVGNUM].x1+text_width/2-1;
2228   numinput_ypix=bgbutt[BG_SEL_FFT3AVGNUM].y1+2;
2229   numinput_chars=4;
2230   erase_numinput_txt();
2231   numinput_flag=FIXED_INT_PARM;
2232   par_from_keyboard_routine=change_fft3_avgnum;
2233   return;
2234 
2235   case BG_WATERF_AVGNUM:
2236   mouse_active_flag=1;
2237   numinput_xpix=bgbutt[BG_WATERF_AVGNUM].x1+text_width/2-1;
2238   numinput_ypix=bgbutt[BG_WATERF_AVGNUM].y1+2;
2239   numinput_chars=4;
2240   erase_numinput_txt();
2241   numinput_flag=FIXED_INT_PARM;
2242   par_from_keyboard_routine=change_bg_waterf_avgnum;
2243   return;
2244 
2245   case BG_SEL_AGC_ATTACK:
2246   mouse_active_flag=1;
2247   numinput_xpix=bgbutt[BG_SEL_AGC_ATTACK].x1+3*text_width/2-1;
2248   numinput_ypix=bgbutt[BG_SEL_AGC_ATTACK].y1+2;
2249   numinput_chars=1;
2250   erase_numinput_txt();
2251   numinput_flag=FIXED_INT_PARM;
2252   par_from_keyboard_routine=new_bg_agc_attack;
2253   return;
2254 
2255   case BG_SEL_AGC_RELEASE:
2256   mouse_active_flag=1;
2257   numinput_xpix=bgbutt[BG_SEL_AGC_RELEASE].x1+3*text_width/2-1;
2258   numinput_ypix=bgbutt[BG_SEL_AGC_RELEASE].y1+2;
2259   numinput_chars=1;
2260   erase_numinput_txt();
2261   numinput_flag=FIXED_INT_PARM;
2262   par_from_keyboard_routine=new_bg_agc_release;
2263   return;
2264 
2265   case BG_SEL_AGC_HANG:
2266   mouse_active_flag=1;
2267   numinput_xpix=bgbutt[BG_SEL_AGC_HANG].x1+3*text_width/2-1;
2268   numinput_ypix=bgbutt[BG_SEL_AGC_HANG].y1+2;
2269   numinput_chars=1;
2270   erase_numinput_txt();
2271   numinput_flag=FIXED_INT_PARM;
2272   par_from_keyboard_routine=new_bg_agc_hang;
2273   return;
2274 
2275 
2276 
2277   case BG_WATERF_ZERO:
2278   mouse_active_flag=1;
2279   numinput_xpix=bgbutt[BG_WATERF_ZERO].x1+text_width/2-1;
2280   numinput_ypix=bgbutt[BG_WATERF_ZERO].y1+2;
2281   numinput_chars=5;
2282   erase_numinput_txt();
2283   numinput_flag=FIXED_FLOAT_PARM;
2284   par_from_keyboard_routine=new_bg_waterfall_zero;
2285   return;
2286 
2287   case BG_WATERF_GAIN:
2288   mouse_active_flag=1;
2289   numinput_xpix=bgbutt[BG_WATERF_GAIN].x1+text_width/2-1;
2290   numinput_ypix=bgbutt[BG_WATERF_GAIN].y1+2;
2291   numinput_chars=4;
2292   erase_numinput_txt();
2293   numinput_flag=FIXED_FLOAT_PARM;
2294   par_from_keyboard_routine=new_bg_waterfall_gain;
2295   return;
2296 
2297   case BG_HORIZ_ARROW_MODE:
2298   bg.horiz_arrow_mode++;
2299   if(bg.horiz_arrow_mode > 2)bg.horiz_arrow_mode=0;
2300   break;
2301 
2302   case BG_MIXER_MODE:
2303   bg.mixer_mode++;
2304   if(bg.mixer_mode > 2)bg.mixer_mode=1;
2305   break;
2306 
2307   case BG_FILTER_SHIFT:
2308   if(rx_mode == MODE_AM && bg.mixer_mode == 1)
2309     {
2310     mouse_active_flag=1;
2311     numinput_xpix=bgbutt[BG_FILTER_SHIFT].x1+5*text_width/2;
2312     numinput_ypix=bgbutt[BG_FILTER_SHIFT].y1+2;
2313     numinput_chars=4;
2314     erase_numinput_txt();
2315     numinput_flag=FIXED_INT_PARM;
2316     par_from_keyboard_routine=new_bg_filter_shift;
2317     }
2318   return;
2319 
2320   case BG_NOTCH_NO:
2321   if(bg.mixer_mode == 1)
2322     {
2323     mouse_active_flag=1;
2324     numinput_xpix=bgbutt[BG_NOTCH_NO].x1+2;
2325     numinput_ypix=bgbutt[BG_NOTCH_NO].y1+2;
2326     numinput_chars=1;
2327     erase_numinput_txt();
2328     numinput_flag=FIXED_INT_PARM;
2329     par_from_keyboard_routine=new_bg_no_of_notches;
2330     return;
2331     }
2332   break;
2333 
2334   case BG_NOTCH_WIDTH:
2335   if(bg.mixer_mode == 1 && bg_no_of_notches > 0)
2336     {
2337     mouse_active_flag=1;
2338     numinput_xpix=bgbutt[BG_NOTCH_WIDTH].x1+3*text_width/2;
2339     numinput_ypix=bgbutt[BG_NOTCH_WIDTH].y1+2;
2340     numinput_chars=3;
2341     erase_numinput_txt();
2342     numinput_flag=FIXED_INT_PARM;
2343     par_from_keyboard_routine=new_bg_notch_width;
2344     return;
2345     }
2346   break;
2347 
2348   case BG_NOTCH_POS:
2349   if(bg.mixer_mode == 1 && bg_no_of_notches > 0)
2350     {
2351     mouse_active_flag=1;
2352     numinput_xpix=bgbutt[BG_NOTCH_POS].x1+7*text_width/2;
2353     numinput_ypix=bgbutt[BG_NOTCH_POS].y1+2;
2354     numinput_chars=4;
2355     erase_numinput_txt();
2356     numinput_flag=FIXED_INT_PARM;
2357     par_from_keyboard_routine=new_bg_notch_pos;
2358     return;
2359     }
2360   break;
2361 
2362   case BG_TOGGLE_FM_MODE:
2363   new_bg_fm_mode=bg.fm_mode+1;
2364   break;
2365 
2366   case BG_TOGGLE_FM_SUBTRACT:
2367   new_bg_fm_subtract=bg.fm_subtract+1;
2368   break;
2369 
2370   case BG_SEL_FM_AUDIO_BW:
2371   mouse_active_flag=1;
2372   numinput_xpix=bgbutt[BG_SEL_FM_AUDIO_BW].x1+5*text_width/2-1;
2373   numinput_ypix=bgbutt[BG_SEL_FM_AUDIO_BW].y1+2;
2374   numinput_chars=3;
2375   erase_numinput_txt();
2376   numinput_flag=FIXED_INT_PARM;
2377   par_from_keyboard_routine=new_bg_fm_audio_bw;
2378   return;
2379 
2380   case BG_SQUELCH_LEVEL:
2381   mouse_active_flag=1;
2382   numinput_xpix=bgbutt[BG_SQUELCH_LEVEL].x1+text_width/2-1;
2383   numinput_ypix=bgbutt[BG_SQUELCH_LEVEL].y1+2;
2384   numinput_chars=2;
2385   erase_numinput_txt();
2386   numinput_flag=FIXED_INT_PARM;
2387   par_from_keyboard_routine=new_bg_squelch_level;
2388   return;
2389 
2390   case BG_SQUELCH_TIME:
2391   mouse_active_flag=1;
2392   numinput_xpix=bgbutt[BG_SQUELCH_TIME].x1+text_width/2-1;
2393   numinput_ypix=bgbutt[BG_SQUELCH_TIME].y1+2;
2394   numinput_chars=1;
2395   erase_numinput_txt();
2396   numinput_flag=FIXED_INT_PARM;
2397   par_from_keyboard_routine=new_bg_squelch_time;
2398   return;
2399 
2400   case BG_SQUELCH_POINT:
2401   mouse_active_flag=1;
2402   numinput_xpix=bgbutt[BG_SQUELCH_POINT].x1+text_width/2-1;
2403   numinput_ypix=bgbutt[BG_SQUELCH_POINT].y1+2;
2404   numinput_chars=2;
2405   erase_numinput_txt();
2406   numinput_flag=FIXED_INT_PARM;
2407   par_from_keyboard_routine=new_bg_squelch_point;
2408   return;
2409 
2410   }
2411 finish:;
2412 leftpressed=BUTTON_IDLE;
2413 mouse_active_flag=0;
2414 if(new_baseb_flag == -1)
2415   {
2416   init_baseband_sizes();
2417   make_baseband_graph(TRUE);
2418   }
2419 baseb_reset_counter++;
2420 }
2421 
clear_bfo(void)2422 void clear_bfo(void)
2423 {
2424 int i;
2425 if(bfo_xpixel > 0)
2426   {
2427   for(i=bg_y1; i<=bg_y0; i++)lir_setpixel(bfo100_xpixel, i,bg_background[i]);
2428   for(i=bg_y2; i<bg_y1; i++)lir_setpixel(bfo10_xpixel, i,bg_background[i]);
2429   for(i=bg_y3; i<bg_y2; i++)lir_setpixel(bfo_xpixel, i,bg_background[i]);
2430   }
2431 }
2432 
2433 
2434 
baseb_par_control(void)2435 void baseb_par_control(void)
2436 {
2437 int old;
2438 float t1;
2439 unconditional_hide_mouse();
2440 switch (bfo_flag)
2441   {
2442   case BG_BFO:
2443   t1=((float)(mouse_x-bg_first_xpixel)/bg.pixels_per_point
2444                                -fft3_size/2+bg_first_xpoint)*bg_hz_per_pixel;
2445   if(bg.bfo_freq != t1)
2446     {
2447     clear_bfo();
2448     bg.bfo_freq=t1;
2449     make_bfo();
2450     }
2451   break;
2452 
2453   case BG_BFO10:
2454   t1=10*((float)(mouse_x-bg_first_xpixel)/bg.pixels_per_point
2455                                -fft3_size/2+bg_first_xpoint)*bg_hz_per_pixel;
2456   if(bg.bfo_freq != t1)
2457     {
2458     clear_bfo();
2459     bg.bfo_freq=t1;
2460     make_bfo();
2461     }
2462   break;
2463 
2464   case BG_BFO100:
2465   t1=100*((float)(mouse_x-bg_first_xpixel)/bg.pixels_per_point
2466                                -fft3_size/2+bg_first_xpoint)*bg_hz_per_pixel;
2467   if(bg.bfo_freq != t1)
2468     {
2469     clear_bfo();
2470     bg.bfo_freq=t1;
2471     make_bfo();
2472     }
2473   break;
2474 
2475   case BG_FLAT:
2476   if(mouse_x != flat_xpixel)
2477     {
2478     bg_flatpoints=filcur_points();
2479     if(bg_flatpoints < 1)bg_flatpoints=1;
2480     bg.filter_flat=bg_hz_per_pixel*bg_flatpoints;
2481     pause_thread(THREAD_SCREEN);
2482     make_bg_filter();
2483     if(kill_all_flag)return;
2484     resume_thread(THREAD_SCREEN);
2485     mg_clear_flag=TRUE;
2486     }
2487   break;
2488 
2489   case BG_CURV:
2490   if(mouse_x != curv_xpixel)
2491     {
2492     bg_curvpoints=filcur_points();
2493     if(bg_curvpoints < 0)bg_curvpoints=0;
2494     bg.filter_curv=bg_hz_per_pixel*10*bg_curvpoints;
2495     pause_thread(THREAD_SCREEN);
2496     make_bg_filter();
2497     if(kill_all_flag)return;
2498     resume_thread(THREAD_SCREEN);
2499     mg_clear_flag=TRUE;
2500     }
2501   break;
2502 
2503   case BG_VOLUME:
2504   if(daout_gain_y != mouse_y)
2505     {
2506     old=daout_gain_y;
2507     daout_gain_y=mouse_y;
2508     make_daout_gain();
2509     update_bar(bg_vol_x1,bg_vol_x2,bg_y0,daout_gain_y,old,
2510                                                  BG_GAIN_COLOR,bg_volbuf);
2511     }
2512   break;
2513   }
2514 if(kill_all_flag)return;
2515 lir_sched_yield();
2516 if(leftpressed == BUTTON_RELEASED)
2517   {
2518   leftpressed=BUTTON_IDLE;
2519   make_modepar_file(GRAPHTYPE_BG);
2520   mouse_active_flag=0;
2521   baseb_control_flag=0;
2522   if(rx_mode == MODE_FM && (bfo_flag == BG_FLAT || bfo_flag == BG_CURV))
2523     {
2524     init_baseband_sizes();
2525     make_baseband_graph(TRUE);
2526     }
2527   }
2528 }
2529 
mouse_on_baseband_graph(void)2530 void mouse_on_baseband_graph(void)
2531 {
2532 int event_no;
2533 // First find out if we are on a button or border line.
2534 for(event_no=0; event_no<MAX_BGBUTT; event_no++)
2535   {
2536   if( bgbutt[event_no].x1 <= mouse_x &&
2537       bgbutt[event_no].x2 >= mouse_x &&
2538       bgbutt[event_no].y1 <= mouse_y &&
2539       bgbutt[event_no].y2 >= mouse_y)
2540     {
2541     mouse_active_flag=1+event_no;
2542     current_mouse_activity=mouse_continue_baseband_graph;
2543     return;
2544     }
2545   }
2546 // Not button or border.
2547 // User wants to change filter, bfo freq or gain.
2548 // We use the upper part to change the flat region and
2549 // the lower part to change steepness.
2550 bfo_flag=0;
2551 if(mouse_y < bg_y0 && mouse_y > bg_ymax)
2552   {
2553   if(mouse_x >= bg_first_xpixel)
2554     {
2555     if(mouse_y > bg_ymax && mouse_y <= bg_y4 && abs(mouse_x-flat_xpixel) < 5)
2556       {
2557       bfo_flag=BG_FLAT;
2558       }
2559     if(mouse_y > bg_y4 && mouse_y <= bg_y3 && abs(mouse_x-curv_xpixel) < 5)
2560       {
2561       bfo_flag=BG_CURV;
2562       }
2563     if(use_bfo != 0)
2564       {
2565       if(mouse_y > bg_y3 && mouse_y <= bg_y2 && abs(mouse_x-bfo_xpixel) < 5)
2566         {
2567         bfo_flag=BG_BFO;
2568         }
2569       if(mouse_y > bg_y2 && mouse_y <= bg_y1 && abs(mouse_x-bfo10_xpixel) < 5)
2570         {
2571         bfo_flag=BG_BFO10;
2572         }
2573       if(mouse_y > bg_y1 && abs(mouse_x-bfo100_xpixel) < 5)
2574         {
2575         bfo_flag=BG_BFO100;
2576         }
2577       }
2578     }
2579   else
2580     {
2581     bfo_flag=BG_VOLUME;
2582     }
2583   }
2584 if(bfo_flag != 0)
2585   {
2586   baseb_control_flag=1;
2587   current_mouse_activity=baseb_par_control;
2588   }
2589 else
2590   {
2591   current_mouse_activity=mouse_nothing;
2592   }
2593 mouse_active_flag=1;
2594 }
2595 
fft3_size_error(char * txt)2596 void fft3_size_error(char *txt)
2597 {
2598 int i;
2599 settextcolor(15);
2600 i=bg.yborder;
2601 while(i<bg.ybottom-text_height)
2602   {
2603   lir_pixwrite(bg.xleft+5*text_width,i,"LIMIT");
2604   lir_pixwrite(bg.xleft+12*text_width,i,txt);
2605   i+=text_height;
2606   }
2607 settextcolor(7);
2608 }
2609 
init_baseband_sizes(void)2610 void init_baseband_sizes(void)
2611 {
2612 int bcha, coh, twop, dela;
2613 halt_rx_output();
2614 if(use_bfo == 0)
2615   {
2616 // Make sure delay is zero in AM and FM.
2617 // Routines probably useless and removed in Linrad-03.09
2618   new_bg_delay=0;
2619   }
2620 // Set mix2.size=-1 to force a call to init_basebmem() from
2621 // make_bg_filter whenever a parameter that affects memory
2622 // allocations has been changed.
2623 // ----------------------------------------------------
2624 if(new_bg_fm_mode > MAX_FM_FFTN-2)new_bg_fm_mode=0;
2625 if(bg.fm_mode != new_bg_fm_mode)mix2.size=-1;
2626 bg.fm_mode=new_bg_fm_mode;
2627 // ----------------------------------------------------
2628 if(new_bg_fm_subtract == 1 && (ui.network_flag & NET_RXOUT_BASEBRAW) == 0)
2629   {
2630   new_bg_fm_subtract=2;
2631   }
2632 if(new_bg_fm_subtract>2)new_bg_fm_subtract=0;
2633 if(bg.fm_subtract != new_bg_fm_subtract)mix2.size=-1;
2634 bg.fm_subtract=new_bg_fm_subtract;
2635 // ----------------------------------------------------
2636 if(genparm[CW_DECODE_ENABLE] != 0)new_bg_agc_flag=0;
2637 if(new_bg_agc_flag > 2)new_bg_agc_flag=0;
2638 if(new_bg_twopol != 0)
2639   {
2640   if(new_bg_agc_flag == 1 )new_bg_agc_flag=2;
2641   }
2642 else
2643   {
2644   if( (rx_mode != MODE_AM || bg_coherent == 0) && new_bg_agc_flag == 2)
2645     {
2646     new_bg_agc_flag=0;
2647     }
2648   }
2649 if(bg.agc_flag != new_bg_agc_flag)mix2.size=-1;
2650 bg.agc_flag=new_bg_agc_flag;
2651 // ----------------------------------------------------
2652 if(new_daout_bytes>ui.rx_max_da_bytes ||
2653    new_daout_bytes<ui.rx_min_da_bytes)
2654   {
2655   new_daout_bytes=ui.rx_min_da_bytes;
2656   }
2657 if(rx_daout_bytes!=new_daout_bytes)mix2.size=-1;
2658 rx_daout_bytes=new_daout_bytes;
2659 // ----------------------------------------------------
2660 bcha=baseb_channels;
2661 coh=bg_coherent;
2662 twop=bg_twopol;
2663 dela=bg_delay;
2664 baseb_channels=1;
2665 bg_coherent=new_bg_coherent;
2666 if(bg_coherent > 3)bg_coherent=0;
2667 bg_twopol=new_bg_twopol;
2668 if(rx_mode == MODE_FM)
2669   {
2670   bg_delay=0;
2671   }
2672 else
2673   {
2674   bg_delay=new_bg_delay;
2675   }
2676 if(bg_coherent > 0 && bg_coherent != 3)
2677   {
2678   if(ui.rx_max_da_channels == 1)
2679     {
2680     bg_coherent=3;
2681     }
2682   else
2683     {
2684     baseb_channels=2;
2685     new_daout_channels=2;
2686     }
2687   }
2688 if(bg_coherent==3)baseb_channels=1;
2689 if(bg_delay != 0)
2690   {
2691   if(ui.rx_max_da_channels == 1)
2692     {
2693     bg_delay=0;
2694     }
2695   else
2696     {
2697     baseb_channels=2;
2698     new_daout_channels=2;
2699     }
2700   }
2701 if(bg_twopol != 0)
2702   {
2703   if(ui.rx_max_da_channels == 1)
2704     {
2705     bg_twopol=0;
2706     }
2707   else
2708     {
2709     baseb_channels=2;
2710     new_daout_channels=2;
2711     }
2712   }
2713 // ----------------------------------------------------
2714 if(new_daout_channels>ui.rx_max_da_channels ||
2715    new_daout_channels<ui.rx_min_da_channels)
2716   {
2717   new_daout_channels=ui.rx_min_da_channels;
2718   }
2719 if(new_daout_channels < baseb_channels)new_daout_channels=baseb_channels;
2720 if(new_daout_channels > ui.rx_max_da_channels)
2721                            new_daout_channels=ui.rx_max_da_channels;
2722 if(new_daout_channels < ui.rx_min_da_channels)
2723                            new_daout_channels=ui.rx_min_da_channels;
2724 if(new_daout_channels!=rx_daout_channels)mix2.size=-1;
2725 rx_daout_channels=new_daout_channels;
2726 // ----------------------------------------------------
2727 if(baseb_channels > rx_daout_channels)baseb_channels=rx_daout_channels;
2728 if( bcha != baseb_channels ||
2729     coh != bg_coherent ||
2730     twop != bg_twopol ||
2731     dela != bg_delay)mix2.size=-1;
2732 bg.ch2_phase=new_bg_ch2_phase;
2733 if(bg.ch2_phase >= MAX_CH2_PHASES)bg.ch2_phase=0;
2734 if(rx_mode != MODE_SSB || bg_coherent==3 )
2735   {
2736   if(bg.ch2_phase == MAX_CH2_PHASES-1)bg.ch2_phase=0;
2737   }
2738 if(  baseb_channels != 1 ||
2739      rx_daout_channels != 2 ||
2740      bg_delay != 0 ||
2741      bg_twopol != 0)bg.ch2_phase=0;
2742 da_ch2_sign=ch2_signs[bg.ch2_phase];
2743 }
2744 
make_baseband_graph(int clear_old)2745 void make_baseband_graph(int clear_old)
2746 {
2747 char *stmp;
2748 char s[80];
2749 int volbuf_bytes;
2750 int i,j,k,sizold,ypixels, fft3_totbytes;
2751 int ix1,ix2,iy1,iy2,ib,ic;
2752 double db_scalestep;
2753 float t1, t2, t3, t4, x1, x2;
2754 float scale_value, scale_y;
2755 pause_thread(THREAD_SCREEN);
2756 if(clear_old)
2757   {
2758   hide_mouse(bg_old_x1,bg_old_x2,bg_old_y1,bg_old_y2);
2759   lir_fillbox(bg_old_x1,bg_old_y1,bg_old_x2-bg_old_x1+1,
2760                                                     bg_old_y2-bg_old_y1+1,0);
2761   }
2762 clear_agc();
2763 current_graph_minh=BG_MINYCHAR*text_height;
2764 current_graph_minw=BG_MIN_WIDTH;
2765 check_graph_placement((void*)(&bg));
2766 clear_button(bgbutt, MAX_BGBUTT);
2767 hide_mouse(bg.xleft,bg.xright,bg.ytop,bg.ybottom);
2768 bg_yborder_min=bg.ytop+3*text_height/2+3;
2769 bg_yborder_max=bg.ybottom-6*text_height;
2770 if(bg.yborder < bg_yborder_min || bg.yborder > bg_yborder_max)
2771   {
2772   bg.yborder=(bg_yborder_max+bg_yborder_min) >> 1;
2773   }
2774 bg_ymax=bg.yborder+text_height+4;
2775 bg_y0=bg.ybottom-3*text_height;
2776 bg_y1=(4*bg_y0+bg_ymax)/5;
2777 bg_y2=(3*bg_y0+2*bg_ymax)/5;
2778 bg_y3=(2*bg_y0+3*bg_ymax)/5;
2779 bg_y4=(bg_y0+4*bg_ymax)/5;
2780 bg_avg_counter=0;
2781 scro[baseband_graph_scro].no=BASEBAND_GRAPH;
2782 scro[baseband_graph_scro].x1=bg.xleft;
2783 scro[baseband_graph_scro].x2=bg.xright;
2784 scro[baseband_graph_scro].y1=bg.ytop;
2785 scro[baseband_graph_scro].y2=bg.ybottom;
2786 bgbutt[BG_LEFT].x1=bg.xleft;
2787 bgbutt[BG_LEFT].x2=bg.xleft+2;
2788 bgbutt[BG_LEFT].y1=bg.ytop;
2789 bgbutt[BG_LEFT].y2=bg.ybottom;
2790 bgbutt[BG_RIGHT].x1=bg.xright-2;
2791 bgbutt[BG_RIGHT].x2=bg.xright;
2792 bgbutt[BG_RIGHT].y1=bg.ytop;
2793 bgbutt[BG_RIGHT].y2=bg.ybottom;
2794 bgbutt[BG_TOP].x1=bg.xleft;
2795 bgbutt[BG_TOP].x2=bg.xright;
2796 bgbutt[BG_TOP].y1=bg.ytop;
2797 bgbutt[BG_TOP].y2=bg.ytop+2;
2798 bgbutt[BG_BOTTOM].x1=bg.xleft;
2799 bgbutt[BG_BOTTOM].x2=bg.xright;
2800 bgbutt[BG_BOTTOM].y1=bg.ybottom-2;
2801 bgbutt[BG_BOTTOM].y2=bg.ybottom;
2802 bgbutt[BG_YBORDER].x1=bg.xleft;
2803 bgbutt[BG_YBORDER].x2=bg.xright;
2804 bgbutt[BG_YBORDER].y1=bg.yborder-1;
2805 bgbutt[BG_YBORDER].y2=bg.yborder+1;
2806 // Draw the border lines
2807 dual_graph_borders((void*)&bg,7);
2808 // Set variables that depend on output format.
2809 if(rx_daout_bytes == 1)bg_amplimit=126; else bg_amplimit=32000;
2810 // The expander (if enabled) expands the amplitude with an
2811 // exponential function y = A* (exp(B*x)-1)
2812 // 0 <= x <= bg_amplimit
2813 // y is always 0 for x=0.
2814 // Make y=bg_amplimit/2 for x=bg_amplimit
2815 bg_expand_b=genparm[AMPLITUDE_EXPAND_EXPONENT]/bg_amplimit;
2816 bg_expand_a=bg_amplimit/(exp(bg_expand_b*bg_amplimit)-1);
2817 bg_maxamp=0;
2818 bg_amp_indicator_y=bg_y0-3;
2819 // Set up all the variables that depend on the window parameters.
2820 bg_first_xpixel=bg.xleft+4*text_width;
2821 bg_last_xpixel=bg.xright-2*text_width;
2822 bg_xpoints=2+(bg_last_xpixel-bg_first_xpixel)/bg.pixels_per_point;
2823 bg_xpixels=bg_last_xpixel-bg_first_xpixel+1;
2824 bg_vol_x1=bg.xleft+text_width;
2825 bg_vol_x2=bg_vol_x1+5*text_width/2;
2826 volbuf_bytes=(bg_y0-bg_ymax+2)*(bg_vol_x2-bg_vol_x1+2)*sizeof(char);
2827 fft3_size=2*timf3_sampling_speed/bg.bandwidth;
2828 if(fft3_size < 1)fft3_size=1;
2829 i=fft3_size;
2830 make_power_of_two(&fft3_size);
2831 if(fft3_size > 1.5*i)fft3_size>>=1;
2832 while(fft3_size < bg_xpoints)fft3_size<<=1;
2833 if(fft3_size > 0x10000)
2834   {
2835   fft3_size=0x10000;
2836   fft3_size_error("Max N = 16");
2837   }
2838 sizold=fft3_size;
2839 while(2*fft3_size*ui.rx_rf_channels+timf3_block > 0.8*timf3_size)fft3_size/=2;
2840 if(sizold != fft3_size)
2841   {
2842   sizold=fft3_size;
2843   if(genparm[SECOND_FFT_ENABLE] == 0)
2844     {
2845     fft3_size_error("fft1 storage time");
2846     }
2847   else
2848     {
2849     fft3_size_error("fft2 storage time");
2850     }
2851   }
2852 while(2*fft3_size/timf3_sampling_speed >
2853                                genparm[BASEBAND_STORAGE_TIME])fft3_size/=2;
2854 if(sizold != fft3_size)
2855   {
2856   fft3_size_error("baseband storage time");
2857   }
2858 // fft3 uses sin squared window with interleave factor=2
2859 new_fft3:;
2860 while(fft3_size < bg_xpoints)
2861   {
2862   bg_xpoints/=2;
2863   bg.pixels_per_point*=2;
2864   }
2865 fft3_n=0;
2866 i=fft3_size;
2867 while(i != 1)
2868   {
2869   i>>=1;
2870   fft3_n++;
2871   }
2872 if(fft3_size > 8192)
2873   {
2874   yieldflag_ndsp_fft3=TRUE;
2875   if(ui.max_blocked_cpus > 5)yieldflag_ndsp_fft3=FALSE;
2876   }
2877 else
2878   {
2879   yieldflag_ndsp_fft3=FALSE;
2880   }
2881 bg.bandwidth=1.9*timf3_sampling_speed/fft3_size;
2882 bg_first_xpoint=(fft3_size-bg_xpoints)/2;
2883 bg_hz_per_pixel=timf3_sampling_speed/fft3_size;
2884 bg_flatpoints=bg.filter_flat/bg_hz_per_pixel;
2885 if(bg_flatpoints < 1)bg_flatpoints=1;
2886 bg_curvpoints=0.1*bg.filter_curv/bg_hz_per_pixel;
2887 fft3_block=fft3_size*2*ui.rx_rf_channels*MAX_MIX1;
2888 fft3_blocktime=0.5*fft3_size/timf3_sampling_speed;
2889 chk_bg_avgnum();
2890 // find out how much memory we need for the fft3 buffer.
2891 // First of all we need to hold the transforms that we use for averaging.
2892 i=bg.fft_avgnum+2;
2893 // And make sure it can hold two blocks of data from
2894 // the source time function.
2895 if(genparm[SECOND_FFT_ENABLE]!=0)
2896   {
2897   k=fft2_new_points;
2898   }
2899 else
2900   {
2901   k=fft1_new_points;
2902   }
2903 t1=2*k/timf1_sampling_speed;
2904 if(t1<2)t1=2;
2905 // make buffer big enough for t1 seconds of data
2906 if(i < t1*bg_hz_per_pixel*2) i=t1*bg_hz_per_pixel*2;
2907 if(i<4)i=4;
2908 make_power_of_two(&i);
2909 t1=fft3_block*i;
2910 if(t1*sizeof(float) > (float)(0x40000000))
2911   {
2912   fft3_size/=2;
2913   fft3_size_error("RAM memory");
2914   if(fft3_size >= bg_xpoints)
2915     {
2916     goto new_fft3;
2917     }
2918   bg.fft_avgnum/=2;
2919   goto new_fft3;
2920   }
2921 fft3_totsiz=fft3_block*i;
2922 fft3_totbytes=fft3_totsiz*sizeof(float);
2923 fft3_mask=fft3_totsiz-1;
2924 fft3_show_size=bg_xpoints*ui.rx_rf_channels*bg.fft_avgnum;
2925 bg_waterf_lines=bg.yborder-bg.ytop-text_height-YWF;
2926 bg_waterf_y1=bg.ytop+text_height+YWF+1;
2927 bg_waterf_y2=bg_waterf_y1+2+bg_waterf_lines/20;
2928 if(bg_waterf_y2 > bg_waterf_y1+bg_waterf_lines-1)
2929                            bg_waterf_y2=bg_waterf_y1+bg_waterf_lines-1;
2930 bg_waterf_y=bg_waterf_y2;
2931 if(bg_waterf_y2 > bg.yborder-1)bg_waterf_y2=bg.yborder-1;
2932 bg_waterf_yinc=bg_waterf_y2-bg_waterf_y1+1;
2933 bg_waterf_size=bg_xpixels*bg_waterf_lines;
2934 max_bg_waterf_times=2+0.5*bg_waterf_lines/text_height;
2935 bg_waterf_ptr=0;
2936 local_bg_waterf_ptr=0;
2937 sc[SC_BG_WATERF_INIT]++;
2938 // ***********************************************
2939 if(fft3_handle != NULL)
2940   {
2941   fft3_handle=chk_free(fft3_handle);
2942   }
2943 init_memalloc(fft3mem,MAX_FFT3_ARRAYS);
2944 mem( 1,&fft3,fft3_totbytes,0);
2945 mem( 2,&fft3_window,fft3_size*sizeof(float),0);
2946 mem( 3,&fft3_tmp,2*fft3_size*(ui.rx_rf_channels+1)*sizeof(float),0);
2947 mem( 4,&fft3_tab,fft3_size*sizeof(COSIN_TABLE)/2,0);
2948 mem( 5,&fft3_permute,fft3_size*sizeof(short int),0);
2949 mem( 6,&fft3_fqwin_inv,fft3_size*sizeof(float),0);
2950 mem( 7,&fft3_power,fft3_show_size*ui.rx_rf_channels*sizeof(float),0);
2951 mem( 8,&fft3_slowsum,bg_xpoints*ui.rx_rf_channels*sizeof(float),0);
2952 mem( 9,&fft3_spectrum,screen_width*ui.rx_rf_channels*sizeof(short int),0);
2953 mem(10,&bg_background,screen_height*sizeof(char),0);
2954 mem(11,&bg_filterfunc,fft3_size*sizeof(float),0);
2955 mem(12,&bg_filterfunc_y,screen_width*sizeof(short int),0);
2956 mem(13,&bg_volbuf,volbuf_bytes,0);
2957 mem(15,&bg_carrfilter,fft3_size*sizeof(float),0);
2958 mem(16,&bg_carrfilter_y,screen_width*sizeof(short int),0);
2959 mem(17,&bg_waterf_sum,bg_xpoints*sizeof(float),0);
2960 mem(18,&bg_waterf,5000+bg_waterf_size*sizeof(short int),0);
2961 mem(19,&bg_waterf_times,max_bg_waterf_times*sizeof(WATERF_TIMES),0);
2962 mem(20,&bg_binshape,fft3_size*sizeof(float),0);
2963 mem(21,&bg_ytmp,fft3_size*sizeof(float),0);
2964 mem(22,&basebraw_fir,fft3_size*sizeof(float),0);
2965 mem(23,&basebcarr_fir,fft3_size*sizeof(float),0);
2966 mem(24,&squelch_info,bg_xpoints*sizeof(float),0);
2967 // **********************************************
2968 fft3_totmem=memalloc(&fft3_handle,"fft3");
2969 if(fft3_totmem == 0)
2970   {
2971   fft3_size/=2;
2972   fft3_size_error("RAM memory");
2973   if(fft3_size >= bg_xpoints)
2974     {
2975     goto new_fft3;
2976     }
2977   lirerr(1056);
2978   return;
2979   }
2980 lir_sched_yield();
2981 memset(fft3,0,MAX_MIX1*fft3_size*4*ui.rx_rf_channels*sizeof(float));
2982 memset(fft3_slowsum,0,bg_xpoints*ui.rx_rf_channels*sizeof(float));
2983 memset(fft3_power,0,fft3_show_size*ui.rx_rf_channels*sizeof(float));
2984 memset(bg_waterf_sum,0,bg_xpoints*sizeof(float));
2985 if(fft3_size > 16384)lir_sched_yield();
2986 fft3_slowsum_cnt=0;
2987 for(i=0; i<max_bg_waterf_times; i++)
2988   {
2989   bg_waterf_times[i].line=5;
2990   bg_waterf_times[i].text[0]=0;
2991   }
2992 // Show the fft size in the upper right corner.
2993 sprintf(s,"%2d",fft3_n);
2994 // Clear the waterfall memory area
2995 for(i=0;i<bg_waterf_size;i++)bg_waterf[i]=0x8000;
2996 // Make sure we know these pixels are not on screen.
2997 for(i=0;i<screen_width; i++)
2998   {
2999   bg_filterfunc_y[i]=-1;
3000   bg_carrfilter_y[i]=-1;
3001   }
3002 lir_pixwrite(bg.xright-2*text_width,bg.yborder+1.5*text_height,s);
3003 fft3_pa=0;
3004 fft3_px=0;
3005 fft3_indicator_block=(fft3_mask+1)/INDICATOR_SIZE;
3006 stmp=(void*)(fft3);
3007 sprintf(stmp,"Reserved for blanker");
3008 i=(bg.xright-bg.xleft)/text_width-12;
3009 if(i<0)i=0;
3010 stmp[i]=0;
3011 lir_pixwrite(bg.xleft+6*text_width,bg.ybottom-text_height-2,stmp);
3012 init_fft(1,fft3_n, fft3_size, fft3_tab, fft3_permute);
3013 make_window(1,fft3_size, genparm[THIRD_FFT_SINPOW], fft3_window);
3014 // Find the average filter shape of an FFT bin.
3015 // It depends on what window we have selected.
3016 // Store a sine-wave with frequency from -0.5 bin to +0.5 bin
3017 // in several steps. Produce the power spectrum in each case
3018 // and collect the average.
3019 lir_sched_yield();
3020 for(j=-3; j<=3; j++)
3021   {
3022   t1=0;
3023   t2=j*PI_L/(fft3_size*3);
3024   for(i=0; i<fft3_size; i++)
3025     {
3026     fft3_tmp[2*i  ]=cos(t1);
3027     fft3_tmp[2*i+1]=sin(t1);
3028     t1+=t2;
3029     }
3030   for( i=0; i<fft3_size/2; i++)
3031     {
3032     t1=fft3_tmp[2*i  ]*fft3_window[2*i];
3033     t2=fft3_tmp[2*i+1]*fft3_window[2*i];
3034     t3=fft3_tmp[fft3_size+2*i  ]*fft3_window[2*i+1];
3035     t4=fft3_tmp[fft3_size+2*i+1]*fft3_window[2*i+1];
3036     x1=t1-t3;
3037     fft3_tmp[2*i  ]=t1+t3;
3038     x2=t4-t2;
3039     fft3_tmp[2*i+1]=t2+t4;
3040     fft3_tmp[fft3_size+2*i   ]=fft3_tab[i].cos*x1+fft3_tab[i].sin*x2;
3041     fft3_tmp[fft3_size+2*i +1]=fft3_tab[i].sin*x1-fft3_tab[i].cos*x2;
3042     }
3043 #if IA64 == 0 && CPU == CPU_INTEL
3044   asmbulk_of_dif(fft3_size, fft3_n, fft3_tmp, fft3_tab, yieldflag_ndsp_fft3);
3045 #else
3046   bulk_of_dif(fft3_size, fft3_n, fft3_tmp, fft3_tab, yieldflag_ndsp_fft3);
3047 #endif
3048   for(i=0; i < fft3_size; i+=2)
3049     {
3050     ib=fft3_permute[i];
3051     ic=fft3_permute[i+1];
3052     bg_binshape[ib  ]=pow(fft3_tmp[2*i  ]+fft3_tmp[2*i+2],2.0)+
3053                        pow(fft3_tmp[2*i+1]+fft3_tmp[2*i+3],2.0);
3054     bg_binshape[ic  ]=pow(fft3_tmp[2*i  ]-fft3_tmp[2*i+2],2.0)+
3055                        pow(fft3_tmp[2*i+1]-fft3_tmp[2*i+3],2.0);
3056     }
3057   if(fft3_size > 8192)lir_sched_yield();
3058   }
3059 // The bin shape has to be symmetric around the midpoint so we
3060 // use the average from both sides. Store in the lower half
3061 // while accumulating errors in the upper half.
3062 i=fft3_size/2-1;
3063 k=fft3_size/2+1;
3064 while(i>0)
3065   {
3066   t1=bg_binshape[i]-bg_binshape[k];
3067   bg_binshape[i]=0.5*(bg_binshape[i]+bg_binshape[k]);
3068   bg_binshape[k]=fabs(t1);
3069   i--;
3070   k++;
3071   }
3072 t1=0;
3073 for(i=3*fft3_size/4; i<fft3_size; i++)
3074   {
3075   t1+=bg_binshape[i];
3076   }
3077 t1/=fft3_size/8;
3078 t2=0.5*t1;
3079 // t1 is now twice the average error.
3080 // Subtract it from our bg_binshape values.
3081 for(i=0; i<=fft3_size/2; i++)
3082   {
3083   bg_binshape[i]-=t1;
3084   if(bg_binshape[i]<t2)bg_binshape[i]=t2;
3085   }
3086 i=fft3_size/2-1;
3087 k=fft3_size/2+1;
3088 while(i > 0)
3089   {
3090   bg_binshape[i]=sqrt(bg_binshape[i]/bg_binshape[fft3_size/2]);
3091   bg_binshape[k]=bg_binshape[i];
3092   i--;
3093   k++;
3094   }
3095 t2=sqrt(t2/bg_binshape[fft3_size/2]);
3096 bg_binshape[fft3_size/2]=1;
3097 binshape_points=0;
3098 i=fft3_size/2-1;
3099 // Get the -100 dB point
3100 while(i>1 && bg_binshape[i-1] > 0.00001)
3101   {
3102   i--;
3103   binshape_points++;
3104   }
3105 binshape_total=binshape_points;
3106 while(i>0 && bg_binshape[i] > 1.5*t2)
3107   {
3108   i--;
3109   binshape_total++;
3110   }
3111 // Now we have the spectral shape of a single FFT bin in
3112 // bg_binshape with the maximum at position fft3_size/2.
3113 // **************************************************************
3114 //  *************************************************************
3115 // When the spectrum is picked from fft1 in the mix1 process,
3116 // mix1_fqwin is applied to suppress spurs.
3117 // as a consequence the noise floor will not be flat in the
3118 // baseband graph.
3119 // Get the inverse of mix1_fqwin in fft3_size points so we can compensate.
3120 make_window(6,fft3_size, 4, fft3_fqwin_inv);
3121 // Near the ends the inverse window has very large values.
3122 // We do not want to multiply with something VERY large, so
3123 // we apply a function that goes gently to zero outside the
3124 // maximum permitted baseband bandwidth.
3125 k=(1-MAX_BASEBFILTER_WIDTH)*fft3_size/2;
3126 t1=-4;
3127 t2=6.0/k;
3128 k=fft3_size-1;
3129 for(i=0; i<fft3_size/2; i++)
3130   {
3131   fft3_fqwin_inv[i]*=0.5*((double)2-erfc(t1));
3132   fft3_fqwin_inv[k]=fft3_fqwin_inv[i];
3133   t1+=t2;
3134   k--;
3135   }
3136 // Init fft3_spectrum at the zero level.
3137 for(i=0; i<screen_width*ui.rx_rf_channels; i++)fft3_spectrum[i]=bg_y0;
3138 bg_show_pa=0;
3139 fft3_slowsum_recalc=0;
3140 make_button(bg.xleft+text_width,bg.ybottom-text_height/2-2,
3141                                          bgbutt,BG_YSCALE_EXPAND,24);
3142 make_button(bg.xleft+3*text_width,bg.ybottom-text_height/2-2,
3143                                          bgbutt,BG_YSCALE_CONTRACT,25);
3144 make_button(bg.xleft+5*text_width,bg.ybottom-text_height/2-2, bgbutt,
3145             BG_HORIZ_ARROW_MODE,arrow_mode_char[bg.horiz_arrow_mode]);
3146 i=(bg.ybottom+bg.yborder)/2;
3147 make_button(bg.xright-text_width,i-text_height/2-2,
3148                                          bgbutt,BG_YZERO_DECREASE,24);
3149 make_button(bg.xright-text_width,i+text_height/2+2,
3150                                          bgbutt,BG_YZERO_INCREASE,25);
3151 make_button(bg.xright-3*text_width,bg.ytop+text_height/2+3,
3152                                          bgbutt,BG_RESOLUTION_DECREASE,26);
3153 make_button(bg.xright-text_width,bg.ytop+text_height/2+3,
3154                                          bgbutt,BG_RESOLUTION_INCREASE,27);
3155 if(ui.operator_skil == OPERATOR_SKIL_EXPERT)
3156   {
3157   make_button(bg.xright-text_width,bg.ybottom-text_height/2-2,
3158                                          bgbutt,BG_OSCILLOSCOPE,'o');
3159   }
3160 ix1=bg.xright-3*text_width+2;
3161 if(bg.oscill_on != 0)
3162   {
3163   make_button(ix1, bg.ybottom-text_height/2-2, bgbutt,BG_OSC_INCREASE,'+');
3164   ix1-=2*text_width-1;
3165   make_button(ix1, bg.ybottom-text_height/2-2, bgbutt,BG_OSC_DECREASE,'-');
3166   ix1-=2*text_width-2;
3167   }
3168 lir_sched_yield();
3169 iy2=bg.ybottom-2;
3170 iy1=iy2-text_height-1;
3171 ix2=ix1-3+text_width;
3172 ix1-=text_width;
3173 bgbutt[BG_NOTCH_NO].x1=ix1;
3174 bgbutt[BG_NOTCH_NO].x2=ix2;
3175 bgbutt[BG_NOTCH_NO].y1=iy1;
3176 bgbutt[BG_NOTCH_NO].y2=iy2;
3177 ix2=ix1-3;
3178 ix1-=7*text_width;
3179 bgbutt[BG_NOTCH_WIDTH].x1=ix1;
3180 bgbutt[BG_NOTCH_WIDTH].x2=ix2;
3181 bgbutt[BG_NOTCH_WIDTH].y1=iy1;
3182 bgbutt[BG_NOTCH_WIDTH].y2=iy2;
3183 ix2=ix1-2;
3184 ix1-=8*text_width;
3185 bgbutt[BG_NOTCH_POS].x1=ix1;
3186 bgbutt[BG_NOTCH_POS].x2=ix2;
3187 bgbutt[BG_NOTCH_POS].y1=iy1;
3188 bgbutt[BG_NOTCH_POS].y2=iy2;
3189 make_button(bg.xleft+text_width,bg.ytop+text_height/2+3,
3190                                          bgbutt,BG_PIX_PER_PNT_DEC,26);
3191 make_button(bg.xleft+3*text_width,bg.ytop+text_height/2+3,
3192                                          bgbutt,BG_PIX_PER_PNT_INC,27);
3193 bgbutt[BG_WATERF_AVGNUM].x1=2+bg.xleft;
3194 bgbutt[BG_WATERF_AVGNUM].x2=2+bg.xleft+4.5*text_width;
3195 bgbutt[BG_WATERF_AVGNUM].y1=bg.yborder-text_height-2;
3196 bgbutt[BG_WATERF_AVGNUM].y2=bg.yborder-2;
3197 bgbutt[BG_WATERF_GAIN].x1=bg.xright-4.5*text_width-2;
3198 bgbutt[BG_WATERF_GAIN].x2=bg.xright-2;
3199 bgbutt[BG_WATERF_GAIN].y1=bg.yborder-2*text_height-4;
3200 bgbutt[BG_WATERF_GAIN].y2=bg.yborder-text_height-4;
3201 bgbutt[BG_WATERF_ZERO].x1=bg.xright-5.5*text_width-2;
3202 bgbutt[BG_WATERF_ZERO].x2=bg.xright-2;
3203 bgbutt[BG_WATERF_ZERO].y1=bg.yborder-text_height-2;
3204 bgbutt[BG_WATERF_ZERO].y2=bg.yborder-2;
3205 iy1=bg.yborder+2;
3206 iy2=bg.yborder+text_height+2;
3207 bgbutt[BG_SEL_FFT3AVGNUM].x1=bg.xleft+2;
3208 bgbutt[BG_SEL_FFT3AVGNUM].x2=bg.xleft+2+4.5*text_width;
3209 bgbutt[BG_SEL_FFT3AVGNUM].y1=iy1;
3210 bgbutt[BG_SEL_FFT3AVGNUM].y2=iy2;
3211 ix1=bg.xleft+4+9*text_width/2;
3212 ix2=ix1+7*text_width/2;
3213 if(rx_mode == MODE_FM)
3214   {
3215   bgbutt[BG_TOGGLE_FM_MODE].x1=ix1;
3216   bgbutt[BG_TOGGLE_FM_MODE].x2=ix2;
3217   bgbutt[BG_TOGGLE_FM_MODE].y1=iy1;
3218   bgbutt[BG_TOGGLE_FM_MODE].y2=iy2;
3219   ix1=ix2+2;
3220   ix2=ix1+3*text_width/2;
3221   bgbutt[BG_TOGGLE_FM_SUBTRACT].x1=ix1;
3222   bgbutt[BG_TOGGLE_FM_SUBTRACT].x2=ix2;
3223   bgbutt[BG_TOGGLE_FM_SUBTRACT].y1=iy1;
3224   bgbutt[BG_TOGGLE_FM_SUBTRACT].y2=iy2;
3225   ix1=ix2+2;
3226   ix2=ix1+11*text_width/2;
3227   bgbutt[BG_SEL_FM_AUDIO_BW].x1=ix1;
3228   bgbutt[BG_SEL_FM_AUDIO_BW].x2=ix2;
3229   bgbutt[BG_SEL_FM_AUDIO_BW].y1=iy1;
3230   bgbutt[BG_SEL_FM_AUDIO_BW].y2=iy2;
3231   freq_readout_x1=ix2;
3232   bg.agc_flag=0;
3233   }
3234 else
3235   {
3236   bgbutt[BG_TOGGLE_AGC].x1=ix1;
3237   bgbutt[BG_TOGGLE_AGC].x2=ix2;
3238   bgbutt[BG_TOGGLE_AGC].y1=iy1;
3239   bgbutt[BG_TOGGLE_AGC].y2=iy2;
3240   if(bg.agc_flag == 0)
3241     {
3242     freq_readout_x1=ix2;
3243     }
3244   else
3245     {
3246     ix1=ix2+2;
3247     ix2=ix1+5*text_width/2;
3248     bgbutt[BG_SEL_AGC_ATTACK].x1=ix1;
3249     bgbutt[BG_SEL_AGC_ATTACK].x2=ix2;
3250     bgbutt[BG_SEL_AGC_ATTACK].y1=iy1;
3251     bgbutt[BG_SEL_AGC_ATTACK].y2=iy2;
3252     ix1=ix2+2;
3253     ix2=ix1+5*text_width/2;
3254     bgbutt[BG_SEL_AGC_RELEASE].x1=ix1;
3255     bgbutt[BG_SEL_AGC_RELEASE].x2=ix2;
3256     bgbutt[BG_SEL_AGC_RELEASE].y1=iy1;
3257     bgbutt[BG_SEL_AGC_RELEASE].y2=iy2;
3258     ix1=ix2+2;
3259     ix2=ix1+5*text_width/2;
3260     bgbutt[BG_SEL_AGC_HANG].x1=ix1;
3261     bgbutt[BG_SEL_AGC_HANG].x2=ix2;
3262     bgbutt[BG_SEL_AGC_HANG].y1=iy1;
3263     bgbutt[BG_SEL_AGC_HANG].y2=iy2;
3264     freq_readout_x1=ix2;
3265     }
3266   }
3267 freq_readout_x1+=text_width;
3268 freq_readout_y1=iy1;
3269 ix2=bg.xright-2;
3270 ix1=ix2-1.5*text_width;
3271 bgbutt[BG_MIXER_MODE].x1=ix1;
3272 bgbutt[BG_MIXER_MODE].x2=ix2;
3273 bgbutt[BG_MIXER_MODE].y1=iy1;
3274 bgbutt[BG_MIXER_MODE].y2=iy2;
3275 if(rx_mode == MODE_AM && bg.mixer_mode == 1)
3276   {
3277 // ***********  make filter shift button ******************
3278   ix2=ix1-2;
3279   ix1-=8*text_width;
3280   bgbutt[BG_FILTER_SHIFT].x1=ix1;
3281   bgbutt[BG_FILTER_SHIFT].x2=ix2;
3282   bgbutt[BG_FILTER_SHIFT].y1=iy1;
3283   bgbutt[BG_FILTER_SHIFT].y2=iy2;
3284   }
3285 // Make the squelch buttons. They will be placed on screen by make_bg_filter.
3286 ix2=ix1-2;
3287 ix1=ix2-1.5*text_width;
3288 bgbutt[BG_SQUELCH_TIME].x1=ix1;
3289 bgbutt[BG_SQUELCH_TIME].x2=ix2;
3290 bgbutt[BG_SQUELCH_TIME].y1=iy1;
3291 bgbutt[BG_SQUELCH_TIME].y2=iy2;
3292 ix2=ix1-2;
3293 ix1=ix2-2.5*text_width;
3294 bgbutt[BG_SQUELCH_POINT].x1=ix1;
3295 bgbutt[BG_SQUELCH_POINT].x2=ix2;
3296 bgbutt[BG_SQUELCH_POINT].y1=iy1;
3297 bgbutt[BG_SQUELCH_POINT].y2=iy2;
3298 ix2=ix1-2;
3299 ix1=ix2-2.5*text_width;
3300 bgbutt[BG_SQUELCH_LEVEL].x1=ix1;
3301 bgbutt[BG_SQUELCH_LEVEL].x2=ix2;
3302 bgbutt[BG_SQUELCH_LEVEL].y1=iy1;
3303 bgbutt[BG_SQUELCH_LEVEL].y2=iy2;
3304 squelch_turnon_time=current_time();
3305 squelch_on=-2;
3306 // Write out the y scale for logarithmic spectrum graph.
3307 // We want a point with amplitude 1<<(fft1_n/2) to be placed at the
3308 // zero point of the dB scale.
3309 for(i=0; i<screen_height; i++)bg_background[i]=0;
3310 ypixels=bg_y0-bg_ymax+1;
3311 bg.db_per_pixel=20*log10(bg.yrange)/ypixels;
3312 db_scalestep=1.3*bg.db_per_pixel*text_height;
3313 adjust_scale(&db_scalestep);
3314 if(db_scalestep < 1)
3315   {
3316   db_scalestep=1;
3317   bg.db_per_pixel=0.5/text_height;
3318   bg.yrange=pow(10.,ypixels*bg.db_per_pixel/20);
3319   }
3320 t1=20*log10( bg.yzero);
3321 i=(t1+0.5*db_scalestep)/db_scalestep;
3322 scale_value=i*db_scalestep;
3323 scale_y=bg_y0+(t1-scale_value)/bg.db_per_pixel;
3324 while( scale_y > bg_ymax)
3325   {
3326   if(scale_y+text_height/2+1 < bg_y0)
3327     {
3328     i=(int)(scale_value);
3329     sprintf(s,"%3d",i);
3330     lir_pixwrite(bg.xleft+text_width/2,(int)scale_y-text_height/2+2,s);
3331     }
3332   if(scale_y+1 < bg_y0)
3333     {
3334     i=scale_y;
3335     bg_background[i]=BG_DBSCALE_COLOR;
3336     if(i > bgbutt[BG_SQUELCH_LEVEL].y2)
3337       {
3338       j=bg_last_xpixel;
3339       }
3340     else
3341       {
3342       j= bgbutt[BG_SQUELCH_LEVEL].x1-1;
3343       }
3344     lir_hline(bg_first_xpixel,i,j,BG_DBSCALE_COLOR);
3345     if(kill_all_flag) return;
3346     }
3347   scale_y-=db_scalestep/bg.db_per_pixel;
3348   scale_value+=db_scalestep;
3349   }
3350 freq_readout_x2=ix1-text_width;
3351 make_bg_yfac();
3352 make_bg_filter();
3353 if(kill_all_flag) return;
3354 make_modepar_file(GRAPHTYPE_BG);
3355 bg_flag=1;
3356 daout_gain_y=-1;
3357 make_daout_gainy();
3358 // *************  Make button to select no of channels for mono modes
3359 ix1=bg.xleft+text_width;
3360 if(  baseb_channels == 1  &&
3361      rx_daout_channels == 2  &&
3362      bg_delay == 0 &&
3363      bg_twopol == 0)
3364   {
3365   make_button(ix1,bg.ybottom-2*text_height,
3366                  bgbutt,BG_TOGGLE_CH2_PHASE,ch2_phase_symbol[bg.ch2_phase]);
3367   }
3368 ix1+=3*text_width/2+2;
3369 make_button(ix1,bg.ybottom-2*text_height,
3370                        bgbutt,BG_TOGGLE_CHANNELS,'0'+rx_daout_channels);
3371 // ************** Make button to select number of bit's
3372 ix1+=4+text_width/2;
3373 ix2=ix1+5*text_width/2;
3374 iy1=bg.ybottom-5*text_height/2-1;
3375 iy2=iy1+text_height+1;
3376 bgbutt[BG_TOGGLE_BYTES].x1=ix1;
3377 bgbutt[BG_TOGGLE_BYTES].x2=ix2;
3378 bgbutt[BG_TOGGLE_BYTES].y1=iy1;
3379 bgbutt[BG_TOGGLE_BYTES].y2=iy2;
3380 // **************   Make the button for the amplitude expander
3381 if(use_bfo != 0)
3382   {
3383   ix1=ix2+2;
3384   ix2=ix1+7*text_width/2;
3385   bgbutt[BG_TOGGLE_EXPANDER].x1=ix1;
3386   bgbutt[BG_TOGGLE_EXPANDER].x2=ix2;
3387   bgbutt[BG_TOGGLE_EXPANDER].y1=iy1;
3388   bgbutt[BG_TOGGLE_EXPANDER].y2=iy2;
3389   }
3390 // *********************     Make the button for coherent CW
3391 ix1=ix2+2;
3392 ix2=ix1+9*text_width/2;
3393 bgbutt[BG_TOGGLE_COHERENT].x1=ix1;
3394 bgbutt[BG_TOGGLE_COHERENT].x2=ix2;
3395 bgbutt[BG_TOGGLE_COHERENT].y1=iy1;
3396 bgbutt[BG_TOGGLE_COHERENT].y2=iy2;
3397 // ***********  make coherent bandwidth factor button ******************
3398 ix1=ix2+2;
3399 ix2=ix1+15*text_width/2;
3400 bgbutt[BG_SEL_COHFAC].x1=ix1;
3401 bgbutt[BG_SEL_COHFAC].x2=ix2;
3402 bgbutt[BG_SEL_COHFAC].y1=iy1;
3403 bgbutt[BG_SEL_COHFAC].y2=iy2;
3404 // ****************************************************************
3405 if(use_bfo != 0)
3406   {
3407 // Make the button for frequency depending phase shift between ears
3408 // This is the same as a time delay for one channel!
3409   ix1=ix2+2;
3410   ix2=ix1+7*text_width/2;
3411   bgbutt[BG_TOGGLE_PHASING].x1=ix1;
3412   bgbutt[BG_TOGGLE_PHASING].x2=ix2;
3413   bgbutt[BG_TOGGLE_PHASING].y1=iy1;
3414   bgbutt[BG_TOGGLE_PHASING].y2=iy2;
3415 // ******  delay no of points button *************
3416   ix1=ix2+2;
3417   ix2=ix1+7*text_width/2;
3418   bgbutt[BG_SEL_DELPNTS].x1=ix1;
3419   bgbutt[BG_SEL_DELPNTS].x2=ix2;
3420   bgbutt[BG_SEL_DELPNTS].y1=iy1;
3421   bgbutt[BG_SEL_DELPNTS].y2=iy2;
3422   }
3423 // ****************************************************************
3424 // Make the button for stereo reception of two channels
3425 // if there are two channels.
3426 if(ui.rx_rf_channels == 2)
3427   {
3428   ix1=ix2+2;
3429   ix2=ix1+7*text_width/2;
3430   bgbutt[BG_TOGGLE_TWOPOL].x1=ix1;
3431   bgbutt[BG_TOGGLE_TWOPOL].x2=ix2;
3432   bgbutt[BG_TOGGLE_TWOPOL].y1=iy1;
3433   bgbutt[BG_TOGGLE_TWOPOL].y2=iy2;
3434   }
3435 else
3436   {
3437   bgbutt[BG_TOGGLE_TWOPOL].x1=screen_width+1;
3438   bgbutt[BG_TOGGLE_TWOPOL].x2=screen_width+1;
3439   }
3440 i=bg_twopol;                 //bit 7
3441 i=(i<<1)+bg_delay;           //bit 6
3442 i=(i<<2)+bg_coherent;        //bits 4 and 5
3443 i=(i<<2)+bg_expand;          //bits 2 and 3
3444 i=(i<<1)+rx_daout_channels-1;   //bit 1
3445 i=(i<<1)+rx_daout_bytes-1;      //bit 0
3446 sprintf(s,"%3d",i);
3447 lir_pixwrite(bg.xright-7*text_width/2,iy1+2,s);
3448 bg_amp_indicator_x=bg.xleft+2;
3449 show_bg_maxamp();
3450 check_bg_cohfac();
3451 check_bg_fm_audio_bw();
3452 make_agc_amplimit();
3453 bg_waterf_block=(bg_waterf_y2-bg_waterf_y1+1)*bg_xpixels;
3454 make_bg_waterf_cfac();
3455 if(genparm[AFC_ENABLE]==0 || rx_mode >= MODE_SSB)
3456   {
3457   sc[SC_SHOW_WHEEL]++;
3458   }
3459 bg_old_y1=bg.ytop;
3460 bg_old_y2=bg.ybottom;
3461 bg_old_x1=bg.xleft;
3462 bg_old_x2=bg.xright;
3463 if(rx_mode == MODE_FM)
3464   {
3465 // *********************** fm_audiofil *********************************
3466   i=1000*fm_audiofil_size*bg.fm_audio_bw/baseband_sampling_speed;
3467   construct_fir(7,fm_audiofil_size, fm_audiofil_n,
3468                    &fm_audiofil_points, i, fm_audiofil_fir, 0.00001);
3469   fm0_ph1=0;
3470   fm0_ph2=0;
3471   fm1_ph1=0;
3472   fm1_ph2=0;
3473   fm2_ph1=0;
3474   fm2_ph2=0;
3475   fm_n=bg.fm_mode+2;
3476   if(fm_n < 3)fm_n=0;
3477   if(fm_n > MAX_FM_FFTSIZE)fm_n=MAX_FM_FFTSIZE;
3478   i=fm_n;
3479   fm_size=1;
3480   while(i>0)
3481     {
3482     i--;
3483     fm_size<<=1;
3484     }
3485   init_fft(0,fm_n, fm_size, fm_tab, fm_permute);
3486   make_window(4,fm_size, 2, fm_win);
3487   }
3488 if(genparm[BG_WATERF_BLANKED_PERCENT] == 0)
3489   {
3490   bg_waterfall_blank_points=0;
3491   }
3492 else
3493   {
3494   bg_waterfall_blank_points=1+(genparm[BG_WATERF_BLANKED_PERCENT]*bg_xpixels)/100;
3495   }
3496 resume_thread(THREAD_SCREEN);
3497 if(mix1_selfreq[0]>0)sc[SC_FREQ_READOUT]++;
3498 sc[SC_BG_FQ_SCALE]++;
3499 sc[SC_BG_BUTTONS]++;
3500 }
3501 
show_bg_maxamp(void)3502 void show_bg_maxamp(void)
3503 {
3504 unsigned char color;
3505 float t1;
3506 t1=bg_maxamp/bg_amplimit;
3507 t1*=bg_y0-bg_ymax-2;
3508 hide_mouse(bg_amp_indicator_x,bg_amp_indicator_x+text_width/2,
3509                                    bg_amp_indicator_y,bg_amp_indicator_y+3);
3510 lir_fillbox(bg_amp_indicator_x,bg_amp_indicator_y,text_width/2,3,0);
3511 bg_amp_indicator_y=bg_y0-t1-1;
3512 if(t1<1)
3513   {
3514   color=10;
3515   }
3516 else
3517   {
3518   if(bg_amp_indicator_y<=bg_ymax+3)
3519     {
3520     color=12;
3521     }
3522   else
3523     {
3524     color=7;
3525     }
3526   }
3527 hide_mouse(bg_amp_indicator_x,bg_amp_indicator_x+text_width/2,
3528                                    bg_amp_indicator_y,bg_amp_indicator_y+3);
3529 lir_fillbox(bg_amp_indicator_x,bg_amp_indicator_y,text_width/2,3,color);
3530 bg_maxamp=0;
3531 }
3532 
init_baseband_graph(void)3533 void init_baseband_graph(void)
3534 {
3535 int i,errcnt;
3536 errcnt=0;
3537 if (read_modepar_file(GRAPHTYPE_BG) == 0)
3538   {
3539 bg_default:;
3540 // Make the default window for the baseband graph.
3541   bg.xleft=hg.xright+2;
3542   bg.xright=bg.xleft+0.5*screen_width;
3543   if(bg.xright > screen_width)
3544     {
3545     bg.xright=screen_width-1;
3546     bg.xleft=bg.xright-BG_MIN_WIDTH;
3547     }
3548   bg.ytop=wg.ybottom+2;
3549   bg.yborder=bg.ytop+0.1*screen_height;
3550   bg.ybottom=bg.yborder+0.2*screen_height;
3551   if(bg.ybottom>0.8*screen_height)
3552     {
3553     bg.ybottom=0.8*screen_height;
3554     bg.yborder=(2*bg.ybottom+bg.ytop)/3;
3555     }
3556   bg.bandwidth=timf3_sampling_speed/256;
3557   bg.yrange=4096;
3558   bg.yzero=1;
3559   switch (rx_mode)
3560     {
3561     case MODE_WCW:
3562     bg.filter_flat=14;
3563     bg.filter_curv=0;
3564     bg.output_gain=1;
3565     bg.agc_flag=0;
3566     bg.waterfall_avgnum=5;
3567     bg.bandwidth/=4;
3568     break;
3569 
3570     case MODE_NCW:
3571     bg.filter_flat=250;
3572     bg.filter_curv=50;
3573     bg.output_gain=100;
3574     bg.agc_flag=1;
3575     bg.waterfall_avgnum=50;
3576     break;
3577 
3578     case MODE_SSB:
3579     bg.filter_flat=1200;
3580     bg.filter_curv=0;
3581     bg.output_gain=5000;
3582     bg.agc_flag=1;
3583     bg.waterfall_avgnum=50;
3584     break;
3585 
3586     case MODE_AM:
3587     bg.filter_flat=3000;
3588     bg.filter_curv=250;
3589     bg.output_gain=5000;
3590     bg.agc_flag=1;
3591     bg.waterfall_avgnum=200;
3592     break;
3593 
3594     case MODE_FM:
3595     bg.filter_flat=5000;
3596     bg.filter_curv=250;
3597     bg.output_gain=5;
3598     bg.agc_flag=0;
3599     bg.waterfall_avgnum=400;
3600     break;
3601 
3602     default:
3603     bg.filter_flat=150;
3604     bg.filter_curv=250;
3605     bg.output_gain=0.05;
3606     bg.agc_flag = 0;
3607     bg.waterfall_avgnum=100;
3608     break;
3609     }
3610   bg.bfo_freq=bg.filter_flat+0.1*bg.filter_curv+300;
3611   bg.check=BG_VERNR;
3612   bg.fft_avgnum=50;
3613   bg.pixels_per_point=1;
3614   bg.coh_factor=8;
3615   bg.delay_points=4;
3616   bg.agc_attack = 2;
3617   bg.agc_release = 4;
3618   bg.agc_hang=2;
3619   bg.waterfall_gain=1;
3620   bg.waterfall_zero=20;
3621   bg.wheel_stepn=0;
3622   bg.oscill_on=0;
3623   bg.oscill_gain=0.1;
3624   bg.horiz_arrow_mode=0;
3625   bg.mixer_mode=1;
3626   bg.filter_shift=0;
3627   bg.fm_mode=0;
3628   bg.fm_subtract=0;
3629   bg.fm_audio_bw=10;
3630   }
3631 if(bg.check != BG_VERNR)goto bg_default;
3632 errcnt++;
3633 if(errcnt < 2)
3634   {
3635   if(
3636     bg.xleft < 0 ||
3637     bg.xleft > screen_last_xpixel ||
3638     bg.xright < 0 ||
3639     bg.xright > screen_last_xpixel ||
3640     bg.xright-bg.xleft < BG_MIN_WIDTH ||
3641     bg.ytop < 0 ||
3642     bg.ytop > screen_height-1 ||
3643     bg.ybottom < 0 ||
3644     bg.ybottom > screen_height-1 ||
3645     bg.ybottom-bg.ytop < 6*text_height ||
3646     bg.pixels_per_point > 16 ||
3647     bg.pixels_per_point < 1 ||
3648     bg.coh_factor < 1 ||
3649     bg.coh_factor > 9999 ||
3650     bg.delay_points < 0 ||
3651     bg.delay_points > 999 ||
3652     bg.waterfall_avgnum < 1 ||
3653     bg.agc_flag < 0 ||
3654     bg.agc_flag > 2 ||
3655     bg.horiz_arrow_mode<0 ||
3656     bg.horiz_arrow_mode > 2 ||
3657     bg.mixer_mode < 1 ||
3658     bg.mixer_mode > 2  ||
3659     bg.filter_shift < -999 ||
3660     bg.filter_shift > 999 ||
3661     bg.fm_mode < 0 ||
3662     bg.fm_mode > MAX_FM_FFTN-2 ||
3663     bg.fm_subtract < 0 ||
3664     bg.fm_subtract > 2 ||
3665     bg.fm_audio_bw < 1 ||
3666     bg.fm_audio_bw > 96 ||
3667     bg.ch2_phase <0 ||
3668     bg.ch2_phase >= MAX_CH2_PHASES ||
3669     bg.agc_attack < 0 ||
3670     bg.agc_attack > 9 ||
3671     bg.agc_release < 0 ||
3672     bg.agc_release > 9 ||
3673     bg.agc_hang < 0 ||
3674     bg.agc_hang > 9
3675     )goto bg_default;
3676   }
3677 bg_no_of_notches=0;
3678 bg_current_notch=0;
3679 new_bg_agc_flag=bg.agc_flag;
3680 if(bg.wheel_stepn<-30 || bg.wheel_stepn >30)bg.wheel_stepn=0;
3681 bfo_flag=0;
3682 mix2.size=-1;
3683 new_daout_bytes=1+(genparm[OUTPUT_MODE]&1);           //bit 0
3684 new_daout_channels=1+((genparm[OUTPUT_MODE]>>1)&1);   //bit 1
3685 bg_expand=(genparm[OUTPUT_MODE]>>2)&3;                //bit 2 and 3
3686 new_bg_coherent=(genparm[OUTPUT_MODE]>>4)&3;          //bits 4 and 5
3687 new_bg_delay=(genparm[OUTPUT_MODE]>>6)&1;             //bit 6
3688 new_bg_twopol=(genparm[OUTPUT_MODE]>>7)&1;            //bit 7
3689 new_bg_fm_mode=bg.fm_mode;
3690 new_bg_fm_subtract=bg.fm_subtract;
3691 new_bg_agc_flag=bg.agc_flag;
3692 new_bg_ch2_phase=0;
3693 baseb_channels=0;
3694 baseband_sampling_speed=0;
3695 timf1_to_baseband_speed_ratio=timf1_sampling_speed;
3696 timf2_blockpower_block=4*ui.rx_rf_channels*timf1_to_baseband_speed_ratio;
3697 baseband_graph_scro=no_of_scro;
3698 bfo_xpixel=-1;
3699 if(ui.operator_skil != OPERATOR_SKIL_EXPERT)
3700   {
3701   bg.oscill_on=0;
3702   }
3703 init_baseband_sizes();
3704 make_baseband_graph(FALSE);
3705 if(kill_all_flag)return;
3706 init_basebmem();
3707 no_of_scro++;
3708 if(no_of_scro >= MAX_SCRO)lirerr(89);
3709 for(i=0; i<screen_width*ui.rx_rf_channels; i++)fft3_spectrum[i]=bg_y0;
3710 // Clear bg_timestamp_counter which is used to show time in the waterfall graph
3711 // every time 2*text_height new waterfall lines have arrived.
3712 bg_timestamp_counter=0;
3713 }
3714 
3715