From 22ea31d5b121e89c67641436449fc7552a3e0993 Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Sun, 19 Feb 2017 14:02:10 +0100 Subject: [PATCH 1/4] First modifications for fir_interpolate_cc, from last April --- csdr.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ libcsdr.c | 18 ++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/csdr.c b/csdr.c index 5763f23..31d8ddc 100644 --- a/csdr.c +++ b/csdr.c @@ -848,6 +848,62 @@ int main(int argc, char *argv[]) //fprintf(stderr,"iskip=%d output_size=%d start=%x target=%x skipcount=%x \n",input_skip,output_size,input_buffer, ((complexf*)input_buffer)+(BIG_BUFSIZE-input_skip),(BIG_BUFSIZE-input_skip)); } } + + if(!strcmp(argv[1],"fir_interpolate_cc")) + { + bigbufs=1; + + if(argc<=2) return badsyntax("need required parameter (interpolation factor)"); + + int factor; + sscanf(argv[2],"%d",&factor); + + float transition_bw = 0.05; + 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,"fir_interpolate_cc: window = %s\n",firdes_get_string_from_window(window)); + + int taps_length=firdes_filter_len(transition_bw); + fprintf(stderr,"fir_interpolate_cc: taps_length = %d\n",taps_length); + + while (env_csdr_fixed_big_bufsize < taps_length*2) env_csdr_fixed_big_bufsize*=2; //temporary fix for buffer size if [transition_bw] is low + //fprintf(stderr, "env_csdr_fixed_big_bufsize = %d\n", env_csdr_fixed_big_bufsize); + + if(!initialize_buffers()) return -2; + sendbufsize(the_bufsize/factor); + + + float *taps; + taps=(float*)malloc(taps_length*sizeof(float)); + + firdes_lowpass_f(taps,taps_length,0.5/(float)factor,window); + + int input_skip=0; + int output_size=0; + FREAD_C; + for(;;) + { + FEOF_CHECK; + output_size=fir_interpolate_cc((complexf*)input_buffer, (complexf*)output_buffer, the_bufsize, factor, taps, taps_length); + //fprintf(stderr, "os %d\n",output_size); + fwrite(output_buffer, sizeof(complexf), output_size, stdout); + fflush(stdout); + TRY_YIELD; + input_skip=factor*output_size; + memmove((complexf*)input_buffer,((complexf*)input_buffer)+input_skip,(the_bufsize-input_skip)*sizeof(complexf)); //memmove lets the source and destination overlap + fread(((complexf*)input_buffer)+(the_bufsize-input_skip), sizeof(complexf), input_skip, stdin); + //fprintf(stderr,"iskip=%d output_size=%d start=%x target=%x skipcount=%x \n",input_skip,output_size,input_buffer, ((complexf*)input_buffer)+(BIG_BUFSIZE-input_skip),(BIG_BUFSIZE-input_skip)); + } + } + + + + /*if(!strcmp(argv[1],"ejw_test")) { printf("ejqd=["); diff --git a/libcsdr.c b/libcsdr.c index e3b01bf..f5da71c 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -379,6 +379,24 @@ int fir_decimate_cc(complexf *input, complexf *output, int input_size, int decim } */ +int fir_interpolate_cc(complexf *input, complexf *output, int input_size, int interpolation, float *taps, int taps_length) +{ + int oi=0; + for(int i=0; iinput_size) break; + float acci=0; + for(int ti=0; ti Date: Sun, 19 Feb 2017 15:41:33 +0100 Subject: [PATCH 2/4] Almost there at working interpolator --- csdr.c | 17 +++++++++++------ libcsdr.c | 26 +++++++++++++++++--------- libcsdr.h | 1 + 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/csdr.c b/csdr.c index 31d8ddc..c135c61 100644 --- a/csdr.c +++ b/csdr.c @@ -48,6 +48,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ima_adpcm.h" #include #include +#include char usage[]= "csdr - a simple commandline tool for Software Defined Radio receiver DSP.\n\n" @@ -857,9 +858,11 @@ int main(int argc, char *argv[]) int factor; sscanf(argv[2],"%d",&factor); + assert(factor >= 1); float transition_bw = 0.05; if(argc>=4) sscanf(argv[3],"%g",&transition_bw); + assert(transition_bw >= 0 && transition_bw < 1.); window_t window = WINDOW_DEFAULT; if(argc>=5) @@ -870,31 +873,33 @@ int main(int argc, char *argv[]) int taps_length=firdes_filter_len(transition_bw); fprintf(stderr,"fir_interpolate_cc: taps_length = %d\n",taps_length); + assert(taps_length > 0); while (env_csdr_fixed_big_bufsize < taps_length*2) env_csdr_fixed_big_bufsize*=2; //temporary fix for buffer size if [transition_bw] is low //fprintf(stderr, "env_csdr_fixed_big_bufsize = %d\n", env_csdr_fixed_big_bufsize); if(!initialize_buffers()) return -2; - sendbufsize(the_bufsize/factor); - + sendbufsize(the_bufsize*factor); + assert(the_bufsize > 0); float *taps; taps=(float*)malloc(taps_length*sizeof(float)); + assert(taps); firdes_lowpass_f(taps,taps_length,0.5/(float)factor,window); int input_skip=0; int output_size=0; - FREAD_C; + float* interp_output_buffer = (float*)malloc(sizeof(float)*2*the_bufsize*factor); for(;;) { FEOF_CHECK; - output_size=fir_interpolate_cc((complexf*)input_buffer, (complexf*)output_buffer, the_bufsize, factor, taps, taps_length); + output_size=fir_interpolate_cc((complexf*)input_buffer, (complexf*)interp_output_buffer, the_bufsize, factor, taps, taps_length); //fprintf(stderr, "os %d\n",output_size); - fwrite(output_buffer, sizeof(complexf), output_size, stdout); + fwrite(interp_output_buffer, sizeof(complexf), output_size, stdout); fflush(stdout); TRY_YIELD; - input_skip=factor*output_size; + input_skip=output_size/factor; memmove((complexf*)input_buffer,((complexf*)input_buffer)+input_skip,(the_bufsize-input_skip)*sizeof(complexf)); //memmove lets the source and destination overlap fread(((complexf*)input_buffer)+(the_bufsize-input_skip), sizeof(complexf), input_skip, stdin); //fprintf(stderr,"iskip=%d output_size=%d start=%x target=%x skipcount=%x \n",input_skip,output_size,input_buffer, ((complexf*)input_buffer)+(BIG_BUFSIZE-input_skip),(BIG_BUFSIZE-input_skip)); diff --git a/libcsdr.c b/libcsdr.c index f5da71c..2e02c8b 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -381,17 +381,25 @@ int fir_decimate_cc(complexf *input, complexf *output, int input_size, int decim int fir_interpolate_cc(complexf *input, complexf *output, int input_size, int interpolation, float *taps, int taps_length) { + //i: input index + //oi: output index + //ti: tap index + //ti: secondary index (inside filter function) + //ip: interpolation phase (0 <= ip < interpolation) int oi=0; - for(int i=0; iinput_size) break; - float acci=0; - for(int ti=0; ti input_size*interpolation) break; + for(int ip=0; ip Date: Sun, 19 Feb 2017 16:06:08 +0100 Subject: [PATCH 3/4] Working interpolator. --- csdr.c | 2 +- libcsdr.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/csdr.c b/csdr.c index c135c61..d297f61 100644 --- a/csdr.c +++ b/csdr.c @@ -860,7 +860,7 @@ int main(int argc, char *argv[]) sscanf(argv[2],"%d",&factor); assert(factor >= 1); - float transition_bw = 0.05; + float transition_bw = 0.01; if(argc>=4) sscanf(argv[3],"%g",&transition_bw); assert(transition_bw >= 0 && transition_bw < 1.); diff --git a/libcsdr.c b/libcsdr.c index 2e02c8b..5483f79 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -394,8 +394,10 @@ int fir_interpolate_cc(complexf *input, complexf *output, int input_size, int in { float acci=0; float accq=0; - for(int ti=ip, si=0; ti Date: Sun, 19 Feb 2017 16:22:49 +0100 Subject: [PATCH 4/4] Added to README and --help as well --- README.md | 7 +- csdr.c | 3 +- grc_tests/test_fir_interpolate_cc.grc | 1212 +++++++++++++++++++++++++ libcsdr.c | 4 +- 4 files changed, 1222 insertions(+), 4 deletions(-) create mode 100644 grc_tests/test_fir_interpolate_cc.grc diff --git a/README.md b/README.md index eb8edfe..72620f0 100644 --- a/README.md +++ b/README.md @@ -287,7 +287,12 @@ Other parameters were explained above at `firdes_lowpass_f`. fir_decimate_cc [transition_bw [window]] It is a decimator that keeps one sample out of `decimation_factor` samples. -To avoid aliasing, it runs a filter on the signal and removes spectral components above `0.5 × nyquist_frequency × decimation_factor`. +To avoid aliasing, it runs a filter on the signal and removes spectral components above `0.5 × nyquist_frequency × decimation_factor` from the input signal. + + fir_interpolate_cc [transition_bw [window]] + +It is an interpolator that generates `interpolation_factor` number of output samples from one input sample. +To avoid aliasing, it runs a filter on the signal and removes spectral components above `0.5 × nyquist_frequency / interpolation_factor` from the output signal. `transition_bw` and `window` are the parameters of the filter. diff --git a/csdr.c b/csdr.c index d297f61..a2beb4a 100644 --- a/csdr.c +++ b/csdr.c @@ -88,6 +88,7 @@ char usage[]= " amdemod_cf\n" " amdemod_estimator_cf\n" " fir_decimate_cc [transition_bw [window]]\n" +" fir_interpolate_cc [transition_bw [window]]\n" " firdes_lowpass_f [window [--octave]]\n" " firdes_bandpass_c [window [--octave]]\n" " agc_ff [hang_time [reference [attack_rate [decay_rate [max_gain [attack_wait [filter_alpha]]]]]]]\n" @@ -860,7 +861,7 @@ int main(int argc, char *argv[]) sscanf(argv[2],"%d",&factor); assert(factor >= 1); - float transition_bw = 0.01; + float transition_bw = 0.05; if(argc>=4) sscanf(argv[3],"%g",&transition_bw); assert(transition_bw >= 0 && transition_bw < 1.); diff --git a/grc_tests/test_fir_interpolate_cc.grc b/grc_tests/test_fir_interpolate_cc.grc new file mode 100644 index 0000000..65eb887 --- /dev/null +++ b/grc_tests/test_fir_interpolate_cc.grc @@ -0,0 +1,1212 @@ + + + + Tue Nov 25 18:16:05 2014 + + options + + author + + + + window_size + 1280, 1024 + + + category + Custom + + + comment + + + + description + + + + _enabled + True + + + _coordinate + (10, 10) + + + _rotation + 0 + + + generate_options + wx_gui + + + id + top_block + + + max_nouts + 0 + + + realtime_scheduling + + + + run_options + prompt + + + run + True + + + thread_safe_setters + + + + title + + + + + variable_slider + + comment + + + + converver + float_converter + + + value + 4e3 + + + _enabled + True + + + _coordinate + (8, 331) + + + _rotation + 0 + + + grid_pos + 2,1,1,1 + + + id + input_freq + + + label + + + + max + samp_rate/2 + + + min + -samp_rate/2 + + + notebook + + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (432, 11) + + + _rotation + 0 + + + id + interpolation + + + value + 2 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (176, 11) + + + _rotation + 0 + + + id + samp_rate + + + value + 240000 + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (328, 11) + + + _rotation + 0 + + + id + samp_rate_2 + + + value + samp_rate*interpolation + + + + variable + + comment + + + + _enabled + True + + + _coordinate + (536, 11) + + + _rotation + 0 + + + id + transition_bw + + + value + 0.01 + + + + 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 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + offset + 0 + + + type + complex + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + + blocks_throttle + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (168, 115) + + + _rotation + 0 + + + id + blocks_throttle_0 + + + ignoretag + True + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samples_per_second + samp_rate + + + type + complex + + + vlen + 1 + + + + ha5kfu_execproc_xx + + alias + + + + commandline + "csdr fir_interpolate_cc "+str(interpolation)+" "+str(transition_bw) + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (352, 115) + + + _rotation + 0 + + + id + ha5kfu_execproc_xx_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + type + cc + + + + interp_fir_filter_xxx + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (368, 643) + + + _rotation + 0 + + + id + interp_fir_filter_xxx_0 + + + interp + interpolation + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_delay + 0 + + + taps + firdes.low_pass(1,1,1./(2*interpolation), transition_bw) + + + type + ccc + + + + notebook + + alias + + + + comment + + + + _enabled + True + + + _coordinate + (16, 683) + + + _rotation + 0 + + + grid_pos + 1,2,1,1 + + + id + nb0 + + + labels + ['scope','fft'] + + + notebook + + + + style + wx.NB_TOP + + + + notebook + + alias + + + + 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, 235) + + + _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_2 + + + title + Resampled signal (csdr) + + + type + complex + + + 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 + (640, 579) + + + _rotation + 0 + + + grid_pos + + + + 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 + complex + + + 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 + (360, 355) + + + _rotation + 0 + + + grid_pos + + + + 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 + complex + + + win_size + + + + win + None + + + y_divs + 10 + + + y_per_div + 10 + + + + wxgui_scopesink2 + + ac_couple + False + + + alias + + + + comment + + + + affinity + + + + _enabled + True + + + _coordinate + (640, 115) + + + _rotation + 0 + + + grid_pos + + + + 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 + complex + + + 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 + (360, 235) + + + _rotation + 0 + + + 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 + complex + + + 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 + (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 + complex + + + v_offset + 0 + + + v_scale + 0 + + + win_size + + + + xy_mode + False + + + y_axis_label + Counts + + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + blocks_throttle_0 + interp_fir_filter_xxx_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_1 + 0 + 0 + + + blocks_throttle_0 + wxgui_scopesink2_0_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0 + 0 + 0 + + + interp_fir_filter_xxx_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + interp_fir_filter_xxx_0 + wxgui_scopesink2_0_1 + 0 + 0 + + diff --git a/libcsdr.c b/libcsdr.c index 5483f79..04440c5 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -396,8 +396,8 @@ int fir_interpolate_cc(complexf *input, complexf *output, int input_size, int in float accq=0; //int tistart = (interpolation-ip)%interpolation; int tistart = (interpolation-ip); //why does this work? why don't we need the % part? - for(int ti=tistart, si=0; ti