Fixed FastDDC! Now it works.

This commit is contained in:
ha7ilm 2015-11-24 22:29:56 +01:00
parent 6efdf7c809
commit 7879191935
2 changed files with 228 additions and 9 deletions

View file

@ -55,12 +55,12 @@ 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; //overlap factor | +-1 ? (or maybe ceil() this?) ddc->v = ddc->fft_size/ddc->overlap_length; //overlap factor | +-1 ? (or maybe ceil() this?)
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;
//fprintf(stderr, "ddc->startbin=%g\n",(float)ddc->startbin); //fprintf(stderr, "ddc->startbin=%g\n",(float)ddc->startbin);
ddc->startbin = ddc->v * round( ddc->startbin / (float)ddc->v ); ddc->startbin = ddc->v * round( ddc->startbin / (float)ddc->v );
//fprintf(stderr, "ddc->startbin=%g\n",(float)ddc->startbin); //fprintf(stderr, "ddc->startbin=%g\n",(float)ddc->startbin);
ddc->offsetbin = ddc->startbin - middlebin; ddc->offsetbin = ddc->startbin - middlebin;
ddc->post_shift = shift_rate-((float)ddc->offsetbin/ddc->fft_size); ddc->post_shift = (ddc->pre_decimation)*(shift_rate+((float)ddc->offsetbin/ddc->fft_size));
ddc->pre_shift = ddc->offsetbin/(float)ddc->fft_size; ddc->pre_shift = ddc->offsetbin/(float)ddc->fft_size;
ddc->dsadata = decimating_shift_addition_init(ddc->post_shift, ddc->post_decimation); ddc->dsadata = decimating_shift_addition_init(ddc->post_shift, ddc->post_decimation);
@ -122,9 +122,10 @@ decimating_shift_addition_status_t fastddc_inv_cc(complexf* input, complexf* out
//Alias & shift & filter at once //Alias & shift & filter at once
fft_swap_sides(input, ddc->fft_size); //TODO this is not very optimal, but now we stick with this slow solution until we got the algorithm working fft_swap_sides(input, ddc->fft_size); //TODO this is not very optimal, but now we stick with this slow solution until we got the algorithm working
//fprintf(stderr, " === fastddc_inv_cc() ===\n"); //fprintf(stderr, " === fastddc_inv_cc() ===\n");
//The problem is, we have to say that the output_index should be the _center_ of the spectrum when i is at startbin! (startbin is at the _center_ of the input to downconvert, not at its first bin!)
for(int i=0;i<ddc->fft_size;i++) for(int i=0;i<ddc->fft_size;i++)
{ {
int output_index = (ddc->fft_size+i-ddc->offsetbin)%plan_inverse->size; int output_index = (ddc->fft_size+i-ddc->offsetbin+(ddc->fft_inv_size/2))%plan_inverse->size;
int tap_index = i; int tap_index = i;
//fprintf(stderr, "output_index = %d , tap_index = %d, input index = %d\n", output_index, tap_index, i); //fprintf(stderr, "output_index = %d , tap_index = %d, input index = %d\n", output_index, tap_index, i);
//cmultadd(inv_input+output_index, input+i, taps_fft+tap_index); //cmultadd(output, input1, input2): complex output += complex input1 * complex input 2 //cmultadd(inv_input+output_index, input+i, taps_fft+tap_index); //cmultadd(output, input1, input2): complex output += complex input1 * complex input 2
@ -149,7 +150,6 @@ decimating_shift_addition_status_t fastddc_inv_cc(complexf* input, complexf* out
fft_swap_sides(inv_input,plan_inverse->size); fft_swap_sides(inv_input,plan_inverse->size);
fft_execute(plan_inverse); fft_execute(plan_inverse);
//Normalize data //Normalize data
for(int i=0;i<plan_inverse->size;i++) //@fastddc_inv_cc: normalize by size for(int i=0;i<plan_inverse->size;i++) //@fastddc_inv_cc: normalize by size
{ {
@ -159,8 +159,8 @@ decimating_shift_addition_status_t fastddc_inv_cc(complexf* input, complexf* out
//Overlap is scrapped, not added //Overlap is scrapped, not added
//Shift correction //Shift correction
//shift_stat=decimating_shift_addition_cc(inv_output+ddc->scrap, output, ddc->post_input_size, ddc->dsadata, ddc->post_decimation, shift_stat); shift_stat=decimating_shift_addition_cc(inv_output+ddc->scrap, output, ddc->post_input_size, ddc->dsadata, ddc->post_decimation, shift_stat);
shift_stat.output_size = ddc->post_input_size; //bypass shift correction //shift_stat.output_size = ddc->post_input_size; //bypass shift correction
memcpy(output, inv_output+ddc->scrap, sizeof(complexf)*ddc->post_input_size); //memcpy(output, inv_output+ddc->scrap, sizeof(complexf)*ddc->post_input_size);
return shift_stat; return shift_stat;
} }

View file

@ -179,7 +179,7 @@
</param> </param>
<param> <param>
<key>value</key> <key>value</key>
<value>250000</value> <value>400000</value>
</param> </param>
</block> </block>
<block> <block>
@ -237,6 +237,57 @@
<value>0</value> <value>0</value>
</param> </param>
</block> </block>
<block>
<key>analog_pll_freqdet_cf</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>(112, 875)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>analog_pll_freqdet_cf_0</value>
</param>
<param>
<key>w</key>
<value>(3.141592654/200)/2</value>
</param>
<param>
<key>max_freq</key>
<value>3.141592654</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>min_freq</key>
<value>-3.141592654</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
</block>
<block> <block>
<key>analog_sig_source_x</key> <key>analog_sig_source_x</key>
<param> <param>
@ -300,6 +351,57 @@
<value>analog.GR_COS_WAVE</value> <value>analog.GR_COS_WAVE</value>
</param> </param>
</block> </block>
<block>
<key>blocks_multiply_const_vxx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>const</key>
<value>(samp_rate/decimation)*(1/(2*3.141592654))</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(136, 763)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_multiply_const_vxx_0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block> <block>
<key>blocks_throttle</key> <key>blocks_throttle</key>
<param> <param>
@ -363,7 +465,7 @@
</param> </param>
<param> <param>
<key>commandline</key> <key>commandline</key>
<value>csdr fastddc_fwd_cc 4 | csdr fastddc_inv_cc 4 -0.1</value> <value>csdr fastddc_fwd_cc %d | csdr fastddc_inv_cc %d 0.4"%(decimation,decimation)+"</value>
</param> </param>
<param> <param>
<key>comment</key> <key>comment</key>
@ -651,6 +753,105 @@
<value>10</value> <value>10</value>
</param> </param>
</block> </block>
<block>
<key>wxgui_numbersink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</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>decimal_places</key>
<value>10</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>factor</key>
<value>1.0</value>
</param>
<param>
<key>_coordinate</key>
<value>(400, 691)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_numbersink2_0</value>
</param>
<param>
<key>max_value</key>
<value>(samp_rate/decimation)/2</value>
</param>
<param>
<key>min_value</key>
<value>(-samp_rate/decimation)/2</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>number_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>show_gauge</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value>PLL locked at</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>units</key>
<value>Hz</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
</block>
<block> <block>
<key>wxgui_scopesink2</key> <key>wxgui_scopesink2</key>
<param> <param>
@ -744,12 +945,24 @@
<source_key>0</source_key> <source_key>0</source_key>
<sink_key>0</sink_key> <sink_key>0</sink_key>
</connection> </connection>
<connection>
<source_block_id>analog_pll_freqdet_cf_0</source_block_id>
<sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection> <connection>
<source_block_id>analog_sig_source_x_0</source_block_id> <source_block_id>analog_sig_source_x_0</source_block_id>
<sink_block_id>blocks_throttle_0</sink_block_id> <sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key> <source_key>0</source_key>
<sink_key>0</sink_key> <sink_key>0</sink_key>
</connection> </connection>
<connection>
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
<sink_block_id>wxgui_numbersink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection> <connection>
<source_block_id>blocks_throttle_0</source_block_id> <source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_1</sink_block_id> <sink_block_id>ha5kfu_execproc_xx_1</sink_block_id>
@ -762,6 +975,12 @@
<source_key>0</source_key> <source_key>0</source_key>
<sink_key>0</sink_key> <sink_key>0</sink_key>
</connection> </connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_1</source_block_id>
<sink_block_id>analog_pll_freqdet_cf_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection> <connection>
<source_block_id>ha5kfu_execproc_xx_1</source_block_id> <source_block_id>ha5kfu_execproc_xx_1</source_block_id>
<sink_block_id>wxgui_fftsink2_0</sink_block_id> <sink_block_id>wxgui_fftsink2_0</sink_block_id>