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