An actually really working costas loop

This commit is contained in:
ha7ilm 2017-04-01 21:30:58 +02:00
parent c7137dc68e
commit df81d6847e
2 changed files with 384 additions and 9 deletions

View file

@ -69,6 +69,65 @@
<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>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(480, 3)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>amplitude</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>max</key>
<value>2</value>
</param>
<param>
<key>min</key>
<value>0</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_slider</key>
<param>
@ -109,11 +168,11 @@
</param>
<param>
<key>max</key>
<value>samp_rate*0.01</value>
<value>samp_rate*0.5</value>
</param>
<param>
<key>min</key>
<value>-samp_rate*0.01</value>
<value>-samp_rate*0.5</value>
</param>
<param>
<key>notebook</key>
@ -128,6 +187,65 @@
<value>wx.SL_HORIZONTAL</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>0.3</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(712, 571)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>loop_bw</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>max</key>
<value>0.5</value>
</param>
<param>
<key>min</key>
<value>0</value>
</param>
<param>
<key>notebook</key>
<value>nb, 1</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>
@ -312,6 +430,57 @@
<value>1</value>
</param>
</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>amplitude</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(496, 155)</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>complex</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>
<key>blocks_throttle</key>
<param>
@ -332,7 +501,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(456, 211)</value>
<value>(488, 211)</value>
</param>
<param>
<key>_rotation</key>
@ -367,6 +536,57 @@
<value>1</value>
</param>
</block>
<block>
<key>digital_costas_loop_cc</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>(928, 537)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>digital_costas_loop_cc_0</value>
</param>
<param>
<key>w</key>
<value>loop_bw</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>order</key>
<value>2</value>
</param>
<param>
<key>use_snr</key>
<value>False</value>
</param>
</block>
<block>
<key>digital_psk_mod</key>
<param>
@ -599,7 +819,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(432, 411)</value>
<value>(400, 411)</value>
</param>
<param>
<key>_rotation</key>
@ -622,6 +842,49 @@
<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>(16, 83)</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>['1', '2']</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>
@ -749,7 +1012,7 @@
</param>
<param>
<key>_coordinate</key>
<value>(824, 507)</value>
<value>(632, 379)</value>
</param>
<param>
<key>_rotation</key>
@ -852,8 +1115,95 @@
</param>
<param>
<key>notebook</key>
<value>nb, 0</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>(samp_rate/256)*8</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>title</key>
<value>After Costas Loop</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>True</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</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>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(1112, 491)</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_0_0</value>
</param>
<param>
<key>notebook</key>
<value>nb, 1</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
@ -1010,15 +1360,27 @@
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_multiply_const_vxx_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>freq_xlating_fir_filter_xxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>digital_costas_loop_cc_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>digital_psk_mod_0</source_block_id>
<sink_block_id>blocks_throttle_0</sink_block_id>
<sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
@ -1028,6 +1390,12 @@
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>freq_xlating_fir_filter_xxx_0</source_block_id>
<sink_block_id>digital_costas_loop_cc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>freq_xlating_fir_filter_xxx_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0</sink_block_id>

View file

@ -1942,7 +1942,8 @@ bpsk_costas_loop_state_t init_bpsk_costas_loop_cc(float samples_per_bits)
float virtual_sampling_rate = 10000;
float virtual_data_rate = virtual_sampling_rate / samples_per_bits;
fprintf(stderr, "virtual_sampling_rate = %g, virtual_data_rate = %g\n", virtual_sampling_rate, virtual_data_rate);
float rc_filter_cutoff = virtual_data_rate/2;
//float rc_filter_cutoff = virtual_data_rate * 2; //this is so far the best
float rc_filter_cutoff = virtual_data_rate * 2;
float rc_filter_rc = 1/(2*M_PI*rc_filter_cutoff); //as of Equation 24 in Feigin
float virtual_sampling_dt = 1.0/virtual_sampling_rate;
fprintf(stderr, "rc_filter_cutoff = %g, rc_filter_rc = %g, virtual_sampling_dt = %g\n",
@ -1966,18 +1967,24 @@ void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, bpsk
if(debug) fprintf(stderr, "%g | %g\n", input_and_vco_mixed_phase, input_phase), debug--;
complexf input_and_vco_mixed_sample;
e_powj(&input_and_vco_mixed_sample, input_and_vco_mixed_phase);
complexf vco_sample;
e_powj(&vco_sample, -state->vco_phase);
//cmult(&input_and_vco_mixed_sample, &input[i], &vco_sample);//if this is enabled, the real input sample is used, not the amplitude normalized
float loop_output_i =
input_and_vco_mixed_sample.i * state->rc_filter_alpha + state->last_lpfi_output * (1-state->rc_filter_alpha);
float loop_output_q =
input_and_vco_mixed_sample.q * state->rc_filter_alpha + state->last_lpfq_output * (1-state->rc_filter_alpha);
//loop_output_i = input_and_vco_mixed_sample.i;
//loop_output_q = input_and_vco_mixed_sample.q;
state->last_lpfi_output = loop_output_i;
state->last_lpfq_output = loop_output_q;
float vco_phase_addition = loop_output_i * loop_output_q * state->vco_phase_addition_multiplier;
state->vco_phase += vco_phase_addition;
while(state->vco_phase>PI) state->vco_phase-=2*PI;
while(state->vco_phase<-PI) state->vco_phase+=2*PI;
output[i].i = loop_output_i;
output[i].q = loop_output_q;
cmult(&output[i], &input[i], &vco_sample);
}
}