From c7d9aa05e73e9a7cb6fb94baeaf8d4b72326c468 Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Tue, 28 Feb 2017 00:27:41 +0100 Subject: [PATCH] Fixed a lot of things related to fractional decimator --- README.md | 9 +- csdr.c | 44 +++- grc_tests/test_fractional_decimator.grc | 322 +++++++++++++++++++++++- libcsdr.c | 6 +- 4 files changed, 352 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index e0f2ddc..959afdf 100644 --- a/README.md +++ b/README.md @@ -312,11 +312,16 @@ The output sample rate will be `interpolation / decimation × input_sample_rate` `transition_bw` and `window` are the parameters of the filter. - fractional_decimator_ff [transition_bw [window]] + fractional_decimator_ff [num_poly_points ( [transition_bw [window]] | --prefilter )] It can decimate by a floating point ratio. -`transition_bw` and `window` are the parameters of the filter. +It uses Lagrance interpolation, where `num_poly_points` (12 by default) input samples are taken into consideration while calculating one output sample. + +It can use an additional FIR filter before applying the Lagrange interpolation. This filter can be activated by: + +* passing only the `transition_bw`, or both the `transition_bw` and the `window` parameters of the filter, +* using the `--prefilter` switch after `num_poly_points` to switch this filter on with the default parameters. bandpass_fir_fft_cc [window] diff --git a/csdr.c b/csdr.c index 7a5910b..689690e 100644 --- a/csdr.c +++ b/csdr.c @@ -98,7 +98,7 @@ char usage[]= " fastagc_ff [block_size [reference]]\n" " rational_resampler_ff [transition_bw [window]]\n" " old_fractional_decimator_ff [transition_bw [window]]\n" -" fractional_decimator_ff [transition_bw [window]]\n" +" fractional_decimator_ff [num_poly_points ( [transition_bw [window]] | --prefilter )]\n" " fft_cc [window [--octave] [--benchmark]]\n" " logpower_cf [add_db]\n" " fft_benchmark [--benchmark]\n" @@ -1322,15 +1322,29 @@ int main(int argc, char *argv[]) float rate; sscanf(argv[2],"%g",&rate); - float transition_bw=0.03; - if(argc>=4) sscanf(argv[3],"%g",&transition_bw); + int num_poly_points = 12; + if(argc>=4) sscanf(argv[3],"%d",&num_poly_points); + if(num_poly_points&1) return badsyntax("num_poly_points should be even"); + if(num_poly_points<2) return badsyntax("num_poly_points should be >= 2"); + int use_prefilter = 0; + float transition_bw=0.03; window_t window = WINDOW_DEFAULT; if(argc>=5) { - window = firdes_get_window_from_string(argv[4]); + if(!strcmp(argv[4], "--prefilter")) + { + fprintf(stderr, "fractional_decimator_ff: using prefilter with default values\n"); + use_prefilter = 1; + } + else + { + sscanf(argv[4],"%g",&transition_bw); + if(argc>=6) window = firdes_get_window_from_string(argv[5]); + } } - else fprintf(stderr,"fractional_decimator_ff: window = %s\n",firdes_get_string_from_window(window)); + fprintf(stderr,"fractional_decimator_ff: use_prefilter = %d, num_poly_points = %d, transition_bw = %g, window = %s\n", + use_prefilter, num_poly_points, transition_bw, firdes_get_string_from_window(window)); if(!initialize_buffers()) return -2; sendbufsize(the_bufsize / rate); @@ -1338,14 +1352,18 @@ int main(int argc, char *argv[]) if(rate==1) clone_(the_bufsize); //copy input to output in this special case (and stick in this function). //Generate filter taps - int taps_length = firdes_filter_len(transition_bw); - fprintf(stderr,"fractional_decimator_ff: taps_length = %d\n",taps_length); - float* taps = (float*)malloc(sizeof(float)*taps_length); - firdes_lowpass_f(taps, taps_length, 0.59*0.5/(rate-transition_bw), window); //0.6 const to compensate rolloff - //for(int=0;i grid_pos - 2, 1, 1, 1 + 1, 1, 1, 1 id @@ -292,7 +292,7 @@ _coordinate - (168, 115) + (168, 163) _rotation @@ -316,7 +316,7 @@ samples_per_second - samp_rate + samp_rate/5 type @@ -386,7 +386,7 @@ commandline - "csdr fractional_decimator_ff "+str(decimation) + "csdr fractional_decimator_ff "+str(decimation)+" 20" comment @@ -402,7 +402,7 @@ _coordinate - (352, 115) + (368, 91) _rotation @@ -425,6 +425,53 @@ ff + + ha5kfu_execproc_xx + + alias + + + + commandline + "csdr old_fractional_decimator_ff "+str(decimation) + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (840, 379) + + + _rotation + 0 + + + id + ha5kfu_execproc_xx_0_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + type + ff + + notebook @@ -449,7 +496,7 @@ grid_pos - 1,2,1,1 + 2,2,1,1 id @@ -492,7 +539,7 @@ grid_pos - 1,1,1,1 + 2,1,1,1 id @@ -535,7 +582,7 @@ grid_pos - 2,2,1,1 + 3,2,1,1 id @@ -554,6 +601,49 @@ wx.NB_TOP + + notebook + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (16, 795) + + + _rotation + 0 + + + grid_pos + 3,1,1,1 + + + id + nb3 + + + labels + ['scope','fft'] + + + notebook + + + + style + wx.NB_TOP + + wxgui_fftsink2 @@ -594,7 +684,7 @@ _coordinate - (640, 235) + (736, 147) _rotation @@ -634,7 +724,7 @@ title - Resampled signal (csdr) + Resampled signal (csdr, new) type @@ -760,6 +850,109 @@ 10 + + wxgui_fftsink2 + + avg_alpha + 0 + + + average + False + + + baseband_freq + 0 + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + fft_size + 1024 + + + freqvar + None + + + _coordinate + (1112, 139) + + + _rotation + 0 + + + grid_pos + + + + id + wxgui_fftsink2_0_1 + + + notebook + nb3,1 + + + peak_hold + False + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_rate + 15 + + + samp_rate + samp_rate_2 + + + title + Resampled signal (csdr, old) + + + type + float + + + win_size + + + + win + None + + + y_divs + 16 + + + y_per_div + 10 + + wxgui_fftsink2 @@ -887,7 +1080,7 @@ _coordinate - (640, 115) + (728, 27) _rotation @@ -919,7 +1112,7 @@ title - Resampled signal (csdr) + Resampled signal (csdr, new) trig_mode @@ -1124,6 +1317,93 @@ Counts + + wxgui_scopesink2 + + ac_couple + False + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (1112, 19) + + + _rotation + 0 + + + grid_pos + + + + id + wxgui_scopesink2_0_2 + + + notebook + nb3,0 + + + num_inputs + 1 + + + samp_rate + samp_rate_2 + + + t_scale + 0 + + + title + Resampled signal (csdr, old) + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + type + float + + + v_offset + 0 + + + v_scale + 0 + + + win_size + + + + xy_mode + False + + + y_axis_label + Counts + + analog_sig_source_x_0 blocks_throttle_0 @@ -1142,6 +1422,12 @@ 0 0 + + blocks_throttle_0 + ha5kfu_execproc_xx_0_0 + 0 + 0 + blocks_throttle_0 wxgui_fftsink2_1 @@ -1178,4 +1464,16 @@ 0 0 + + ha5kfu_execproc_xx_0_0 + wxgui_fftsink2_0_1 + 0 + 0 + + + ha5kfu_execproc_xx_0_0 + wxgui_scopesink2_0_2 + 0 + 0 + diff --git a/libcsdr.c b/libcsdr.c index 14a1eaf..ff7415c 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -739,8 +739,10 @@ void fractional_decimator_ff(float* input, float* output, int input_size, fracti //d->num_poly_points above is theoretically more than we could have here, but this makes the spectrum look good int sxifirst = FD_INDEX_LOW + d->xifirst; int sxilast = FD_INDEX_LOW + d->xilast; - if(d->taps) for(int wi=0;winum_poly_points;wi++) d->filtered_buf[wi] = fir_one_pass_ff(input+FD_INDEX_LOW+wi, d->taps, d->taps_length); - else for(int wi=0;winum_poly_points;wi++) d->filtered_buf[wi] = *(input+FD_INDEX_LOW+wi); + if(d->taps) + for(int wi=0;winum_poly_points;wi++) d->filtered_buf[wi] = fir_one_pass_ff(input+FD_INDEX_LOW+wi, d->taps, d->taps_length); + else + for(int wi=0;winum_poly_points;wi++) d->filtered_buf[wi] = *(input+FD_INDEX_LOW+wi); int id=0; float xwhere = d->where - FD_INDEX_LOW; for(int xi=d->xifirst;xi<=d->xilast;xi++)