Fixed segmentation fault and a couple of other things. Added a GRC test for fastddc.

This commit is contained in:
ha7ilm 2015-11-17 10:01:34 +01:00
parent edc2c21e43
commit c7e363d5cf
5 changed files with 1295 additions and 561 deletions

View file

@ -45,7 +45,7 @@ FFTW_PACKAGE = fftw-3.3.3
.PHONY: clean-vect clean .PHONY: clean-vect clean
all: csdr ddcd all: csdr ddcd
libcsdr.so: fft_fftw.c fft_rpi.c libcsdr_wrapper.c libcsdr.c libcsdr_gpl.c *.h libcsdr.so: fft_fftw.c fft_rpi.c libcsdr_wrapper.c libcsdr.c libcsdr_gpl.c fastddc.c *.h
@echo NOTE: you may have to manually edit Makefile to optimize for your CPU \(especially if you compile on ARM, please edit PARAMS_NEON\). @echo NOTE: you may have to manually edit Makefile to optimize for your CPU \(especially if you compile on ARM, please edit PARAMS_NEON\).
@echo Auto-detected optimization parameters: $(PARAMS_SIMD) @echo Auto-detected optimization parameters: $(PARAMS_SIMD)
@echo @echo
@ -63,7 +63,7 @@ clean-vect:
rm -f dumpvect*.vect rm -f dumpvect*.vect
clean: clean-vect clean: clean-vect
rm -f libcsdr.so csdr ddcd rm -f libcsdr.so csdr ddcd
install: install: all
install -m 0755 libcsdr.so /usr/lib install -m 0755 libcsdr.so /usr/lib
install -m 0755 csdr /usr/bin install -m 0755 csdr /usr/bin
install -m 0755 csdr-fm /usr/bin install -m 0755 csdr-fm /usr/bin

25
csdr.c
View file

