#define YWF 4 #define FRESH_RECALC 25 #define YBO 4 #define DA_GAIN_RANGE 7. #define DA_GAIN_REF 0.1 #define BG_MINYCHAR 8 #define BG_MIN_WIDTH (36*text_width) #include #include #include "globdef.h" #include "uidef.h" #include "fft3def.h" #include "fft2def.h" #include "fft1def.h" #include "sigdef.h" #include "seldef.h" #include "vernr.h" #include "screendef.h" #include "graphcal.h" #include "thrdef.h" #include "options.h" int baseband_graph_scro; int bg_old_x1; int bg_old_x2; int bg_old_y1; int bg_old_y2; void make_baseband_graph(int clear_old); void make_bg_waterf_cfac(void) { bg_waterf_cfac=bg.waterfall_gain*0.1; bg_waterf_czer=10*bg.waterfall_zero; } void make_bg_yfac(void) { if(genparm[SECOND_FFT_ENABLE]==0) { bg.yfac_power=FFT1_BASEBAND_FACTOR; bg.yfac_power*=ui.rx_rf_channels*ui.rx_rf_channels; } else { bg.yfac_power=FFT2_BASEBAND_FACTOR* (float)(1<bg_y0)daout_gain_y=bg_y0; if(daout_gain_y 0) { if(bg_filterfunc_y[bfo_xpixel] > 0) lir_setpixel(bfo_xpixel,bg_filterfunc_y[bfo_xpixel],14); if(bg_filterfunc_y[bfo10_xpixel] > 0) lir_setpixel(bfo10_xpixel,bg_filterfunc_y[bfo10_xpixel],14); if(bg_filterfunc_y[bfo100_xpixel] > 0) lir_setpixel(bfo100_xpixel,bg_filterfunc_y[bfo100_xpixel],14); if(bg_carrfilter_y[bfo_xpixel] > 0) lir_setpixel(bfo_xpixel,bg_carrfilter_y[bfo_xpixel],14); if(bg_carrfilter_y[bfo10_xpixel] > 0) lir_setpixel(bfo10_xpixel,bg_carrfilter_y[bfo10_xpixel],14); if(bg_carrfilter_y[bfo100_xpixel] > 0) lir_setpixel(bfo100_xpixel,bg_carrfilter_y[bfo100_xpixel],14); } // When we arrive here only bg.bfo_freq is defined. // Set up the other variables we need that depend on it. daout_phstep=-2*PI_L*bg.bfo_freq/genparm[DA_OUTPUT_SPEED]; bforef=bg_first_xpixel+0.5+bg.pixels_per_point*(fft3_size/2-bg_first_xpoint); bfooff=bg.pixels_per_point*bg.bfo_freq/bg_hz_per_pixel; bfo_xpixel=bforef+bfooff; if(bfo_xpixel < bg_first_xpixel)bfo_xpixel=bg_first_xpixel; if(bfo_xpixel > bg_last_xpixel)bfo_xpixel=bg_last_xpixel; bfo10_xpixel=bforef+0.1*bfooff; if(bfo10_xpixel < bg_first_xpixel)bfo10_xpixel=bg_first_xpixel; if(bfo10_xpixel > bg_last_xpixel)bfo10_xpixel=bg_last_xpixel; bfo100_xpixel=bforef+0.01*bfooff; if(bfo100_xpixel < bg_first_xpixel)bfo100_xpixel=bg_first_xpixel; if(bfo100_xpixel > bg_last_xpixel)bfo100_xpixel=bg_last_xpixel; lir_line(bfo100_xpixel, bg_y0,bfo100_xpixel,bg_y1,12); if(kill_all_flag) return; lir_line(bfo10_xpixel, bg_y1-1,bfo10_xpixel,bg_y2,12); if(kill_all_flag) return; lir_line(bfo_xpixel, bg_y2-1,bfo_xpixel,bg_ymax,12); } void make_audio_signal(void) { int i,i1,i2,i3,i4,mm,nn; float t1,t2,t3,t4,t5,t6,t7; short int *intvar; float r1,r2,a1,a2,b1,b2; float rdiff, final_gain; // Resample the baseband signal so we get the correct sampling speed // for the D/A converter. // For each interval in baseb_out there is a non integer number of points // in da_output. mm=rx_daout_channels*rx_daout_bytes; nn=2*baseb_channels; r1=daout_pa/(mm*da_resample_ratio); while(r1>baseband_size)r1-=baseband_size; resamp:; r2=(daout_pa+mm)/(mm*da_resample_ratio); if(r2>baseband_size)r2-=baseband_size; i2=baseb_fx+r1+.5; if(r2>r1) { i3=baseb_fx+r2+.5; } else { i3=baseb_fx+r2+.5+daout_size/(mm*da_resample_ratio); } i2&=baseband_mask; i3&=baseband_mask; if(abs(i3-i2) > 1) { i2=baseb_fx+(r1+r2)/2; i3=i2+1; i2&=baseband_mask; i3&=baseband_mask; } else { if(i3==i2) { i2=baseb_fx+r1; i2&=baseband_mask; if(i3==i2) { i3=i2+1; i3&=baseband_mask; } } } i4=(i3+1)&baseband_mask; i1=(i2+baseband_mask)&baseband_mask; baseb_wts=((baseb_pa-i4+baseband_size)&baseband_mask); if( ((daout_px-daout_pa+daout_bufmask)&daout_bufmask) <= 2*rx_daout_block) { return; } if( baseb_wts > baseb_margin) { rdiff=r1+baseb_fx-i2; if(rdiff > baseband_size/2) { rdiff-=baseband_size; } daout_phase+=daout_phstep; if(daout_phase > PI_L)daout_phase-=2*PI_L; if(daout_phase < -PI_L)daout_phase+=2*PI_L; // Use Lagrange's interpolation formula to fit a third degree // polynomial to 4 points: // a1=-rdiff * (rdiff-1)*(rdiff-2)*baseb_out[nn*i1]/6 // +(rdiff+1)*(rdiff-1)*(rdiff-2)*baseb_out[nn*i2]/2 // -(rdiff+1)* rdiff *(rdiff-2)*baseb_out[nn*i3]/2 // +(rdiff+1)* rdiff *(rdiff-1)*baseb_out[nn*i4]/6; // Rewrite slightly to save a few multiplications - do not // think the compiler is smart enough to do it for us. t1=rdiff-1; t2=rdiff-2; t3=rdiff+1; t4=t1*t2; t5=t3*rdiff; t6=rdiff*t4; t4=t3*t4; t7=t5*t2; t5=t5*t1; final_gain=daout_gain; if(bg.agc_flag != 0) { if( daout_gain*baseb_agc_level[i2] > bg_agc_amplimit) { final_gain=bg_agc_amplimit/baseb_agc_level[i2]; } } if(baseb_channels == 1) { a1=final_gain*(((t5*baseb_out[nn*i4 ]-t6*baseb_out[nn*i1 ])/3 +t4*baseb_out[nn*i2 ]-t7*baseb_out[nn*i3 ])/2); a2=final_gain*(((t5*baseb_out[nn*i4+1]-t6*baseb_out[nn*i1+1])/3 +t4*baseb_out[nn*i2+1]-t7*baseb_out[nn*i3+1])/2); if(bg_expand != 2) { t1=sqrt(a1*a1+a2*a2); if(t1 > 0.5) { if(t1 bg_amplimit)t2=bg_amplimit; if(t2 < -bg_amplimit)t2=-bg_amplimit; if(bg_maxamp < t2)bg_maxamp=t2; if(rx_daout_bytes == 1) { daout[daout_pa]=i=0x80+t2; if(rx_daout_channels == 2)daout[daout_pa+1]=0x80+t2*da_ch2_sign; } else { i=t2; intvar=(void*)(&daout[daout_pa]); intvar[0]=i; if(rx_daout_channels == 2)intvar[1]=i*da_ch2_sign; } } } else { a1=final_gain*(((t5*baseb_out[nn*i4 ]-t6*baseb_out[nn*i1 ])/3 +t4*baseb_out[nn*i2 ]-t7*baseb_out[nn*i3 ])/2); a2=final_gain*(((t5*baseb_out[nn*i4+1]-t6*baseb_out[nn*i1+1])/3 +t4*baseb_out[nn*i2+1]-t7*baseb_out[nn*i3+1])/2); b1=final_gain*(((t5*baseb_out[nn*i4+2]-t6*baseb_out[nn*i1+2])/3 +t4*baseb_out[nn*i2+2]-t7*baseb_out[nn*i3+2])/2); b2=final_gain*(((t5*baseb_out[nn*i4+3]-t6*baseb_out[nn*i1+3])/3 +t4*baseb_out[nn*i2+3]-t7*baseb_out[nn*i3+3])/2); if(bg_expand != 2) { t1=a1*a1+a2*a2; t2=b1*b1+b2*b2; if(t1 < t2)t1=t2; t1=sqrt(t1); if(t1 > 0.5) { if(t1 bg_amplimit)t1=bg_amplimit; if(t1 < -bg_amplimit)t1=-bg_amplimit; if(t2 > bg_amplimit)t2=bg_amplimit; if(t2 < -bg_amplimit)t2=-bg_amplimit; if(bg_maxamp < t1)bg_maxamp=t1; if(bg_maxamp < t2)bg_maxamp=t2; if(rx_daout_bytes == 1) { daout[daout_pa]=0x80+t1; daout[daout_pa+1]=0x80+t2; } else { intvar=(void*)(&daout[daout_pa]); intvar[0]=t1; intvar[1]=t2; } } } r1=r2; daout_pa=(daout_pa+mm)&daout_bufmask; if(daout_pa == 0) { baseb_fx+=r2; r1=0; da_resample_ratio=new_da_resample_ratio; if(baseb_fx>baseband_size)baseb_fx-=baseband_size; } goto resamp; } } void chk_bg_avgnum(void) { if(fft3_blocktime*bg.fft_avgnum > genparm[BASEBAND_STORAGE_TIME]) bg.fft_avgnum=genparm[BASEBAND_STORAGE_TIME]/fft3_blocktime; if(bg.fft_avgnum >9999)bg.fft_avgnum=9999; if(bg.fft_avgnum <1)bg.fft_avgnum=1; if(bg.afc2_delay>bg.fft_avgnum/2+1) { bg.afc2_delay=bg.fft_avgnum/2+1; } } void clear_agc(void) { // The AGC attack is operated from two series connected low pass filters. // followed by a peak detector. // The AGC is in the function coherent(); agc_factor=1; agc_sumpow1=0; agc_sumpow2=0; agc_attack_factor1=pow(0.5,1000./(baseband_sampling_speed*(1<>3; baseband_sizhalf=baseband_size>>1; // The time stored in the baseband buffers is // baseband_size/baseband_sampling_speed, the same time is contained in // the basblock buffers in mix2_size/2 fewer points. // Find out the number of basblock points that correspond to // 5 seconds, the time constant for dB meter peak hold. basblock_size=2*baseband_size/mix2_size; basblock_mask=basblock_size-1; basblock_hold_points=5*basblock_size*baseband_sampling_speed/baseband_size; if(basblock_hold_points<3)basblock_hold_points=3; if(basblock_hold_points>basblock_mask)basblock_hold_points=basblock_mask; // When listening to wideband signals, the time between basblock // points may become short. // Make sure we do not update the coherent graph too often, // graphics may be rather slow. cg_update_interval=basblock_hold_points/20; cg_update_count=0; clear_agc(); // ******************************************************** init_memalloc(basebmem, MAX_BASEB_ARRAYS); mem(1,&baseb_out,baseband_size*2*baseb_channels*sizeof(float),0); mem(2,&baseb_carrier,baseband_size*2*sizeof(float),0); mem(3,&baseb_raw,baseband_size*2*sizeof(float),0); mem(4,&baseb_raw_orthog,baseband_size*2*sizeof(float),0); mem(5,&baseb,baseband_size*2*sizeof(float),0); mem(6,&baseb_totpwr,baseband_size*sizeof(float),0); mem(7,&baseb_carrier_ampl,baseband_size*sizeof(float),0); mem(8,&mix2_permute,mix2_size*sizeof(short int),0); mem(9,&mix2_table,mix2_size*sizeof(COSIN_TABLE)/2,0); // allocate space so we will not overflow even if channels // and bytes become doubled. mem(10,&daout,daout_size*4,0); mem(11,&cg_map,cg_size*cg_size*sizeof(float),0); mem(13,&cg_traces,CG_MAXTRACE*MAX_CG_OSCW*sizeof(short int),0); mem(14,&baseb_upthreshold,baseband_size*sizeof(float),0); mem(15,&baseb_threshold,baseband_size*sizeof(float),0); mem(16,&basblock_maxpower,basblock_size*sizeof(float),0); mem(17,&basblock_avgpower,basblock_size*sizeof(float),0); mem(18,&baseb_agc_level,baseband_size*sizeof(float),0); mem(27,&baseb_ramp,baseband_size*sizeof(short int),0); if(genparm[CW_DECODE_ENABLE] != 0) { cw_spectrum_size=bg_flatpoints+1.5*bg_curvpoints; mem(19,&baseb_envelope,baseband_size*2*sizeof(float),0); mem(21,&dash_waveform,cw_waveform_max*2*sizeof(float),0); mem(22,&dot_waveform,cw_waveform_max*sizeof(float),0); mem(23,&baseb_fit,baseband_size*2*sizeof(float),0); mem(24,&mix2_window,mix2_size*sizeof(float),0); mem(25,&mix2_tmp,2*mix2_size*sizeof(float),0); mem(26,&mix2_pwr,mix2_size*sizeof(float),0); mem(28,&baseb_tmp,baseband_size*2*sizeof(float),0); mem(281,&baseb_sho1,baseband_size*2*sizeof(float),0); mem(282,&baseb_sho2,baseband_size*2*sizeof(float),0); mem(283,&baseb_wb_raw,baseband_size*2*sizeof(float),0); mem(284,&baseb_wb,baseband_size*2*sizeof(float),0); mem(30,&cw,max_cwdat*sizeof(MORSE_DECODE_DATA),0); mem(31,&cw_spectrum,2*cw_spectrum_size*sizeof(float),0); } baseband_totmem=memalloc((int*)(&baseband_handle),"baseband"); if(baseband_totmem == 0 || lir_status==LIR_MEMERR) { lir_status=LIR_OK; baseband_size/=2; lir_pixwrite(bg.xleft+text_width,bg.ybottom-4*text_height,"BUFFERS REDUCED"); goto reduce; } k=fft3_size/mix2_size; mix2_n=fft3_n; while(k>1) { mix2_n--; k/=2; } init_fft(0,mix2_n, mix2_size, mix2_table, mix2_permute); if(genparm[CW_DECODE_ENABLE] != 0) { make_window(9,mix2_size, 2, mix2_window); } for(i=0; i baseband_size)clr_size=baseband_size; memset(baseb_raw,0,2*clr_size*sizeof(float)); memset(baseb_raw_orthog,0,2*clr_size*sizeof(float)); lir_sched_yield(); memset(baseb_carrier,0,2*clr_size*sizeof(float)); memset(baseb,0,2*clr_size*sizeof(float)); memset(baseb_agc_level,0,clr_size*sizeof(float)); memset(baseb_totpwr,0,clr_size*sizeof(float)); memset(baseb_carrier_ampl,0,clr_size*sizeof(float)); memset(baseb_upthreshold,0,clr_size*sizeof(float)); memset(baseb_threshold,0,clr_size*sizeof(float)); memset(baseb_ramp,0,clr_size*sizeof(short int)); lir_sched_yield(); if(genparm[CW_DECODE_ENABLE] != 0) { for(i=0; i<2*clr_size; i++) { baseb_envelope[i]=0; baseb_fit[i]=0; baseb_tmp[i]=0; baseb_sho1[i]=0; baseb_sho2[i]=0; } for(i=0; i= 0)clear_da(); daout_phase=0; old_baseb_channels=baseb_channels; if(kill_all_flag)return; clear_coherent(); am_dclevel1=0; am_dclevel2=0; am_dclevel_factor1=pow(0.5,100./(baseband_sampling_speed*(1<bg_ymax-2) { lir_setpixel(i,bg_filterfunc_y[i],bg_background[bg_filterfunc_y[i]]); } if(bg_carrfilter_y[i] < bg.ybottom && bg_carrfilter_y[i] >bg_ymax-2) { lir_setpixel(i,bg_carrfilter_y[i],bg_background[bg_carrfilter_y[i]]); } } // pos is the fft bin in fft3 that we want to have our filter // centered around. // The center point of the graph is always fft3_size/2 for(i=bg_first_xpixel; i<=bg_last_xpixel; i++) { bg_filterfunc_y[i]=-1; bg_carrfilter_y[i]=-1; } j=pos-fft3_size/2+bg_first_xpoint; for(i=bg_first_xpixel; i<=bg_last_xpixel; i+=bg.pixels_per_point) { k=j; if(k<0)k=0; if(k>=fft3_size)k=fft3_size-1; if(bg_filterfunc[k] != 0) { y=2*bg.yfac_log*log10(1./bg_filterfunc[k]); y=bg_ymax-1+y; } else { y=bg_y0+1; } if(y>bg_y0)y=bg_y0+1; bg_filterfunc_y[i]=y; lir_setpixel(i,y,14); if(bg_carrfilter[k] != 0) { y=2*bg.yfac_log*log10(1./bg_carrfilter[k]); y=bg_ymax-1+y; } else { y=bg_y0+1; } if(y>bg_y0)y=bg_y0+1; bg_carrfilter_y[i]=y; lir_setpixel(i,y,14); j++; } } void make_bg_filter(void) { int i,k,max,mm; float t1,t2,t3; // Set up the filter function in the baseband for // the main signal and show it on the screen. // bg.filter_flat is the size of the flat region // of the filter in Hz (divided by 2) // bg.filter_curv is the curvature expressed as ten times the distance // to the 6dB point from the end of the flat region. // The filter response is a flat center region with parabolic fall off. for(i=0; i>1)-4; if(use_bfo == 0) { max=k; } else { max=genparm[DA_OUTPUT_SPEED]*0.35/bg_hz_per_pixel; if(max>k)max=k; } bg_flatpoints=1+bg.filter_flat/bg_hz_per_pixel; bg_curvpoints=1+0.1*bg.filter_curv/bg_hz_per_pixel; if( afc2_active_flag != 0 || genparm[CW_DECODE_ENABLE] != 0) { k=bg_xpixels/(2*bg.pixels_per_point)-NOISE_SEP- NOISE_FILTERS*(NOISE_POINTS+NOISE_SEP)-1; if(max>k)max=k; k=bg_flatpoints+2*bg_curvpoints-max; if(k>0) { k/=2; bg_flatpoints-=k; if(bg_flatpoints<1)bg_flatpoints=1; bg_curvpoints=(max-bg_flatpoints-1)/2; if(bg_curvpoints < 1) { k=1+2*bg_curvpoints; bg_flatpoints+=k; bg_curvpoints=1; } bg.filter_flat=bg_hz_per_pixel*(bg_flatpoints-1); bg.filter_curv=10*bg_hz_per_pixel*bg_curvpoints; bg_curvpoints=1+0.1*bg.filter_curv/bg_hz_per_pixel; } } else { k=bg_flatpoints+bg_curvpoints-max; if(k>0) { k/=2; bg_flatpoints-=k; if(bg_flatpoints<1)bg_flatpoints=1; bg_curvpoints=max-bg_flatpoints-1; if(bg_curvpoints < 1) { k=1+bg_curvpoints; bg_flatpoints+=k; bg_curvpoints=1; } bg.filter_flat=bg_hz_per_pixel*(bg_flatpoints-1); bg.filter_curv=10*bg_hz_per_pixel*bg_curvpoints; bg_curvpoints=1+0.1*bg.filter_curv/bg_hz_per_pixel; } } bgfil_weight=0; for(i=1; i<=bg_flatpoints; i++) { bg_filterfunc[fft3_size/2+i-1]=1; bg_filterfunc[fft3_size/2-i]=1; bgfil_weight+=2; } mm=bg_flatpoints+1; t1=.5/bg_curvpoints; t2=1; t3=t1; t2=1-t3*t3; t3+=t1; while(t2 > 0 && mm>1) ) { lirerr(1163); return; } // The filter we just specified determines the bandwidth of // the signal we recover when backtransforming from fft3. // Find out by what factor we should reduce the sampling speed // for further processing k=(1.5*(fft3_size+mm))/mm; make_power_of_two(&k); if(genparm[CW_DECODE_ENABLE] != 0)k/=2; k/=8; if(k > 2) { t1=timf3_sampling_speed/k; if(t1 > baseband_sampling_speed || t1 < 8*baseband_sampling_speed) { baseband_sampling_speed=2*t1; if(mix2_size != 2*fft3_size/k) { mix2_size=2*fft3_size/k; init_basebmem(); } } } else { if(mix2_size != fft3_size || baseband_sampling_speed == 0) { baseband_sampling_speed=timf3_sampling_speed; mix2_size=fft3_size; init_basebmem(); } } baseb_margin=2+baseband_sampling_speed/genparm[DA_OUTPUT_SPEED]; if(baseb_channels != old_baseb_channels) { init_basebmem(); } if(kill_all_flag) return; while(mm<=fft3_size/2) { bg_filterfunc[fft3_size/2+mm-1]=0; bg_filterfunc[fft3_size/2-mm]=0; mm++; } if(mix2_size>fft3_size) { lirerr(88888); return; } for(i=0; i 0 && mm<=fft3_size/2) { bg_carrfilter[fft3_size/2+mm]=t2; bg_carrfilter[fft3_size/2-mm]=t2; carrfil_weight+=2*t2*t2; t2=1-t3*t3; t3+=t1; mm++; } // Place the current filter function on the screen. show_bg_filterfunc(fft3_size/2); // Place the BFO line on the screen and make bfo related stuff. make_bfo(); baseband_bw_hz=2*bg_hz_per_pixel*(bg_flatpoints+bg_curvpoints); baseband_bw_fftxpts=baseband_bw_hz*mix1_points_per_hz; } void check_bg_cohfac(void) { int i,j,k; if(use_bfo != 0) { if(bg.coh_factor < 3)bg.coh_factor=3; } else { if(bg.coh_factor < 1)bg.coh_factor=1; } j=0; k=(bg_y1+bg_y2)/2; for(i=bg_first_xpixel; i<=bg_last_xpixel; i+=bg.pixels_per_point) { if(bg_filterfunc_y[i] > bg.yborder+text_height && bg_filterfunc_y[i]999)j=999; if(bg.coh_factor > j)bg.coh_factor=j; } void new_bg_cohfac(void) { bg.coh_factor=numinput_int_data; check_bg_cohfac(); make_baseband_graph(TRUE); } void new_bg_delpnts(void) { bg.delay_points=numinput_int_data; if(bg.delay_points < 1)bg.delay_points=1; if(bg.delay_points > 999)bg.delay_points=999; sc[SC_BG_BUTTONS]++; } void new_bg_agc_attack(void) { bg.agc_attack=numinput_int_data; sc[SC_BG_BUTTONS]++; make_modepar_file(GRAPHTYPE_BG); clear_agc(); } void new_bg_agc_release(void) { bg.agc_release=numinput_int_data; am_dclevel_factor1=pow(0.5,100./(baseband_sampling_speed*(1<bg.fft_avgnum/2+1)bg.afc2_delay=bg.fft_avgnum/2+1; sc[SC_BG_BUTTONS]++; make_modepar_file(GRAPHTYPE_BG); if(new_baseb_flag >= 0) clear_da(); } void new_bg_waterfall_zero(void) { bg.waterfall_zero=numinput_float_data; sc[SC_BG_BUTTONS]++; make_bg_waterf_cfac(); make_modepar_file(GRAPHTYPE_BG); sc[SC_BG_WATERF_REDRAW]++; } void help_on_baseband_graph(void) { int msg_no; int event_no; // Set msg invalid in case we are not in any select area. msg_no=-1; if(mouse_y < bg_y0) { if(mouse_x < bg_first_xpixel) { if(mouse_x >= bg_vol_x1 && mouse_x <= bg_vol_x2 && mouse_y >= bg_ymax) { msg_no=33; } } else { if(mouse_x < bg.xright-text_width-6) { msg_no=34; } } } for(event_no=0; event_no= mouse_x && bgbutt[event_no].y1 <= mouse_y && bgbutt[event_no].y2 >= mouse_y) { switch (event_no) { case BG_TOP: case BG_BOTTOM: case BG_LEFT: case BG_RIGHT: case BG_YBORDER: msg_no=100; break; case BG_YSCALE_EXPAND: msg_no=35; break; case BG_YSCALE_CONTRACT: msg_no=36; break; case BG_YZERO_DECREASE: msg_no=37; break; case BG_YZERO_INCREASE: msg_no=38; break; case BG_RESOLUTION_DECREASE: msg_no=39; break; case BG_RESOLUTION_INCREASE: msg_no=40; break; case BG_OSCILLOSCOPE: msg_no=41; break; case BG_OSC_INCREASE: msg_no=42; break; case BG_OSC_DECREASE: msg_no=43; break; case BG_PIX_PER_PNT_INC: msg_no=44; break; case BG_PIX_PER_PNT_DEC: msg_no=45; break; case BG_TOGGLE_EXPANDER: msg_no=46; break; case BG_TOGGLE_COHERENT: msg_no=47; break; case BG_TOGGLE_PHASING: msg_no=48; break; case BG_TOGGLE_TWOPOL: msg_no=49; break; case BG_TOGGLE_CHANNELS: msg_no=50; break; case BG_TOGGLE_BYTES: msg_no=51; break; case BG_SEL_COHFAC: msg_no=52; break; case BG_SEL_DELPNTS: msg_no=53; break; case BG_SEL_FFT3AVGNUM: msg_no=63; break; case BG_TOGGLE_AGC: msg_no=79; break; case BG_SEL_AGC_ATTACK: msg_no=80; break; case BG_SEL_AGC_RELEASE: msg_no=81; break; case BG_WATERF_ZERO: msg_no=64; break; case BG_WATERF_GAIN: msg_no=66; break; case BG_WATERF_AVGNUM: msg_no=61; break; case BG_AFC2_RANGE: msg_no=88; break; case BG_AFC2_DELAY: msg_no=89; break; } } } help_message(msg_no); } void change_fft3_avgnum(void) { int j,k; bg.fft_avgnum=numinput_int_data; chk_bg_avgnum(); make_modepar_file(GRAPHTYPE_BG); if(sw_onechan) { for(k=bg_first_xpixel; k<=bg_last_xpixel; k++) { lir_setpixel(k,fft3_spectrum[k],bg_background[fft3_spectrum[k]]); fft3_spectrum[k]=bg_y0; } } else { for(k=bg_first_xpixel; k<=bg_last_xpixel; k++) { for(j=2*k; j<2*k+2; j++) { lir_setpixel(k,fft3_spectrum[j],bg_background[fft3_spectrum[j]]); fft3_spectrum[j]=bg_y0; } } } make_baseband_graph(FALSE); } void change_bg_waterf_avgnum(void) { bg.waterfall_avgnum=numinput_int_data; make_modepar_file(GRAPHTYPE_BG); make_bg_yfac(); sc[SC_BG_BUTTONS]++; } void make_agc_amplimit(void) { bg_agc_amplimit=bg_amplimit*0.18; if(rx_mode==MODE_AM) { bg_agc_amplimit*=1.2; if(bg_coherent != 0) bg_agc_amplimit*=.75; } } void mouse_continue_baseband_graph(void) { int j; switch (mouse_active_flag-1) { case BG_TOP: if(bg.ytop!=mouse_y) { pause_screen_and_hide_mouse(); dual_graph_borders((void*)&bg,0); bg.ytop=mouse_y; j=bg.ybottom-BG_MINYCHAR*text_height; if(bg.ytop > j)bg.ytop=j; if(bg_old_y1 > bg.ytop)bg_old_y1=bg.ytop; dual_graph_borders((void*)&bg,15); resume_thread(THREAD_SCREEN); } break; case BG_BOTTOM: if(bg.ybottom!=mouse_y) { pause_screen_and_hide_mouse(); dual_graph_borders((void*)&bg,0); bg.ybottom=mouse_y; j=bg.yborder+BG_MINYCHAR*text_height; if(bg.ybottom < j)bg.ybottom=j; if(bg.ybottom >= screen_height)bg.ybottom=screen_height-1; if(bg_old_y2 < bg.ybottom)bg_old_y2=bg.ybottom; dual_graph_borders((void*)&bg,15); resume_thread(THREAD_SCREEN); } break; case BG_LEFT: if(bg.xleft!=mouse_x) { pause_screen_and_hide_mouse(); dual_graph_borders((void*)&bg,0); bg.xleft=mouse_x; j=bg.xright-BG_MIN_WIDTH; if(j<0)j=0; if(bg.xleft > j)bg.xleft=j; if(bg_old_x1 > bg.xleft)bg_old_x1=bg.xleft; dual_graph_borders((void*)&bg,15); resume_thread(THREAD_SCREEN); } break; case BG_RIGHT: if(bg.xright!=mouse_x) { pause_screen_and_hide_mouse(); dual_graph_borders((void*)&bg,0); bg.xright=mouse_x; j=bg.xleft+BG_MIN_WIDTH; if(j>=screen_width)j=screen_width-1; if(bg.xright < j)bg.xright=j; if(bg_old_x2 < bg.xright)bg_old_x2=bg.xright; dual_graph_borders((void*)&bg,15); resume_thread(THREAD_SCREEN); } break; case BG_YBORDER: if(bg.yborder!=mouse_y) { pause_screen_and_hide_mouse(); dual_graph_borders((void*)&bg,0); bg.yborder=mouse_y; if(bg.yborder < bg_yborder_min)bg.yborder = bg_yborder_min; if(bg.yborder > bg_yborder_max)bg.yborder = bg_yborder_max; dual_graph_borders((void*)&bg,15); resume_thread(THREAD_SCREEN); } break; default: goto await_release; } if(leftpressed == BUTTON_RELEASED)goto finish; return; await_release:; if(leftpressed != BUTTON_RELEASED) return; switch (mouse_active_flag-1) { case BG_YSCALE_EXPAND: bg.yrange/=1.5; break; case BG_YSCALE_CONTRACT: bg.yrange*=1.5; break; case BG_YZERO_DECREASE: bg.yzero/=1.5; break; case BG_YZERO_INCREASE: bg.yzero*=1.5; break; case BG_RESOLUTION_DECREASE: bg.bandwidth/=2; break; case BG_RESOLUTION_INCREASE: bg.bandwidth*=2; break; case BG_OSCILLOSCOPE: bg_oscill_on^=1; break; case BG_OSC_INCREASE: if(bg_oscill_on != 0) { bg_oscill_gain*=5; } break; case BG_OSC_DECREASE: if(bg_oscill_on != 0) { bg_oscill_gain*=0.25; } break; case BG_PIX_PER_PNT_INC: bg.pixels_per_point++; if(bg.pixels_per_point > 16)bg.pixels_per_point=16; break; case BG_PIX_PER_PNT_DEC: bg.pixels_per_point--; if(bg.pixels_per_point < 1)bg.pixels_per_point=1; break; case BG_TOGGLE_EXPANDER: bg_expand++; if(bg_expand > 2)bg_expand=0; break; case BG_TOGGLE_COHERENT: bg_coherent++; if(bg_coherent > 3)bg_coherent=0; if(rx_mode == MODE_FM && bg_coherent > 2)bg_coherent=0; if(bg_coherent == 0)bg_da_channels=1+((genparm[OUTPUT_MODE]>>1)&1); bg_twopol=0; bg_delay=0; make_agc_amplimit(); break; case BG_TOGGLE_PHASING: if(bg_coherent == 0) { bg_twopol=0; bg_delay^=1; if(bg_delay == 0)bg_da_channels=1+((genparm[OUTPUT_MODE]>>1)&1); } break; case BG_TOGGLE_TWOPOL: if(bg_coherent == 0) { bg_delay=0; bg_twopol^=1; if(bg_twopol == 0)bg_da_channels=1+((genparm[OUTPUT_MODE]>>1)&1); } break; case BG_TOGGLE_CHANNELS: bg_da_channels++; if(bg_da_channels>ui.rx_max_da_channels) bg_da_channels=ui.rx_min_da_channels; break; case BG_TOGGLE_BYTES: bg_da_bytes++; if(bg_da_bytes>ui.rx_max_da_bytes)bg_da_bytes=ui.rx_min_da_bytes; break; case BG_TOGGLE_AGC: bg.agc_flag++; bg.agc_flag &= 1; clear_agc(); break; case BG_SEL_COHFAC: mouse_active_flag=1; numinput_xpix=bgbutt[BG_SEL_COHFAC].x1+7*text_width/2-1; numinput_ypix=bgbutt[BG_SEL_COHFAC].y1+2; numinput_chars=3; erase_numinput_txt(); numinput_flag=FIXED_INT_PARM; par_from_keyboard_routine=new_bg_cohfac; return; case BG_SEL_DELPNTS: mouse_active_flag=1; numinput_xpix=bgbutt[BG_SEL_DELPNTS].x1+3*text_width/2-1; numinput_ypix=bgbutt[BG_SEL_DELPNTS].y1+2; numinput_chars=2; erase_numinput_txt(); numinput_flag=FIXED_INT_PARM; par_from_keyboard_routine=new_bg_delpnts; return; case BG_SEL_FFT3AVGNUM: mouse_active_flag=1; numinput_xpix=bgbutt[BG_SEL_FFT3AVGNUM].x1+text_width/2-1; numinput_ypix=bgbutt[BG_SEL_FFT3AVGNUM].y1+2; numinput_chars=4; erase_numinput_txt(); numinput_flag=FIXED_INT_PARM; par_from_keyboard_routine=change_fft3_avgnum; return; case BG_WATERF_AVGNUM: mouse_active_flag=1; numinput_xpix=bgbutt[BG_WATERF_AVGNUM].x1+text_width/2-1; numinput_ypix=bgbutt[BG_WATERF_AVGNUM].y1+2; numinput_chars=4; erase_numinput_txt(); numinput_flag=FIXED_INT_PARM; par_from_keyboard_routine=change_bg_waterf_avgnum; return; case BG_SEL_AGC_ATTACK: mouse_active_flag=1; numinput_xpix=bgbutt[BG_SEL_AGC_ATTACK].x1+3*text_width/2-1; numinput_ypix=bgbutt[BG_SEL_AGC_ATTACK].y1+2; numinput_chars=1; erase_numinput_txt(); numinput_flag=FIXED_INT_PARM; par_from_keyboard_routine=new_bg_agc_attack; return; case BG_SEL_AGC_RELEASE: mouse_active_flag=1; numinput_xpix=bgbutt[BG_SEL_AGC_RELEASE].x1+3*text_width/2-1; numinput_ypix=bgbutt[BG_SEL_AGC_RELEASE].y1+2; numinput_chars=1; erase_numinput_txt(); numinput_flag=FIXED_INT_PARM; par_from_keyboard_routine=new_bg_agc_release; return; case BG_WATERF_ZERO: mouse_active_flag=1; numinput_xpix=bgbutt[BG_WATERF_ZERO].x1+text_width/2-1; numinput_ypix=bgbutt[BG_WATERF_ZERO].y1+2; numinput_chars=5; erase_numinput_txt(); numinput_flag=FIXED_FLOAT_PARM; par_from_keyboard_routine=new_bg_waterfall_zero; return; case BG_WATERF_GAIN: mouse_active_flag=1; numinput_xpix=bgbutt[BG_WATERF_GAIN].x1+text_width/2-1; numinput_ypix=bgbutt[BG_WATERF_GAIN].y1+2; numinput_chars=4; erase_numinput_txt(); numinput_flag=FIXED_FLOAT_PARM; par_from_keyboard_routine=new_bg_waterfall_gain; return; case BG_AFC2_RANGE: if( (genparm[AFC_ENABLE] != 0 && ag.mode_control != 0) || bg_coherent !=0) { mouse_active_flag=1; numinput_xpix=bgbutt[BG_AFC2_RANGE].x1+9*text_width/2-1; numinput_ypix=bgbutt[BG_AFC2_RANGE].y1+2; numinput_chars=2; erase_numinput_txt(); numinput_flag=FIXED_INT_PARM; par_from_keyboard_routine=new_bg_afc2_range; return; } break; case BG_AFC2_DELAY: if( (genparm[AFC_ENABLE] != 0 && ag.mode_control != 0) || bg_coherent !=0) { mouse_active_flag=1; numinput_xpix=bgbutt[BG_AFC2_DELAY].x1+9*text_width/2-1; numinput_ypix=bgbutt[BG_AFC2_DELAY].y1+2; numinput_chars=3; erase_numinput_txt(); numinput_flag=FIXED_INT_PARM; par_from_keyboard_routine=new_bg_afc2_delay; return; } break; } finish:; leftpressed=BUTTON_IDLE; mouse_active_flag=0; make_baseband_graph(TRUE); } void clear_bfo(void) { int i; if(bfo_xpixel > 0) { for(i=bg_y1; i<=bg_y0; i++)lir_setpixel(bfo100_xpixel, i,bg_background[i]); for(i=bg_y2; i bg.yborder-mouse_y) { bg_curvpoints=10*(k-bg_flatpoints-bg_curvpoints/2); if(bg_curvpoints<1)bg_curvpoints=1; bg.filter_curv=bg_hz_per_pixel*bg_curvpoints; bg_curvpoints=1+0.1*bg.filter_curv/bg_hz_per_pixel; } else { bg_flatpoints=k; bg.filter_flat=bg_hz_per_pixel*bg_flatpoints; bg_flatpoints=1+bg.filter_flat/bg_hz_per_pixel; } make_bg_filter(); break; case BG_VOLUME: old=daout_gain_y; daout_gain_y=mouse_y; make_daout_gain(); update_bar(bg_vol_x1,bg_vol_x2,bg_y0,daout_gain_y,old, BG_GAIN_COLOR,bg_volbuf); break; } if(kill_all_flag)return; lir_sched_yield(); if(leftpressed == BUTTON_RELEASED) { leftpressed=BUTTON_IDLE; make_modepar_file(GRAPHTYPE_BG); // Restart output. It stops in case resampling_ratio was changed if(bfo_flag == BG_FILTER && new_baseb_flag >= 0)clear_da(); mouse_active_flag=0; } } void mouse_on_baseband_graph(void) { int event_no; // First find out if we are on a button or border line. for(event_no=0; event_no= mouse_x && bgbutt[event_no].y1 <= mouse_y && bgbutt[event_no].y2 >= mouse_y) { bg_old_y1=bg.ytop; bg_old_y2=bg.ybottom; bg_old_x1=bg.xleft; bg_old_x2=bg.xright; mouse_active_flag=1+event_no; current_mouse_activity=mouse_continue_baseband_graph; return; } } // Not button or border. // User wants to change filter, bfo freq or gain. // We use the upper part to change the flat region and // the lower part to change steepness. bfo_flag=0; if(mouse_y < bg_y0 && mouse_y > bg_ymax) { if(mouse_x >= bg_first_xpixel) { bfo_flag = BG_FILTER; if(use_bfo != 0) { if( mouse_y <= bg_y2 && abs(mouse_x-bfo_xpixel) < 5) { bfo_flag=BG_BFO; } if(mouse_y >= bg_y2 && mouse_y <= bg_y1 && abs(mouse_x-bfo10_xpixel) < 5) { bfo_flag=BG_BFO10; } if(mouse_y > bg_y1 && abs(mouse_x-bfo100_xpixel) < 5) { bfo_flag=BG_BFO100; } } } else { bfo_flag=BG_VOLUME; } } if(bfo_flag != 0) { current_mouse_activity=baseb_par_control; } else { current_mouse_activity=mouse_nothing; } mouse_active_flag=1; } void fft3_size_error(char *txt) { int i; settextcolor(15); i=bg.yborder; while(i bg_yborder_max) { bg.yborder=(bg_yborder_max+bg_yborder_min) >> 1; } bg_ymax=bg.yborder+text_height+4; bg_y0=bg.ybottom-3*text_height; bg_y1=(2*bg_y0+bg_ymax)/3; bg_y2=(bg_y0+2*bg_ymax)/3; bg_avg_counter=0; scro[baseband_graph_scro].no=BASEBAND_GRAPH; scro[baseband_graph_scro].x1=bg.xleft; scro[baseband_graph_scro].x2=bg.xright; scro[baseband_graph_scro].y1=bg.ytop; scro[baseband_graph_scro].y2=bg.ybottom; bgbutt[BG_LEFT].x1=bg.xleft; bgbutt[BG_LEFT].x2=bg.xleft; bgbutt[BG_LEFT].y1=bg.ytop; bgbutt[BG_LEFT].y2=bg.ybottom; bgbutt[BG_RIGHT].x1=bg.xright; bgbutt[BG_RIGHT].x2=bg.xright; bgbutt[BG_RIGHT].y1=bg.ytop; bgbutt[BG_RIGHT].y2=bg.ybottom; bgbutt[BG_TOP].x1=bg.xleft; bgbutt[BG_TOP].x2=bg.xright; bgbutt[BG_TOP].y1=bg.ytop; bgbutt[BG_TOP].y2=bg.ytop; bgbutt[BG_BOTTOM].x1=bg.xleft; bgbutt[BG_BOTTOM].x2=bg.xright; bgbutt[BG_BOTTOM].y1=bg.ybottom; bgbutt[BG_BOTTOM].y2=bg.ybottom; bgbutt[BG_YBORDER].x1=bg.xleft; bgbutt[BG_YBORDER].x2=bg.xright; bgbutt[BG_YBORDER].y1=bg.yborder; bgbutt[BG_YBORDER].y2=bg.yborder; // Draw the border lines dual_graph_borders((void*)&bg,7); // Set variables that depend on output format. old_da_chan=rx_daout_channels; old_da_bytes=rx_daout_bytes; if(baseb_channels < 1)baseb_channels=1; rx_daout_bytes=bg_da_bytes; rx_daout_channels=bg_da_channels; baseb_channels=1; if(bg_coherent > 0 && bg_coherent != 3) { if(ui.rx_max_da_channels == 1) { bg_coherent=0; } else { baseb_channels=2; } } if(bg_delay != 0) { if(ui.rx_max_da_channels == 1) { bg_delay=0; } else { baseb_channels=2; } } if(bg_twopol != 0) { if(ui.rx_max_da_channels == 1) { bg_twopol=0; } else { baseb_channels=2; } } if(rx_daout_channels < baseb_channels)rx_daout_channels=baseb_channels; if(rx_daout_channels > ui.rx_max_da_channels) rx_daout_channels=ui.rx_max_da_channels; if(rx_daout_channels < ui.rx_min_da_channels) rx_daout_channels=ui.rx_min_da_channels; bg_da_channels=rx_daout_channels; if( baseb_channels == 1 && rx_daout_channels == 2 && bg_delay == 0 && bg_twopol == 0 && ui.rx_min_da_channels == 1) { da_ch2_sign=-1; } else { da_ch2_sign=1; } daout_samps=rx_daout_block/(rx_daout_channels*rx_daout_bytes); if( (old_da_chan != rx_daout_channels || old_da_bytes != rx_daout_bytes) && new_baseb_flag >=0)clear_da(); if(rx_daout_bytes == 1)bg_amplimit=126; else bg_amplimit=32000; // The expander (if enabled) expands the amplitude with an // exponential function y = A* (exp(B*x)-1) // 0 <= x <= bg_amplimit // y is always 0 for x=0. // Make y=bg_amplimit/2 for x=bg_amplimit bg_expand_b=genparm[AMPLITUDE_EXPAND_EXPONENT]/bg_amplimit; bg_expand_a=bg_amplimit/(exp(bg_expand_b*bg_amplimit)-1); bg_maxamp=0; bg_amp_indicator_y=bg_y0-3; // Set up all the variables that depend on the window parameters. bg_first_xpixel=bg.xleft+4*text_width; bg_last_xpixel=bg.xright-2*text_width; bg_xpoints = 2+(bg_last_xpixel-bg_first_xpixel)/bg.pixels_per_point; bg_xpixels=bg_last_xpixel-bg_first_xpixel+1; bg_vol_x1=bg.xleft+text_width; bg_vol_x2=bg_vol_x1+5*text_width/2; volbuf_bytes=(bg_y0-bg_ymax+2)*(bg_vol_x2-bg_vol_x1+2)*sizeof(char); fft3_size=2*timf3_sampling_speed/bg.bandwidth; if(fft3_size < 1)fft3_size=1; i=fft3_size; make_power_of_two(&fft3_size); if(fft3_size > 1.5*i)fft3_size>>=1; while(fft3_size < bg_xpoints)fft3_size<<=1; if(fft3_size > 0x8000) { fft3_size=0x8000; fft3_size_error("Max N = 15"); } sizold=fft3_size; while(2*fft3_size*ui.rx_rf_channels+timf3_block > 0.8*timf3_size)fft3_size/=2; if(sizold != fft3_size) { sizold=fft3_size; if(genparm[SECOND_FFT_ENABLE] == 0) { fft3_size_error("fft1 storage time"); } else { fft3_size_error("fft2 storage time"); } } while(2*fft3_size/timf3_sampling_speed > genparm[BASEBAND_STORAGE_TIME])fft3_size/=2; if(sizold != fft3_size) { fft3_size_error("baseband storage time"); } // fft3 uses sin squared window with interleave factor=2 new_fft3:; fft3_n=0; i=fft3_size; while(i != 1) { i>>=1; fft3_n++; } bg.bandwidth=1.9*timf3_sampling_speed/fft3_size; bg_first_xpoint=(fft3_size-bg_xpoints)/2; bg_hz_per_pixel=timf3_sampling_speed/fft3_size; fft3_block=fft3_size*2*ui.rx_rf_channels*MAX_MIX1; fft3_tmpbytes=2*fft3_size*(ui.rx_rf_channels+1)*sizeof(float); fft3_blocktime=0.5*fft3_size/timf3_sampling_speed; chk_bg_avgnum(); // find out how much memory we need for the fft3 buffer. // First of all we need to hold the transforms that we use for averaging. i=bg.fft_avgnum+2; // And make sure it can hold two blocks of data from // the source time function. if(genparm[SECOND_FFT_ENABLE]!=0) { k=fft2_new_points; } else { k=fft1_new_points; } t1=2*k/timf1_sampling_speed; if(t1<2)t1=2; // make buffer big enough for t1 seconds of data if(i < t1*bg_hz_per_pixel*2) i=t1*bg_hz_per_pixel*2; if(i<4)i=4; make_power_of_two(&i); t1=fft3_block*i; if(t1*sizeof(float) > (float)(0x40000000)) { fft3_size/=2; fft3_size_error("RAM memory"); if(fft3_size >= bg_xpoints) { goto new_fft3; } bg.fft_avgnum/=2; goto new_fft3; } fft3_totsiz=fft3_block*i; fft3_totbytes=fft3_totsiz*sizeof(float); fft3_mask=fft3_totsiz-1; fft3_show_size=bg_xpoints*bg.fft_avgnum; bg_waterf_lines=bg.yborder-bg.ytop-text_height-YWF; bg_waterf_y1=bg.ytop+text_height+YWF+1; bg_waterf_y2=bg_waterf_y1+2+bg_waterf_lines/20; if(bg_waterf_y2 > bg_waterf_y1+bg_waterf_lines-1) bg_waterf_y2=bg_waterf_y1+bg_waterf_lines-1; bg_waterf_y=bg_waterf_y2; if(bg_waterf_y2 > bg.yborder-1)bg_waterf_y2=bg.yborder-1; bg_waterf_yinc=bg_waterf_y2-bg_waterf_y1+1; bg_waterf_size=bg_xpixels*bg_waterf_lines; max_bg_waterf_times=2+0.5*bg_waterf_lines/text_height; bg_waterf_ptr=0; local_bg_waterf_ptr=0; sc[SC_BG_WATERF_INIT]++; // *********************************************** if(fft3_handle != NULL) { fft3_handle=chk_free(fft3_handle); } init_memalloc(fft3mem,MAX_FFT3_ARRAYS); mem( 1,&fft3,fft3_totbytes,0); mem( 2,&fft3_win,fft3_size*sizeof(float),0); mem( 3,&fft3_tmp,fft3_tmpbytes,0); mem( 4,&fft3_tab,fft3_size*sizeof(COSIN_TABLE)/2,0); mem( 5,&fft3_permute,fft3_size*sizeof(short int),0); mem( 6,&fft3_fqwin_inv,fft3_size*sizeof(float),0); mem( 7,&fft3_power,fft3_show_size*ui.rx_rf_channels*sizeof(float),0); mem( 8,&fft3_slowsum,bg_xpoints*ui.rx_rf_channels*sizeof(float),0); mem( 9,&fft3_spectrum,screen_width*ui.rx_rf_channels*sizeof(short int),0); mem(10,&bg_background,screen_height*sizeof(char),0); mem(11,&bg_filterfunc,fft3_size*sizeof(float),0); mem(12,&bg_filterfunc_y,screen_width*sizeof(short int),0); mem(13,&bg_volbuf,volbuf_bytes,0); mem(14,&bg_behind_carrcur,3*text_height*sizeof(char),0); mem(15,&bg_carrfilter,fft3_size*sizeof(float),0); mem(16,&bg_carrfilter_y,screen_width*sizeof(short int),0); mem(17,&bg_waterf_sum,bg_xpoints*sizeof(float),0); mem(18,&bg_waterf,5000+bg_waterf_size*sizeof(short int),0); mem(19,&bg_waterf_times,max_bg_waterf_times*sizeof(WATERF_TIMES),0); // ********************************************** fft3_totmem=memalloc((int*)(&fft3_handle),"fft3"); if(fft3_totmem == 0) { fft3_size/=2; fft3_size_error("RAM memory"); if(fft3_size >= bg_xpoints) { goto new_fft3; } lirerr(1056); return; } k=MAX_MIX1*fft3_size*4*ui.rx_rf_channels; for(i=0; i bg_ymax) { if(scale_y+text_height/2+1 < bg_y0) { i=(int)(scale_value); sprintf(s,"%3d",i); lir_pixwrite(bg.xleft+text_width/2,(int)scale_y-text_height/2+2,s); } if(scale_y+1 < bg_y0) { i=scale_y; bg_background[i]=BG_DBSCALE_COLOR; lir_hline(bg_first_xpixel,i,bg_last_xpixel,BG_DBSCALE_COLOR); if(kill_all_flag) return; } scale_y-=db_scalestep/bg.db_per_pixel; scale_value+=db_scalestep; } // Init fft3_spectrum at the zero level. for(i=0; i 2)bg_coherent=0; check_bg_cohfac(); make_agc_amplimit(); bg_waterf_block=(bg_waterf_y2-bg_waterf_y1+1)*bg_xpixels; make_bg_waterf_cfac(); if(genparm[AFC_ENABLE]==0 || rx_mode >= MODE_SSB) { show_wheel_stepmult(); } resume_thread(THREAD_SCREEN); if(mix1_selfreq[0]>0)sc[SC_FREQ_READOUT]++; sc[SC_BG_FQ_SCALE]++; sc[SC_BG_BUTTONS]++; } void show_bg_maxamp(void) { unsigned char color; float t1; t1=bg_maxamp/bg_amplimit; t1*=bg_y0-bg_ymax-2; hide_mouse(bg_amp_indicator_x,bg_amp_indicator_x+text_width/2, bg_amp_indicator_y,bg_amp_indicator_y+3); lir_fillbox(bg_amp_indicator_x,bg_amp_indicator_y,text_width/2,3,0); bg_amp_indicator_y=bg_y0-t1-1; if(t1<1) { color=10; } else { if(bg_amp_indicator_y<=bg_ymax+3) { color=12; } else { color=7; } } hide_mouse(bg_amp_indicator_x,bg_amp_indicator_x+text_width/2, bg_amp_indicator_y,bg_amp_indicator_y+3); lir_fillbox(bg_amp_indicator_x,bg_amp_indicator_y,text_width/2,3,color); bg_maxamp=0; } void init_baseband_graph(void) { int i,errcnt; errcnt=0; if (read_modepar_file(GRAPHTYPE_BG) == 0) { bg_default:; // Make the default window for the high resolution graph. bg.xleft=hg.xright+2; bg.xright=bg.xleft+0.5*screen_width; if(bg.xright > screen_width) { bg.xright=screen_width-1; bg.xleft=bg.xright-BG_MIN_WIDTH; } bg.ytop=wg.ybottom+2; bg.yborder=bg.ytop+0.1*screen_height; bg.ybottom=bg.yborder+0.2*screen_height; if(bg.ybottom>screen_height-text_height-1)bg.ybottom=screen_height-text_height-1; bg.bandwidth=timf3_sampling_speed/256; bg.yrange=4096; bg.yzero=1; bg.filter_flat=150; bg.filter_curv=250; bg.bfo_freq=bg.filter_flat+0.1*bg.filter_curv+300; bg.output_gain=0.05; bg.check=BG_VERNR; bg.fft_avgnum=50; bg.pixels_per_point=1; bg.coh_factor=8; bg.delay_points=4; bg.agc_flag = 0; bg.agc_attack = 2; bg.agc_release = 4; bg.waterfall_avgnum=5; bg.waterfall_gain=1; bg.waterfall_zero=20; bg.afc2_range=99; bg.afc2_delay=0; bg.wheel_stepn=0; } if(bg.check != BG_VERNR)goto bg_default; errcnt++; if(errcnt < 2) { if(bg.xleft < 0 || bg.xleft > screen_last_xpixel)goto bg_default; if(bg.xright < 0 || bg.xright > screen_last_xpixel)goto bg_default; if(bg.xright-bg.xleft < BG_MIN_WIDTH)goto bg_default; if(bg.ytop < 0 || bg.ytop > screen_height-1)goto bg_default; if(bg.ybottom < 0 || bg.ybottom > screen_height-1)goto bg_default; if(bg.ybottom-bg.ytop < 6*text_height)goto bg_default; if(bg.pixels_per_point > 16)goto bg_default; if(bg.pixels_per_point < 1)goto bg_default; if(bg.coh_factor < 1 || bg.coh_factor > 999)goto bg_default; if(bg.delay_points < 0 || bg.delay_points > 999)goto bg_default; if(bg.waterfall_avgnum<1)goto bg_default; if(bg.afc2_delay < 0 || bg.afc2_delay > bg.fft_avgnum/2+1)goto bg_default; if(bg.afc2_range < 0 || bg.afc2_range > 99)goto bg_default; } if(bg.wheel_stepn<-30 || bg.wheel_stepn >30)bg.wheel_stepn=0; bfo_flag=0; bg_oscill_on=0; bg_oscill_gain=0.1; mix2_size=-1; new_baseb_flag=-1; bg_da_bytes=1+(genparm[OUTPUT_MODE]&1); //bit 0 bg_da_channels=1+((genparm[OUTPUT_MODE]>>1)&1); //bit 1 bg_expand=(genparm[OUTPUT_MODE]>>2)&3; //bit 2 and 3 bg_coherent=(genparm[OUTPUT_MODE]>>4)&3; //bits 4 and 5 if(bg_coherent > 3)bg_coherent=3; bg_delay=(genparm[OUTPUT_MODE]>>6)&1; //bit 6 bg_twopol=(genparm[OUTPUT_MODE]>>7)&1; //bit 7 baseb_channels=0; old_baseb_channels=0; baseband_sampling_speed=0; baseband_graph_scro=no_of_scro; bfo_xpixel=-1; make_baseband_graph(FALSE); no_of_scro++; if(no_of_scro >= MAX_SCRO)lirerr(89); for(i=0; i