From 7ba726af5b4ce523bd0496ddfd2eee6eb3f66182 Mon Sep 17 00:00:00 2001 From: Rico van Genugten Date: Thu, 6 Oct 2016 09:12:34 +0000 Subject: [PATCH 01/15] Fixed issue simonyiszk/csdr#15 by using veor instead of vmov to zero accumulators in fir_decimate_cc. Also removed some unused variables --- libcsdr.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/libcsdr.c b/libcsdr.c index 737a786..3f197cb 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -280,11 +280,7 @@ int fir_decimate_cc(complexf *input, complexf *output, int input_size, int decim for(int i=0; iinput_size) break; - register float acci=0; - register float accq=0; - - register int ti=0; - register float* pinput=(float*)&(input[i+ti]); + register float* pinput=(float*)&(input[i]); register float* ptaps=taps; register float* ptaps_end=taps+taps_length; float quad_acciq [8]; @@ -297,8 +293,8 @@ q4, q5: accumulator for I branch and Q branch (will be the output) */ asm volatile( - " vmov.f32 q4, #0.0\n\t" //another way to null the accumulators - " vmov.f32 q5, #0.0\n\t" + " veor q4, q4\n\t" + " veor q5, q5\n\t" "for_fdccasm: vld2.32 {q0-q1}, [%[pinput]]!\n\t" //load q0 and q1 directly from the memory address stored in pinput, with interleaving (so that we get the I samples in q0 and the Q samples in q1), also increment the memory address in pinput (hence the "!" mark) //http://community.arm.com/groups/processors/blog/2010/03/17/coding-for-neon--part-1-load-and-stores " vld1.32 {q2}, [%[ptaps]]!\n\t" " vmla.f32 q4, q0, q2\n\t" //quad_acc_i += quad_input_i * quad_taps_1 //http://stackoverflow.com/questions/3240440/how-to-use-the-multiply-and-accumulate-intrinsics-in-arm-cortex-a8 //http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489e/CIHEJBIE.html From 12d7db8b4973551cd8f0f2b43f3d9e9165b455b4 Mon Sep 17 00:00:00 2001 From: Rico van Genugten Date: Thu, 6 Oct 2016 11:28:34 +0000 Subject: [PATCH 02/15] Fixed issue simonyiszk/csdr#15 by fixing allocating size in bytes instead of size in amount of taps --- csdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csdr.c b/csdr.c index ec08e27..b2b8678 100644 --- a/csdr.c +++ b/csdr.c @@ -940,7 +940,7 @@ int main(int argc, char *argv[]) padded_taps_length = taps_length+(NEON_ALIGNMENT/4)-1 - ((taps_length+(NEON_ALIGNMENT/4)-1)%(NEON_ALIGNMENT/4)); fprintf(stderr,"padded_taps_length = %d\n", padded_taps_length); - taps = (float*) (float*)malloc(padded_taps_length+NEON_ALIGNMENT); + taps = (float*) (float*)malloc((padded_taps_length+NEON_ALIGNMENT)*sizeof(float)); fprintf(stderr,"taps = %x\n", taps); taps = (float*)((((unsigned)taps)+NEON_ALIGNMENT-1) & ~(NEON_ALIGNMENT-1)); fprintf(stderr,"taps = %x\n", taps); From f4da40ffa7cbf1a075a537ce7b107802ae66631c Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Sat, 18 Feb 2017 15:49:04 +0100 Subject: [PATCH 03/15] fractional_decimator_ff gets new algorithm based on Lagrange interpolator formula --- .gitignore | 1 + csdr.c | 48 +- grc_tests/test_fractional_decimator.grc | 1532 ++++++++++++----------- libcsdr.c | 94 +- libcsdr.h | 25 +- 5 files changed, 957 insertions(+), 743 deletions(-) diff --git a/.gitignore b/.gitignore index 1d4be5f..71766fd 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ ddcd *.so tags dumpvect.*.vect +grc_tests/top_block.py diff --git a/csdr.c b/csdr.c index 5506ab8..6035ac9 100644 --- a/csdr.c +++ b/csdr.c @@ -97,6 +97,7 @@ char usage[]= " agc_ff [hang_time [reference [attack_rate [decay_rate [max_gain [attack_wait [filter_alpha]]]]]]]\n" " 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" " fft_cc [window [--octave] [--benchmark]]\n" " logpower_cf [add_db]\n" @@ -1343,14 +1344,57 @@ int main(int argc, char *argv[]) firdes_lowpass_f(taps, taps_length, 0.59*0.5/(rate-transition_bw), window); //0.6 const to compensate rolloff //for(int=0;i initialized to zero + fprintf(stderr,"fractional_decimator_ff: not using taps\n"); + fractional_decimator_ff_t d = fractional_decimator_ff_init(rate, 4, NULL, 0); for(;;) { FEOF_CHECK; if(d.input_processed==0) d.input_processed=the_bufsize; else memcpy(input_buffer, input_buffer+d.input_processed, sizeof(float)*(the_bufsize-d.input_processed)); fread(input_buffer+(the_bufsize-d.input_processed), sizeof(float), d.input_processed, stdin); - d = fractional_decimator_ff(input_buffer, output_buffer, the_bufsize, rate, taps, taps_length, d); + fractional_decimator_ff(input_buffer, output_buffer, the_bufsize, &d); + fwrite(output_buffer, sizeof(float), d.output_size, stdout); + TRY_YIELD; + } + } + + if(!strcmp(argv[1],"old_fractional_decimator_ff")) + { + //Process the params + if(argc<=2) return badsyntax("need required parameters (rate)"); + float rate; + sscanf(argv[2],"%g",&rate); + + float transition_bw=0.03; + if(argc>=4) sscanf(argv[3],"%g",&transition_bw); + + window_t window = WINDOW_DEFAULT; + if(argc>=5) + { + window = firdes_get_window_from_string(argv[4]); + } + else fprintf(stderr,"old_fractional_decimator_ff: window = %s\n",firdes_get_string_from_window(window)); + + if(!initialize_buffers()) return -2; + sendbufsize(the_bufsize / rate); + + 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,"old_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 initialized to zero + for(;;) + { + FEOF_CHECK; + if(d.input_processed==0) d.input_processed=the_bufsize; + else memcpy(input_buffer, input_buffer+d.input_processed, sizeof(float)*(the_bufsize-d.input_processed)); + fread(input_buffer+(the_bufsize-d.input_processed), sizeof(float), d.input_processed, stdin); + d = old_fractional_decimator_ff(input_buffer, output_buffer, the_bufsize, rate, taps, taps_length, d); fwrite(output_buffer, sizeof(float), d.output_size, stdout); TRY_YIELD; } diff --git a/grc_tests/test_fractional_decimator.grc b/grc_tests/test_fractional_decimator.grc index 3b587fe..c57bd3c 100644 --- a/grc_tests/test_fractional_decimator.grc +++ b/grc_tests/test_fractional_decimator.grc @@ -1,49 +1,49 @@ - - + + Tue Nov 25 18:16:05 2014 options - - id - top_block - - - _enabled - True - - - title - - author - - description - - window_size 1280, 1024 - - generate_options - wx_gui - category Custom - run_options - prompt + comment + - run + description + + + + _enabled True + + _coordinate + (10, 10) + + + _rotation + 0 + + + generate_options + wx_gui + + + id + top_block + max_nouts 0 @@ -53,36 +53,32 @@ - alias + run_options + prompt + + + run + True + + + thread_safe_setters - _coordinate - (10, 10) - - - _rotation - 0 + title + variable - id - decimation + comment + _enabled True - - value - 3.2 - - - alias - - _coordinate (376, 11) @@ -91,52 +87,84 @@ _rotation 0 - - - variable id - samp_rate_2 + decimation + + + value + 1.09352 + + + + variable_slider + + comment + + + + converver + float_converter + + + value + 4e3 _enabled True - - value - samp_rate/decimation - - - alias - - _coordinate - (272, 11) + (16, 291) _rotation 0 + + grid_pos + 2, 1, 1, 1 + + + id + input_freq + + + label + + + + max + samp_rate/2 + + + min + 0 + + + notebook + + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + variable - id - samp_rate + comment + _enabled True - - value - 240000 - - - alias - - _coordinate (176, 11) @@ -145,16 +173,91 @@ _rotation 0 + + id + samp_rate + + + value + 240000 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (272, 11) + + + _rotation + 0 + + + id + samp_rate_2 + + + value + samp_rate/decimation + analog_sig_source_x + + amp + 1 + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + freq + input_freq + + + _coordinate + (8, 83) + + + _rotation + 0 + id analog_sig_source_x_0 - _enabled - True + maxoutbuf + 0 + + + minoutbuf + 0 + + + offset + 0 type @@ -168,309 +271,24 @@ waveform analog.GR_COS_WAVE - - freq - input_freq - - - amp - 1 - - - offset - 0 - - - alias - - - - affinity - - - - minoutbuf - 0 - - - maxoutbuf - 0 - - - _coordinate - (8, 83) - - - _rotation - 0 - - - - wxgui_fftsink2 - - id - wxgui_fftsink2_1 - - - _enabled - True - - - type - float - - - title - Original signal - - - samp_rate - samp_rate - - - baseband_freq - 0 - - - y_per_div - 10 - - - y_divs - 10 - - - ref_level - 0 - - - ref_scale - 2.0 - - - fft_size - 1024 - - - fft_rate - 15 - - - peak_hold - False - - - average - False - - - avg_alpha - 0 - - - win - None - - - win_size - - - - grid_pos - - - - notebook - nb1,1 - - - freqvar - None - - - alias - - - - affinity - - - - _coordinate - (360, 355) - - - _rotation - 0 - - - - ha5kfu_execproc_xx - - id - ha5kfu_execproc_xx_0 - - - _enabled - True - - - type - ff - - - commandline - "csdr fractional_decimator_ff "+str(decimation) - - - alias - - - - affinity - - - - minoutbuf - 0 - - - maxoutbuf - 0 - - - _coordinate - (352, 115) - - - _rotation - 0 - - - - wxgui_scopesink2 - - id - wxgui_scopesink2_0_0 - - - _enabled - True - - - type - float - - - title - Original signal - - - samp_rate - samp_rate - - - v_scale - 0 - - - v_offset - 0 - - - t_scale - 0 - - - ac_couple - False - - - xy_mode - False - - - num_inputs - 1 - - - win_size - - - - grid_pos - - - - notebook - nb1,0 - - - trig_mode - wxgui.TRIG_MODE_AUTO - - - y_axis_label - Counts - - - alias - - - - affinity - - - - _coordinate - (360, 235) - - - _rotation - 0 - blocks_throttle - - id - blocks_throttle_0 - - - _enabled - True - - - type - float - - - samples_per_second - samp_rate - - - vlen - 1 - - - ignoretag - True - alias + + comment + + affinity - minoutbuf - 0 - - - maxoutbuf - 0 + _enabled + True _coordinate @@ -480,202 +298,72 @@ _rotation 0 - - - wxgui_fftsink2 id - wxgui_fftsink2_0 + blocks_throttle_0 - _enabled + ignoretag True + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samples_per_second + samp_rate + type float - title - Resampled signal (csdr) - - - samp_rate - samp_rate_2 - - - baseband_freq - 0 - - - y_per_div - 10 - - - y_divs - 10 - - - ref_level - 0 - - - ref_scale - 2.0 - - - fft_size - 1024 - - - fft_rate - 15 - - - peak_hold - False - - - average - False - - - avg_alpha - 0 - - - win - None - - - win_size - - - - grid_pos - - - - notebook - nb0,1 - - - freqvar - None - - - alias - - - - affinity - - - - _coordinate - (640, 235) - - - _rotation - 0 - - - - wxgui_scopesink2 - - id - wxgui_scopesink2_0 - - - _enabled - True - - - type - float - - - title - Resampled signal (csdr) - - - samp_rate - samp_rate_2 - - - v_scale - 0 - - - v_offset - 0 - - - t_scale - 0 - - - ac_couple - False - - - xy_mode - False - - - num_inputs + vlen 1 - - win_size - - - - grid_pos - - - - notebook - nb0,0 - - - trig_mode - wxgui.TRIG_MODE_AUTO - - - y_axis_label - Counts - - - alias - - - - affinity - - - - _coordinate - (640, 115) - - - _rotation - 0 - fractional_resampler_xx - id - fractional_resampler_xx_0 + alias + + + + comment + + + + affinity + _enabled True - type - float + _coordinate + (360, 608) + + + _rotation + 0 + + + id + fractional_resampler_xx_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 phase_shift @@ -685,147 +373,248 @@ resamp_ratio decimation + + type + float + + + + ha5kfu_execproc_xx alias + + commandline + "csdr fractional_decimator_ff "+str(decimation) + + + comment + + affinity - minoutbuf + _enabled + True + + + _coordinate + (352, 115) + + + _rotation 0 + + id + ha5kfu_execproc_xx_0 + maxoutbuf 0 - _coordinate - (360, 608) + minoutbuf + 0 - _rotation - 0 + type + ff - wxgui_scopesink2 + notebook - id - wxgui_scopesink2_0_1 + alias + + + + comment + _enabled True - type - float + _coordinate + (16, 683) - title - Resampled signal (GNU Radio) - - - samp_rate - samp_rate_2 - - - v_scale + _rotation 0 - - v_offset - 0 - - - t_scale - 0 - - - ac_couple - False - - - xy_mode - False - - - num_inputs - 1 - - - win_size - - grid_pos - + 1,2,1,1 + + + id + nb0 + + + labels + ['scope','fft'] notebook - nb2,0 + - trig_mode - wxgui.TRIG_MODE_AUTO + style + wx.NB_TOP + + + + notebook + + alias + - y_axis_label - Counts + comment + + + + _enabled + True + + + _coordinate + (16, 579) + + + _rotation + 0 + + + grid_pos + 1,1,1,1 + + + id + nb1 + + + labels + ['scope','fft'] + + + notebook + + + + style + wx.NB_TOP + + + + notebook + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (16, 475) + + + _rotation + 0 + + + grid_pos + 2,2,1,1 + + + id + nb2 + + + labels + ['scope','fft'] + + + notebook + + + + style + wx.NB_TOP + + + + wxgui_fftsink2 + + avg_alpha + 0 + + + average + False + + + baseband_freq + 0 alias + + comment + + affinity + + _enabled + True + + + fft_size + 1024 + + + freqvar + None + _coordinate - (640, 459) + (640, 235) _rotation 0 - - - wxgui_fftsink2 + + grid_pos + + id - wxgui_fftsink2_0_0 + wxgui_fftsink2_0 - _enabled - True + notebook + nb0,1 - type - float - - - title - Resampled signal (GNU Radio) - - - samp_rate - samp_rate_2 - - - baseband_freq - 0 - - - y_per_div - 10 - - - y_divs - 10 + peak_hold + False ref_level @@ -835,54 +624,77 @@ ref_scale 2.0 - - fft_size - 1024 - fft_rate 15 - peak_hold - False + samp_rate + samp_rate_2 - average - False + title + Resampled signal (csdr) - avg_alpha - 0 - - - win - None + type + float win_size - grid_pos - - - - notebook - nb2,1 - - - freqvar + win None + + y_divs + 10 + + + y_per_div + 10 + + + + wxgui_fftsink2 + + avg_alpha + 0 + + + average + False + + + baseband_freq + 0 + alias + + comment + + affinity + + _enabled + True + + + fft_size + 1024 + + + freqvar + None + _coordinate (640, 579) @@ -891,192 +703,436 @@ _rotation 0 - - - notebook - - id - nb0 - - - _enabled - True - - - style - wx.NB_TOP - - - labels - ['scope','fft'] - grid_pos - 1,2,1,1 + + + + id + wxgui_fftsink2_0_0 notebook + nb2,1 + + + peak_hold + False + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_rate + 15 + + + samp_rate + samp_rate_2 + + + title + Resampled signal (GNU Radio) + + + type + float + + + win_size + + win + None + + + y_divs + 10 + + + y_per_div + 10 + + + + wxgui_fftsink2 + + avg_alpha + 0 + + + average + False + + + baseband_freq + 0 + alias - _coordinate - (16, 683) + comment + - _rotation - 0 - - - - notebook - - id - nb1 + affinity + _enabled True - style - wx.NB_TOP + fft_size + 1024 - labels - ['scope','fft'] + freqvar + None + + + _coordinate + (360, 355) + + + _rotation + 0 grid_pos - 1,1,1,1 + + + + id + wxgui_fftsink2_1 notebook + nb1,1 + + + peak_hold + False + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_rate + 15 + + + samp_rate + samp_rate + + + title + Original signal + + + type + float + + + win_size + + win + None + + + y_divs + 10 + + + y_per_div + 10 + + + + wxgui_scopesink2 + + ac_couple + False + alias - _coordinate - (16, 579) + comment + - _rotation - 0 - - - - notebook - - id - nb2 + affinity + _enabled True - style - wx.NB_TOP + _coordinate + (640, 115) - labels - ['scope','fft'] + _rotation + 0 grid_pos - 2,2,1,1 + + + + id + wxgui_scopesink2_0 notebook + nb0,0 + + + num_inputs + 1 + + + samp_rate + samp_rate_2 + + + t_scale + 0 + + + title + Resampled signal (csdr) + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + type + float + + + v_offset + 0 + + + v_scale + 0 + + + win_size + + xy_mode + False + + + y_axis_label + Counts + + + + wxgui_scopesink2 + + ac_couple + False + alias - _coordinate - (16, 475) + comment + - _rotation - 0 - - - - variable_slider - - id - input_freq + affinity + _enabled True - label - + _coordinate + (360, 235) - value - 4e3 - - - min + _rotation 0 - - max - samp_rate/2 - - - num_steps - 100 - - - style - wx.SL_HORIZONTAL - - - converver - float_converter - grid_pos + + id + wxgui_scopesink2_0_0 + notebook + nb1,0 + + + num_inputs + 1 + + + samp_rate + samp_rate + + + t_scale + 0 + + + title + Original signal + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + type + float + + + v_offset + 0 + + + v_scale + 0 + + + win_size + + xy_mode + False + + + y_axis_label + Counts + + + + wxgui_scopesink2 + + ac_couple + False + alias + + comment + + + + affinity + + + + _enabled + True + _coordinate - (16, 355) + (640, 459) _rotation 0 + + grid_pos + + + + id + wxgui_scopesink2_0_1 + + + notebook + nb2,0 + + + num_inputs + 1 + + + samp_rate + samp_rate_2 + + + t_scale + 0 + + + title + Resampled signal (GNU Radio) + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + type + float + + + v_offset + 0 + + + v_scale + 0 + + + win_size + + + + xy_mode + False + + + y_axis_label + Counts + - ha5kfu_execproc_xx_0 - wxgui_scopesink2_0 + analog_sig_source_x_0 + blocks_throttle_0 0 0 - analog_sig_source_x_0 - blocks_throttle_0 + blocks_throttle_0 + fractional_resampler_xx_0 0 0 @@ -1086,18 +1142,6 @@ 0 0 - - blocks_throttle_0 - wxgui_scopesink2_0_0 - 0 - 0 - - - ha5kfu_execproc_xx_0 - wxgui_fftsink2_0 - 0 - 0 - blocks_throttle_0 wxgui_fftsink2_1 @@ -1106,7 +1150,13 @@ blocks_throttle_0 - fractional_resampler_xx_0 + wxgui_scopesink2_0_0 + 0 + 0 + + + fractional_resampler_xx_0 + wxgui_fftsink2_0_0 0 0 @@ -1117,8 +1167,14 @@ 0 - fractional_resampler_xx_0 - wxgui_fftsink2_0_0 + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0 0 0 diff --git a/libcsdr.c b/libcsdr.c index 972d216..6b8fc62 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -654,7 +654,7 @@ float inline fir_one_pass_ff(float* input, float* taps, int taps_length) return acc; } -fractional_decimator_ff_t fractional_decimator_ff(float* input, float* output, int input_size, float rate, float *taps, int taps_length, fractional_decimator_ff_t d) +old_fractional_decimator_ff_t old_fractional_decimator_ff(float* input, float* output, int input_size, float rate, float *taps, int taps_length, old_fractional_decimator_ff_t d) { if(rate<=1.0) return d; //sanity check, can't decimate <=1.0 //This routine can handle floating point decimation rates. @@ -687,6 +687,98 @@ fractional_decimator_ff_t fractional_decimator_ff(float* input, float* output, i return d; } +fractional_decimator_ff_t fractional_decimator_ff_init(float rate, int num_poly_points, float* taps, int taps_length) +{ + fractional_decimator_ff_t d; + d.num_poly_points = num_poly_points&~1; //num_poly_points needs to be even! + d.poly_precalc_denomiator = (float*)malloc(d.num_poly_points*sizeof(float)); + //x0..x3 + //-1,0,1,2 + //-(4/2)+1 + //x0..x5 + //-2,-1,0,1,2,3 + d.xifirst=-(num_poly_points/2)+1, d.xilast=num_poly_points/2; + int id = 0; //index in poly_precalc_denomiator + for(int xi=d.xifirst;xi<=d.xilast;xi++) + { + d.poly_precalc_denomiator[id]=1; + for(int xj=d.xifirst;xj<=d.xilast;xj++) + { + if(xi!=xj) d.poly_precalc_denomiator[id] *= (xi-xj); //poly_precalc_denomiator could be integer as well. But that would later add a necessary conversion. + } + id++; + } + d.where=-d.xifirst; + d.coeffs_buf=(float*)malloc(d.num_poly_points*sizeof(float)); + d.filtered_buf=(float*)malloc(d.num_poly_points*sizeof(float)); + //d.last_inputs_circbuf = (float)malloc(d.num_poly_points*sizeof(float)); + //d.last_inputs_startsat = 0; + //d.last_inputs_samplewhere = -1; + //for(int i=0;irate); + if(DEBUG_ASSERT) assert(d->rate > 1.0); + int oi=0; //output index + int index_high; +#define FD_INDEX_LOW (index_high-1) + //we optimize to calculate ceilf(where) only once every iteration, so we do it here: + for(;(index_high=ceilf(d->where))+d->taps_lengthwhere+=d->rate) //@fractional_decimator_ff + { + 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); + int id=0; + float xwhere = d->where - FD_INDEX_LOW; + for(int xi=d->xifirst;xi<=d->xilast;xi++) + { + d->coeffs_buf[id]=1; + for(int xj=d->xifirst;xj<=d->xilast;xj++) + { + if(xi!=xj) d->coeffs_buf[id] *= (xwhere-xj); + } + id++; + } + float acc = 0; + for(int i=0;inum_poly_points;i++) + { + acc += (d->coeffs_buf[i]/d->poly_precalc_denomiator[i])*d->filtered_buf[i]; //(xnom/xden)*yn + } + output[oi++]=acc; + } + d->input_processed=FD_INDEX_LOW + d->xifirst; + d->where-=d->input_processed; + if(DEBUG_ASSERT) assert(d->where >= -d->xifirst); + d->output_size=oi; +} + +/* + int last_input_samplewhere_shouldbe = (index_high-1)+xifirst; + int last_input_offset = last_input_samplewhere_shouldbe - d->last_input_samplewhere; + if(last_input_offset < num_poly_points) + { + //if we can move the last_input circular buffer, we move, and add the new samples at the end + d->last_inputs_startsat += last_input_offset; + d->last_inputs_startsat %= num_poly_points; + int num_copied_samples = 0; + for(int i=0; ilast_inputs_circbuf[i]= + } + d->last_input_samplewhere = d->las + } +*/ void apply_fir_fft_cc(FFT_PLAN_T* plan, FFT_PLAN_T* plan_inverse, complexf* taps_fft, complexf* last_overlap, int overlap_size) { diff --git a/libcsdr.h b/libcsdr.h index 4f45a43..b1afa1c 100644 --- a/libcsdr.h +++ b/libcsdr.h @@ -146,12 +146,33 @@ void accumulate_power_cf(complexf* input, float* output, int size); void log_ff(float* input, float* output, int size, float add_db); typedef struct fractional_decimator_ff_s +{ + float where; + int input_processed; + int output_size; + int num_poly_points; //number of samples that the Lagrange interpolator will use + float* poly_precalc_denomiator; //while we don't precalculate coefficients here as in a Farrow structure, because it is a fractional interpolator, but we rather precaculate part of the interpolator expression + //float* last_inputs_circbuf; //circular buffer to store the last (num_poly_points) number of input samples. + //int last_inputs_startsat; //where the circular buffer starts now + //int last_inputs_samplewhere; + float* coeffs_buf; + float* filtered_buf; + int xifirst; + int xilast; + float rate; + float *taps; + int taps_length; +} fractional_decimator_ff_t; +fractional_decimator_ff_t fractional_decimator_ff_init(float rate, int num_poly_points, float* taps, int taps_length); +void fractional_decimator_ff(float* input, float* output, int input_size, fractional_decimator_ff_t* d); + +typedef struct old_fractional_decimator_ff_s { float remain; int input_processed; int output_size; -} fractional_decimator_ff_t; -fractional_decimator_ff_t fractional_decimator_ff(float* input, float* output, int input_size, float rate, float *taps, int taps_length, fractional_decimator_ff_t d); +} old_fractional_decimator_ff_t; +old_fractional_decimator_ff_t old_fractional_decimator_ff(float* input, float* output, int input_size, float rate, float *taps, int taps_length, old_fractional_decimator_ff_t d); typedef struct shift_table_data_s { From 139d3d731b1070e888cdeb93bb6b6e57d9bbfd06 Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Sat, 18 Feb 2017 16:01:14 +0100 Subject: [PATCH 04/15] single samples bad, possibly at the beginning --- libcsdr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libcsdr.c b/libcsdr.c index 6b8fc62..23bca76 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -729,6 +729,7 @@ void fractional_decimator_ff(float* input, float* output, int input_size, fracti //The pre-filter can be switched off by applying taps=NULL. //fprintf(stderr, "drate=%f\n", d->rate); if(DEBUG_ASSERT) assert(d->rate > 1.0); + if(DEBUG_ASSERT) assert(d->where >= -d->xifirst); int oi=0; //output index int index_high; #define FD_INDEX_LOW (index_high-1) @@ -757,10 +758,9 @@ void fractional_decimator_ff(float* input, float* output, int input_size, fracti } output[oi++]=acc; } - d->input_processed=FD_INDEX_LOW + d->xifirst; - d->where-=d->input_processed; - if(DEBUG_ASSERT) assert(d->where >= -d->xifirst); - d->output_size=oi; + d->input_processed = FD_INDEX_LOW + d->xifirst; + d->where -= d->input_processed + d->xifirst + 1; + d->output_size = oi; } /* From 5f8f8695d3c6456efbd5773a5a0cbc9b019c6e4f Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Sat, 18 Feb 2017 16:17:53 +0100 Subject: [PATCH 05/15] fixed fractional_decimator_ff --- libcsdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcsdr.c b/libcsdr.c index 23bca76..3063cff 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -734,7 +734,7 @@ void fractional_decimator_ff(float* input, float* output, int input_size, fracti int index_high; #define FD_INDEX_LOW (index_high-1) //we optimize to calculate ceilf(where) only once every iteration, so we do it here: - for(;(index_high=ceilf(d->where))+d->taps_lengthwhere+=d->rate) //@fractional_decimator_ff + for(;(index_high=ceilf(d->where))+d->xilast+d->taps_lengthwhere+=d->rate) //@fractional_decimator_ff { int sxifirst = FD_INDEX_LOW + d->xifirst; int sxilast = FD_INDEX_LOW + d->xilast; From 0306b5b5bf2339e8df762825ccbb0799c73b2b6e Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Sat, 18 Feb 2017 16:24:19 +0100 Subject: [PATCH 06/15] fixed fractional_decimator_ff for N=6 interpolator, still interesting effect on the spectrum --- csdr.c | 2 +- libcsdr.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csdr.c b/csdr.c index 6035ac9..251eaf2 100644 --- a/csdr.c +++ b/csdr.c @@ -1345,7 +1345,7 @@ int main(int argc, char *argv[]) //for(int=0;iinput_processed = FD_INDEX_LOW + d->xifirst; - d->where -= d->input_processed + d->xifirst + 1; + d->where -= d->input_processed; d->output_size = oi; } From 1fab87af1d1a92f7fb04ac3e848ba70fd54fe3b6 Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Sat, 18 Feb 2017 16:26:51 +0100 Subject: [PATCH 07/15] haha, fixed that artifact too. Strange flickering line in the spectrum at -100 dB was caused by reading some samples out of region --- libcsdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcsdr.c b/libcsdr.c index fbbf6c5..ab7523f 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -734,7 +734,7 @@ void fractional_decimator_ff(float* input, float* output, int input_size, fracti int index_high; #define FD_INDEX_LOW (index_high-1) //we optimize to calculate ceilf(where) only once every iteration, so we do it here: - for(;(index_high=ceilf(d->where))+d->xilast+d->taps_lengthwhere+=d->rate) //@fractional_decimator_ff + for(;(index_high=ceilf(d->where))+d->xilast+1+d->taps_lengthwhere+=d->rate) //@fractional_decimator_ff { int sxifirst = FD_INDEX_LOW + d->xifirst; int sxilast = FD_INDEX_LOW + d->xilast; From 5f772ec3e3962e87a1b3a6aa472df537a8f44027 Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Sat, 18 Feb 2017 16:36:36 +0100 Subject: [PATCH 08/15] made that spectrum even better --- csdr.c | 2 +- grc_tests/test_fractional_decimator.grc | 4 ++-- libcsdr.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/csdr.c b/csdr.c index 251eaf2..7a5910b 100644 --- a/csdr.c +++ b/csdr.c @@ -1345,7 +1345,7 @@ int main(int argc, char *argv[]) //for(int=0;i y_divs - 10 + 16 y_per_div @@ -753,7 +753,7 @@ y_divs - 10 + 16 y_per_div diff --git a/libcsdr.c b/libcsdr.c index ab7523f..3ee3039 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -734,7 +734,7 @@ void fractional_decimator_ff(float* input, float* output, int input_size, fracti int index_high; #define FD_INDEX_LOW (index_high-1) //we optimize to calculate ceilf(where) only once every iteration, so we do it here: - for(;(index_high=ceilf(d->where))+d->xilast+1+d->taps_lengthwhere+=d->rate) //@fractional_decimator_ff + for(;(index_high=ceilf(d->where))+d->num_poly_points+d->taps_lengthwhere+=d->rate) //@fractional_decimator_ff { int sxifirst = FD_INDEX_LOW + d->xifirst; int sxilast = FD_INDEX_LOW + d->xilast; From 875434bf96428894c9bb06f5918e34fd728e7c68 Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Sat, 18 Feb 2017 16:37:49 +0100 Subject: [PATCH 09/15] added comment --- libcsdr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libcsdr.c b/libcsdr.c index 3ee3039..14a1eaf 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -736,6 +736,7 @@ void fractional_decimator_ff(float* input, float* output, int input_size, fracti //we optimize to calculate ceilf(where) only once every iteration, so we do it here: for(;(index_high=ceilf(d->where))+d->num_poly_points+d->taps_lengthwhere+=d->rate) //@fractional_decimator_ff { + //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); From c7d9aa05e73e9a7cb6fb94baeaf8d4b72326c468 Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Tue, 28 Feb 2017 00:27:41 +0100 Subject: [PATCH 10/15] 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++) From 86cedde53f3f7871fa76bef3ea057f4f49880ddb Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Tue, 28 Feb 2017 16:27:04 +0100 Subject: [PATCH 11/15] Fixed some more docs --- README.md | 2 +- grc_tests/test_fractional_decimator.grc | 58 +- grc_tests/test_rational_resampler.grc | 1658 ++++++++++++----------- 3 files changed, 914 insertions(+), 804 deletions(-) diff --git a/README.md b/README.md index 959afdf..117aea6 100644 --- a/README.md +++ b/README.md @@ -318,7 +318,7 @@ It can decimate by a floating point ratio. 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: +It can filter the signal with an anti-aliasing FIR filter before applying the Lagrange interpolation. This filter is inactive by default, but 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. diff --git a/grc_tests/test_fractional_decimator.grc b/grc_tests/test_fractional_decimator.grc index 764b362..a763ddb 100644 --- a/grc_tests/test_fractional_decimator.grc +++ b/grc_tests/test_fractional_decimator.grc @@ -155,6 +155,60 @@ wx.SL_HORIZONTAL + + variable + + comment + + + + _enabled + True + + + _coordinate + (480, 11) + + + _rotation + 0 + + + id + num_poly_points + + + value + 20 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (608, 11) + + + _rotation + 0 + + + id + prefilter + + + value + False + + variable @@ -386,7 +440,7 @@ commandline - "csdr fractional_decimator_ff "+str(decimation)+" 20" + "csdr fractional_decimator_ff "+str(decimation)+" "+str(num_poly_points)+("" if not prefilter else " --prefilter") comment @@ -449,7 +503,7 @@ _coordinate - (840, 379) + (784, 379) _rotation diff --git a/grc_tests/test_rational_resampler.grc b/grc_tests/test_rational_resampler.grc index fe8e838..6cb477c 100644 --- a/grc_tests/test_rational_resampler.grc +++ b/grc_tests/test_rational_resampler.grc @@ -1,49 +1,49 @@ - - + + Tue Mar 17 19:40:27 2015 options - - id - top_block - - - _enabled - True - - - title - - author - - description - - window_size 1280, 1024 - - generate_options - wx_gui - category Custom - run_options - prompt + comment + - run + description + + + + _enabled True + + _coordinate + (10, 10) + + + _rotation + 0 + + + generate_options + wx_gui + + + id + top_block + max_nouts 0 @@ -53,36 +53,32 @@ - alias + run_options + prompt + + + run + True + + + thread_safe_setters - _coordinate - (10, 10) - - - _rotation - 0 + title + variable - id - decimation + comment + _enabled True - - value - 1 - - - alias - - _coordinate (376, 11) @@ -91,110 +87,32 @@ _rotation 0 - - - variable id - interpolation - - - _enabled - True + decimation value - 4 - - - alias - - - - _coordinate - (272, 11) - - - _rotation - 0 - - - - variable - - id - samp_rate - - - _enabled - True - - - value - 32000 - - - alias - - - - _coordinate - (176, 11) - - - _rotation - 0 + 1 variable_slider - id - frequency - - - _enabled - True - - - label + comment - - value - 1e3 - - - min - 0 - - - max - samp_rate/2 - - - num_steps - 100 - - - style - wx.SL_HORIZONTAL - converver float_converter - grid_pos - + value + 1e3 - notebook - - - - alias - + _enabled + True _coordinate @@ -204,431 +122,142 @@ _rotation 0 - - - wxgui_fftsink2 + + grid_pos + 2,1,1,1 + id - wxgui_fftsink2_0 + frequency + + + label + + + + max + samp_rate/2 + + + min + 0 + + + notebook + + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + + variable + + comment + _enabled True - type - float + _coordinate + (272, 11) - title - Original signal + _rotation + 0 - samp_rate + id + interpolation + + + value + 4 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (176, 11) + + + _rotation + 0 + + + id samp_rate - baseband_freq - 0 - - - y_per_div - 10 - - - y_divs - 10 - - - ref_level - 0 - - - ref_scale - 2.0 - - - fft_size - 1024 - - - fft_rate - 15 - - - peak_hold - False - - - average - False - - - avg_alpha - 0 - - - win - None - - - win_size - - - - grid_pos - - - - notebook - nb0,1 - - - freqvar - None - - - alias - - - - affinity - - - - _coordinate - (752, 379) - - - _rotation - 0 + value + 32000 - wxgui_scopesink2 + analog_sig_source_x - id - wxgui_scopesink2_0 - - - _enabled - True - - - type - float - - - title - Original signal - - - samp_rate - samp_rate - - - v_scale - 0 - - - v_offset - 0 - - - t_scale - 0 - - - ac_couple - False - - - xy_mode - False - - - num_inputs + amp 1 - - win_size - - - - grid_pos - - - - notebook - nb0,0 - - - trig_mode - wxgui.TRIG_MODE_AUTO - - - y_axis_label - Counts - alias + + comment + + affinity - - _coordinate - (752, 259) - - - _rotation - 0 - - - - wxgui_fftsink2 - - id - wxgui_fftsink2_0_0 - _enabled True - type - float - - - title - Resampled signal (csdr) - - - samp_rate - samp_rate*(interpolation/float(decimation)) - - - baseband_freq - 0 - - - y_per_div - 10 - - - y_divs - 10 - - - ref_level - 0 - - - ref_scale - 2.0 - - - fft_size - 1024 - - - fft_rate - 15 - - - peak_hold - False - - - average - False - - - avg_alpha - 0 - - - win - None - - - win_size - - - - grid_pos - - - - notebook - nb1,1 - - - freqvar - None - - - alias - - - - affinity - + freq + frequency _coordinate - (984, 195) + (104, 211) _rotation 0 - - - wxgui_scopesink2 id - wxgui_scopesink2_1 - - - _enabled - True - - - type - float - - - title - Resampled signal (csdr) - - - samp_rate - samp_rate*(interpolation/float(decimation)) - - - v_scale - 0 - - - v_offset - 0 - - - t_scale - 0 - - - ac_couple - False - - - xy_mode - False - - - num_inputs - 1 - - - win_size - - - - grid_pos - - - - notebook - nb1,0 - - - trig_mode - wxgui.TRIG_MODE_AUTO - - - y_axis_label - Counts - - - alias - - - - affinity - - - - _coordinate - (984, 75) - - - _rotation - 0 - - - - blocks_throttle - - id - blocks_throttle_0 - - - _enabled - True - - - type - float - - - samples_per_second - samp_rate - - - vlen - 1 - - - ignoretag - True - - - alias - - - - affinity - - - - minoutbuf - 0 + analog_sig_source_x_0 maxoutbuf 0 - _coordinate - (312, 243) - - - _rotation + minoutbuf 0 - - - analog_sig_source_x - id - analog_sig_source_x_0 - - - _enabled - True + offset + 0 type @@ -642,73 +271,123 @@ waveform analog.GR_SIN_WAVE - - freq - frequency - - - amp - 1 - - - offset - 0 - + + + blocks_throttle alias + + comment + + affinity - minoutbuf + _enabled + True + + + _coordinate + (312, 243) + + + _rotation 0 + + id + blocks_throttle_0 + + + ignoretag + True + maxoutbuf 0 - _coordinate - (104, 211) + minoutbuf + 0 - _rotation - 0 + samples_per_second + samp_rate + + + type + float + + + vlen + 1 - notebook + ha5kfu_execproc_xx - id - nb0 + alias + + + + commandline + "csdr rational_resampler_ff %d %d 0.05"%(interpolation,decimation) + + + comment + + + + affinity + _enabled True - style - wx.NB_TOP + _coordinate + (752, 195) - labels - ['scope', 'fft'] + _rotation + 0 - grid_pos - 1,1,1,1 + id + ha5kfu_execproc_xx_0 - notebook - + maxoutbuf + 0 + + minoutbuf + 0 + + + type + ff + + + + notebook alias + + comment + + + + _enabled + True + _coordinate (8, 75) @@ -717,37 +396,41 @@ _rotation 0 - - - notebook + + grid_pos + 1,1,1,1 + id - nb1 - - - _enabled - True - - - style - wx.NB_TOP + nb0 labels ['scope', 'fft'] - - grid_pos - 1,2,1,1 - notebook + + style + wx.NB_TOP + + + + notebook alias + + comment + + + + _enabled + True + _coordinate (152, 75) @@ -756,219 +439,41 @@ _rotation 0 - - - wxgui_scopesink2 - - id - wxgui_scopesink2_1_0 - - - _enabled - True - - - type - float - - - title - Resampled signal (GNU Radio) - - - samp_rate - samp_rate*(interpolation/float(decimation)) - - - v_scale - 0 - - - v_offset - 0 - - - t_scale - 0 - - - ac_couple - False - - - xy_mode - False - - - num_inputs - 1 - - - win_size - - grid_pos - + 1,2,1,1 - - notebook - nb2,0 - - - trig_mode - wxgui.TRIG_MODE_AUTO - - - y_axis_label - Counts - - - alias - - - - affinity - - - - _coordinate - (760, 603) - - - _rotation - 0 - - - - wxgui_fftsink2 id - wxgui_fftsink2_0_0_0 - - - _enabled - True - - - type - float - - - title - Resampled signal (GNU Radio) - - - samp_rate - samp_rate*(interpolation/float(decimation)) - - - baseband_freq - 0 - - - y_per_div - 10 - - - y_divs - 10 - - - ref_level - 0 - - - ref_scale - 2.0 - - - fft_size - 1024 - - - fft_rate - 15 - - - peak_hold - False - - - average - False - - - avg_alpha - 0 - - - win - None - - - win_size - - - - grid_pos - - - - notebook - nb2,1 - - - freqvar - None - - - alias - - - - affinity - - - - _coordinate - (760, 723) - - - _rotation - 0 - - - - notebook - - id - nb2 - - - _enabled - True - - - style - wx.NB_TOP + nb1 labels ['scope', 'fft'] - - grid_pos - 2,2,1,1 - notebook + + style + wx.NB_TOP + + + + notebook alias + + comment + + + + _enabled + True + _coordinate (296, 75) @@ -977,51 +482,51 @@ _rotation 0 + + grid_pos + 2,2,1,1 + + + id + nb2 + + + labels + ['scope', 'fft'] + + + notebook + + + + style + wx.NB_TOP + rational_resampler_xxx - - id - rational_resampler_xxx_0 - - - _enabled - True - - - type - fff - - - interp - interpolation - - - decim - decimation - - - taps - firdes.low_pass(5,1,0.5*min(1./interpolation,1./decimation),0.05) - - - fbw - 0 - alias + + comment + + affinity - minoutbuf - 0 + decim + decimation - maxoutbuf + _enabled + True + + + fbw 0 @@ -1032,62 +537,601 @@ _rotation 0 - - - ha5kfu_execproc_xx id - ha5kfu_execproc_xx_0 + rational_resampler_xxx_0 - _enabled - True + interp + interpolation + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + taps + firdes.low_pass(5,1,0.5*min(1./interpolation,1./decimation),0.05) type - ff + fff + + + + wxgui_fftsink2 + + avg_alpha + 0 - commandline - "csdr rational_resampler_ff %d %d 0.05"%(interpolation,decimation) + average + False + + + baseband_freq + 0 alias + + comment + + affinity - minoutbuf - 0 + _enabled + True - maxoutbuf - 0 + fft_size + 1024 + + + freqvar + None _coordinate - (752, 195) + (752, 379) _rotation 0 + + grid_pos + + + + id + wxgui_fftsink2_0 + + + notebook + nb0,1 + + + peak_hold + False + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_rate + 15 + + + samp_rate + samp_rate + + + title + Original signal + + + type + float + + + win_size + + + + win + None + + + y_divs + 10 + + + y_per_div + 10 + + + + wxgui_fftsink2 + + avg_alpha + 0 + + + average + False + + + baseband_freq + 0 + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + fft_size + 1024 + + + freqvar + None + + + _coordinate + (984, 195) + + + _rotation + 0 + + + grid_pos + + + + id + wxgui_fftsink2_0_0 + + + notebook + nb1,1 + + + peak_hold + False + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_rate + 15 + + + samp_rate + samp_rate*(interpolation/float(decimation)) + + + title + Resampled signal (csdr) + + + type + float + + + win_size + + + + win + None + + + y_divs + 10 + + + y_per_div + 10 + + + + wxgui_fftsink2 + + avg_alpha + 0 + + + average + False + + + baseband_freq + 0 + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + fft_size + 1024 + + + freqvar + None + + + _coordinate + (760, 723) + + + _rotation + 0 + + + grid_pos + + + + id + wxgui_fftsink2_0_0_0 + + + notebook + nb2,1 + + + peak_hold + False + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_rate + 15 + + + samp_rate + samp_rate*(interpolation/float(decimation)) + + + title + Resampled signal (GNU Radio) + + + type + float + + + win_size + + + + win + None + + + y_divs + 10 + + + y_per_div + 10 + + + + wxgui_scopesink2 + + ac_couple + False + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (752, 259) + + + _rotation + 0 + + + grid_pos + + + + id + wxgui_scopesink2_0 + + + notebook + nb0,0 + + + num_inputs + 1 + + + samp_rate + samp_rate + + + t_scale + 0 + + + title + Original signal + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + type + float + + + v_offset + 0 + + + v_scale + 0 + + + win_size + + + + xy_mode + False + + + y_axis_label + Counts + + + + wxgui_scopesink2 + + ac_couple + False + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (984, 75) + + + _rotation + 0 + + + grid_pos + + + + id + wxgui_scopesink2_1 + + + notebook + nb1,0 + + + num_inputs + 1 + + + samp_rate + samp_rate*(interpolation/float(decimation)) + + + t_scale + 0 + + + title + Resampled signal (csdr) + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + type + float + + + v_offset + 0 + + + v_scale + 0 + + + win_size + + + + xy_mode + False + + + y_axis_label + Counts + + + + wxgui_scopesink2 + + ac_couple + False + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (760, 603) + + + _rotation + 0 + + + grid_pos + + + + id + wxgui_scopesink2_1_0 + + + notebook + nb2,0 + + + num_inputs + 1 + + + samp_rate + samp_rate*(interpolation/float(decimation)) + + + t_scale + 0 + + + title + Resampled signal (GNU Radio) + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + type + float + + + v_offset + 0 + + + v_scale + 0 + + + win_size + + + + xy_mode + False + + + y_axis_label + Counts + - - blocks_throttle_0 - ha5kfu_execproc_xx_0 - 0 - 0 - - - ha5kfu_execproc_xx_0 - wxgui_scopesink2_1 - 0 - 0 - analog_sig_source_x_0 blocks_throttle_0 @@ -1095,8 +1139,14 @@ 0 - ha5kfu_execproc_xx_0 - wxgui_fftsink2_0_0 + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + blocks_throttle_0 + rational_resampler_xxx_0 0 0 @@ -1113,14 +1163,14 @@ 0 - blocks_throttle_0 - rational_resampler_xxx_0 + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0_0 0 0 - rational_resampler_xxx_0 - wxgui_scopesink2_1_0 + ha5kfu_execproc_xx_0 + wxgui_scopesink2_1 0 0 @@ -1130,4 +1180,10 @@ 0 0 + + rational_resampler_xxx_0 + wxgui_scopesink2_1_0 + 0 + 0 + From 59513fc306421994710a6d226bdfea26b325ba41 Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Tue, 28 Feb 2017 17:03:21 +0100 Subject: [PATCH 12/15] Fixed even more docs --- README.md | 4 ++++ libcsdr.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index 117aea6..dbc3f45 100644 --- a/README.md +++ b/README.md @@ -329,6 +329,10 @@ It performs a bandpass FIR filter on complex samples, using FFT and the overlap- Parameters are described under `firdes_bandpass_c` and `firdes_lowpass_f`. + old_fractional_decimator_ff [num_poly_points [transition_bw [window]]] + +This is the deprecated, old version of `fractional_decimator_ff` (only uses linear interpolation, its filter cuts at 59% of the passband). + agc_ff [hang_time [reference [attack_rate [decay_rate [max_gain [attack_wait [filter_alpha]]]]]]] It is an automatic gain control function. diff --git a/libcsdr.c b/libcsdr.c index ff7415c..2d512b2 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -767,6 +767,7 @@ void fractional_decimator_ff(float* input, float* output, int input_size, fracti } /* + * Some notes to myself on the circular buffer I wanted to implement here: int last_input_samplewhere_shouldbe = (index_high-1)+xifirst; int last_input_offset = last_input_samplewhere_shouldbe - d->last_input_samplewhere; if(last_input_offset < num_poly_points) @@ -781,6 +782,7 @@ void fractional_decimator_ff(float* input, float* output, int input_size, fracti } d->last_input_samplewhere = d->las } + However, I think I should just rather do a continuous big buffer. */ void apply_fir_fft_cc(FFT_PLAN_T* plan, FFT_PLAN_T* plan_inverse, complexf* taps_fft, complexf* last_overlap, int overlap_size) From c8eac341109a6d3b0d7a962c9fd310690e1c4197 Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Tue, 28 Feb 2017 17:08:07 +0100 Subject: [PATCH 13/15] Added *.swp to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 71766fd..73f4345 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ ddcd tags dumpvect.*.vect grc_tests/top_block.py +*.swp From d56fc2d7996fbae80cb38e0b68fe97c58bc72d6a Mon Sep 17 00:00:00 2001 From: Andras Retzler Date: Sun, 2 Apr 2017 21:23:47 +0000 Subject: [PATCH 14/15] Fixed segmentation fault in fractional_decimator_ff --- csdr.c | 1 + libcsdr.c | 1 + 2 files changed, 2 insertions(+) diff --git a/csdr.c b/csdr.c index 6bc3e52..0a64c39 100644 --- a/csdr.c +++ b/csdr.c @@ -1372,6 +1372,7 @@ int main(int argc, char *argv[]) fread(input_buffer+(the_bufsize-d.input_processed), sizeof(float), d.input_processed, stdin); fractional_decimator_ff(input_buffer, output_buffer, the_bufsize, &d); fwrite(output_buffer, sizeof(float), d.output_size, stdout); + //fprintf(stderr, "os = %d, ip = %d\n", d.output_size, d.input_processed); TRY_YIELD; } } diff --git a/libcsdr.c b/libcsdr.c index 70e16a3..a77cb68 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -714,6 +714,7 @@ fractional_decimator_ff_t fractional_decimator_ff_init(float rate, int num_poly_ d.rate = rate; d.taps = taps; d.taps_length = taps_length; + d.input_processed = 0; return d; } From 47333b66908df9830a9c66380671bd62726db14a Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Wed, 5 Apr 2017 13:07:17 +0200 Subject: [PATCH 15/15] Make OpenWebRX be more responsive and load faster! --- csdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csdr.c b/csdr.c index 0a64c39..f0f06df 100644 --- a/csdr.c +++ b/csdr.c @@ -136,7 +136,7 @@ int bigbufs = 0; //change on on 2015-08-29: we don't yield at all. fread() will do it if it blocks #define YIELD_EVERY_N_TIMES 3 //#define TRY_YIELD if(++yield_counter%YIELD_EVERY_N_TIMES==0) sched_yield() -#define TRY_YIELD +#define TRY_YIELD fflush(stdout); sched_yield() //unsigned yield_counter=0; int badsyntax(char* why)