@ -1649,15 +1649,16 @@ int main(int argc, char *argv[])
if( !strcmp(argv[1],"fastddc_fwd_cc") ) //<decimation> [transition_bw [window]] if( !strcmp(argv[1],"fastddc_fwd_cc") ) //<decimation> [transition_bw [window]]
{ {
int decimation; int decimation;
if(argc<=2) return badsyntax("need required parameter (decimation)"); if(argc<=2) return badsyntax("need required parameter (decimation)");
sscanf(argv[2],"%d",&decimation); sscanf(argv[2],"%d",&decimation);
float transition_bw = 0.05; float transition_bw = 0.05;
if(argc>=3) sscanf(argv[3],"%g",&transition_bw); if(argc>3) sscanf(argv[3],"%g",&transition_bw);
window_t window = WINDOW_DEFAULT; window_t window = WINDOW_DEFAULT;
if(argc>=4) window=firdes_get_window_from_string(argv[5]); if(argc>4) window=firdes_get_window_from_string(argv[5]);
else fprintf(stderr,"fastddc_fwd_cc: window = %s\n",firdes_get_string_from_window(window)); else fprintf(stderr,"fastddc_fwd_cc: window = %s\n",firdes_get_string_from_window(window));
fastddc_t ddc; fastddc_t ddc;
@ -1683,7 +1684,7 @@ int main(int argc, char *argv[])
{ {
FEOF_CHECK; FEOF_CHECK;
//overlapped FFT //overlapped FFT
for(int i=0;i<ddc.overlap_length;i++) input[i]=input[i+ddc.input_size]; for(int i=0;i<ddc.overlap_length;i++) input[i]=input[i+ddc.overlap_length];
fread(input+ddc.overlap_length, sizeof(complexf), ddc.input_size, stdin); fread(input+ddc.overlap_length, sizeof(complexf), ddc.input_size, stdin);
apply_window_c(input,windowed,ddc.fft_size,window); apply_window_c(input,windowed,ddc.fft_size,window);
fft_execute(plan); fft_execute(plan);
@ -1699,13 +1700,13 @@ int main(int argc, char *argv[])
sscanf(argv[2],"%d",&decimation); sscanf(argv[2],"%d",&decimation);
float shift_rate; float shift_rate;
if(argc>=3) sscanf(argv[3],"%g",&shift_rate); if(argc>3) sscanf(argv[3],"%g",&shift_rate);
float transition_bw = 0.05; float transition_bw = 0.05;
if(argc>=4) sscanf(argv[4],"%g",&transition_bw); if(argc>4) sscanf(argv[4],"%g",&transition_bw);
window_t window = WINDOW_DEFAULT; window_t window = WINDOW_DEFAULT;
if(argc>=5) window=firdes_get_window_from_string(argv[5]); if(argc>5) window=firdes_get_window_from_string(argv[5]);
else fprintf(stderr,"fastddc_apply_cc: window = %s\n",firdes_get_string_from_window(window)); else fprintf(stderr,"fastddc_apply_cc: window = %s\n",firdes_get_string_from_window(window));
fastddc_t ddc; fastddc_t ddc;
@ -1726,14 +1727,16 @@ int main(int argc, char *argv[])
fft_execute(plan_taps); fft_execute(plan_taps);
//make FFT plan //make FFT plan
complexf* inv_input = (complexf*)fft_malloc(sizeof(complexf)*ddc.fft_inv_size);
complexf* inv_output = (complexf*)fft_malloc(sizeof(complexf)*ddc.fft_inv_size);
fprintf(stderr,"fastddc_apply_cc: benchmarking FFT...");
FFT_PLAN_T* plan_inverse = make_fft_c2c(ddc.fft_inv_size, inv_input, inv_output, 0, 1); //inverse, do benchmark
fprintf(stderr," done\n");
//alloc. buffers
complexf* input = (complexf*)fft_malloc(sizeof(complexf)*ddc.fft_size); complexf* input = (complexf*)fft_malloc(sizeof(complexf)*ddc.fft_size);
complexf* output = (complexf*)fft_malloc(sizeof(complexf)*ddc.output_size); complexf* output = (complexf*)fft_malloc(sizeof(complexf)*ddc.output_size);
int benchmark = 1;
if(benchmark) fprintf(stderr,"fastddc_apply_cc: benchmarking FFT...");
FFT_PLAN_T* plan_inverse = make_fft_c2c(ddc.fft_size, input, output, 0, 1); //inverse, do benchmark
if(benchmark) fprintf(stderr," done\n");
decimating_shift_addition_status_t shift_stat; decimating_shift_addition_status_t shift_stat;
bzero(&shift_stat, sizeof(shift_stat)); bzero(&shift_stat, sizeof(shift_stat));
for(;;) for(;;)

View file

@ -55,11 +55,11 @@ int fastddc_init(fastddc_t* ddc, float transition_bw, int decimation, float shif
//Shift operation in the frequency domain: we can shift by a multiple of v. //Shift operation in the frequency domain: we can shift by a multiple of v.
ddc->v = ddc->fft_size/ddc->overlap_length; //+-1 ? (or maybe ceil() this?) //TODO: why? ddc->v = ddc->fft_size/ddc->overlap_length; //+-1 ? (or maybe ceil() this?) //TODO: why?
int middlebin=ddc->fft_size / 2; int middlebin=ddc->fft_size / 2;
ddc->startbin = middlebin + middlebin * shift_rate * 2; ddc->startbin = middlebin + middlebin * shift_rate * 2;
ddc->startbin = ddc->v * round( ddc->startbin / (float)ddc->v ); ddc->startbin = ddc->v * round( ddc->startbin / (float)ddc->v );
ddc->offsetbin = ddc->startbin - middlebin; ddc->offsetbin = ddc->startbin - middlebin;
ddc->post_shift = ((float)ddc->offsetbin/ddc->fft_size) - shift_rate; ddc->post_shift = shift_rate-((float)ddc->offsetbin/ddc->fft_size);
ddc->pre_shift = ddc->offsetbin * ddc->v; ddc->pre_shift = ddc->offsetbin/(float)ddc->fft_size;
//Overlap is scraped, not added //Overlap is scraped, not added
ddc->scrape=ddc->overlap_length/ddc->pre_decimation; ddc->scrape=ddc->overlap_length/ddc->pre_decimation;
@ -73,14 +73,16 @@ void fastddc_print(fastddc_t* ddc)
{ {
fprintf(stderr, fprintf(stderr,
"fastddc_print_sizes(): (fft_size = %d) = (taps_length = %d) + (input_size = %d) - 1\n" "fastddc_print_sizes(): (fft_size = %d) = (taps_length = %d) + (input_size = %d) - 1\n"
"\t(overlap_length = %d) = taps_length - 1, taps_real_length = %d\n" " overlap :: (overlap_length = %d) = taps_length - 1, taps_real_length = %d\n"
"\tdecimation = (pre_decimation = %d) * (post_decimation = %d), fft_inv_size = %d\n" " decimation :: decimation = (pre_decimation = %d) * (post_decimation = %d), fft_inv_size = %d\n"
"\tstartbin = %d, offsetbin = %d, v = %d, pre_shift = %g, post_shift = %g\n" " shift :: startbin = %d, offsetbin = %d, v = %d, pre_shift = %g, post_shift = %g\n"
" o&s :: output_size = %d, scrape = %d\n"
, ,
ddc->fft_size, ddc->taps_length, ddc->input_size, ddc->fft_size, ddc->taps_length, ddc->input_size,
ddc->overlap_length, ddc->taps_real_length, ddc->overlap_length, ddc->taps_real_length,
ddc->pre_decimation, ddc->post_decimation, ddc->fft_inv_size, ddc->pre_decimation, ddc->post_decimation, ddc->fft_inv_size,
ddc->startbin, ddc->offsetbin, ddc->v, ddc->pre_shift, ddc->post_shift ); ddc->startbin, ddc->offsetbin, ddc->v, ddc->pre_shift, ddc->post_shift,
ddc->output_size, ddc->scrape );
} }
decimating_shift_addition_status_t fastddc_apply_cc(complexf* input, complexf* output, fastddc_t* ddc, FFT_PLAN_T* plan_inverse, complexf* taps_fft, decimating_shift_addition_status_t shift_stat) decimating_shift_addition_status_t fastddc_apply_cc(complexf* input, complexf* output, fastddc_t* ddc, FFT_PLAN_T* plan_inverse, complexf* taps_fft, decimating_shift_addition_status_t shift_stat)
@ -120,6 +122,6 @@ decimating_shift_addition_status_t fastddc_apply_cc(complexf* input, complexf* o
//Overlap is scraped, not added //Overlap is scraped, not added
//Shift correction //Shift correction
shift_addition_data_t dsadata=decimating_shift_addition_init(ddc->post_shift, ddc->post_decimation); //this could be optimized (passed as parameter), but we would not win too much at all shift_addition_data_t dsadata=decimating_shift_addition_init(ddc->post_shift, ddc->post_decimation); //this could be optimized (passed as parameter), but we would not win too much at all
shift_stat=decimating_shift_addition_cc(plan_inverse->output+ddc->scrape, output, ddc->output_size, dsadata, ddc->post_decimation, shift_stat); shift_stat=decimating_shift_addition_cc(inv_output+ddc->scrape, output, ddc->output_size, dsadata, ddc->post_decimation, shift_stat);
return shift_stat; return shift_stat;
} }

File diff suppressed because it is too large Load diff

689
grc_tests/test_fastddc.grc Normal file
View file

@ -0,0 +1,689 @@
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.8'?>
<flow_graph>
<timestamp>Sat Nov 15 20:06:19 2014</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>thread_safe_setters</key>
<value></value>
</param>
<param>
<key>title</key>
<value></value>
</param>
</block>
<block>
<key>variable_slider</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>converver</key>
<value>float_converter</value>
</param>
<param>
<key>value</key>
<value>50</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(16, 267)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>freq</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>max</key>
<value>samp_rate/2</value>
</param>
<param>
<key>min</key>
<value>-samp_rate/2</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>num_steps</key>
<value>100</value>
</param>
<param>
<key>style</key>
<value>wx.SL_HORIZONTAL</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(9, 170)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>value</key>
<value>250000</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>amp</key>
<value>0.2</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>freq</key>
<value>freq</value>
</param>
<param>
<key>_coordinate</key>
<value>(224, 29)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>waveform</key>
<value>analog.GR_COS_WAVE</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(424, 59)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr fastddc_fwd_cc 10 | csdr fastddc_apply_cc 10 0.1 | csdr floatdump_f 2&gt;&amp;1 | head -n 100</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(584, 59)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_1</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(160, 283)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>nb</value>
</param>
<param>
<key>labels</key>
<value>['FFT', 'Scope']</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(936, 155)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>notebook</key>
<value>nb, 0</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT plot of csdr processed signal</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(936, 371)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT plot of original signal</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(952, 35)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>notebook</key>
<value>nb, 1</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>title</key>
<value>Scope plot of csdr processed signal</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
</block>
<connection>
<source_block_id>analog_sig_source_x_0</source_block_id>
<sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_1</source_block_id>
<sink_block_id>wxgui_fftsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_1</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>