Fixed CLI for timing recovery, added max_dphase for Costas

This commit is contained in:
ha7ilm 2017-05-15 21:35:58 +02:00
parent fe46aba98d
commit 50528abd71
5 changed files with 587 additions and 63 deletions

31
csdr.c
View file

@ -127,7 +127,7 @@ char usage[]=
" rtty_baudot2ascii_u8_u8\n" " rtty_baudot2ascii_u8_u8\n"
" serial_line_decoder_f_u8 <samples_per_bits> [databits [stopbits]]\n" " serial_line_decoder_f_u8 <samples_per_bits> [databits [stopbits]]\n"
" octave_complex_c <samples_to_plot> <out_of_n_samples>\n" " octave_complex_c <samples_to_plot> <out_of_n_samples>\n"
" timing_recovery_cc <algorithm> <decimation> [mu [--add_q [--output_error | --output_indexes | --octave <debug_n>]]] \n" " timing_recovery_cc <algorithm> <decimation> [mu [--add_q [--output_error | --output_indexes | --octave <show_every_nth> | --octave_save <show_every_nth> <directory> ]]] \n"
" psk31_varicode_encoder_u8_u8\n" " psk31_varicode_encoder_u8_u8\n"
" psk31_varicode_decoder_u8_u8\n" " psk31_varicode_decoder_u8_u8\n"
" differential_encoder_u8_u8\n" " differential_encoder_u8_u8\n"
@ -136,7 +136,7 @@ char usage[]=
" psk_modulator_u8_c <n_psk>\n" " psk_modulator_u8_c <n_psk>\n"
" psk31_interpolate_sine_cc <interpolation>\n" " psk31_interpolate_sine_cc <interpolation>\n"
" duplicate_samples_ntimes_u8_u8 <sample_size_bytes> <ntimes>\n" " duplicate_samples_ntimes_u8_u8 <sample_size_bytes> <ntimes>\n"
" bpsk_costas_loop_cc //<loop_bandwidth> <damping_factor> [--dd | --decision_directed] [--output_error | --output_dphase | --output_nco | --output_combined <error_file> <dphase_file> <nco_file>]\n" " bpsk_costas_loop_cc <loop_bandwidth> <damping_factor> [--dd | --decision_directed] [--output_error | --output_dphase | --output_nco | --output_combined <error_file> <dphase_file> <nco_file>]\n"
" binary_slicer_f_u8\n" " binary_slicer_f_u8\n"
" simple_agc_cc <rate> [reference [max_gain]]\n" " simple_agc_cc <rate> [reference [max_gain]]\n"
" firdes_peak_c <rate> <length> [window [--octave]]\n" " firdes_peak_c <rate> <length> [window [--octave]]\n"
@ -2549,7 +2549,7 @@ int main(int argc, char *argv[])
} }
} }
if(!strcmp(argv[1],"timing_recovery_cc")) //<algorithm> <decimation> [loop_gain [max_error [--add_q] [--output_error | --output_indexes | --octave <debug_n>]]] if(!strcmp(argv[1],"timing_recovery_cc")) //<algorithm> <decimation> [mu [max_error [--add_q [--output_error | --output_indexes | --octave <show_every_nth> | --octave_save <show_every_nth> <directory> ]]]] \n"
{ {
if(argc<=2) return badsyntax("need required parameter (algorithm)"); if(argc<=2) return badsyntax("need required parameter (algorithm)");
timing_recovery_algorithm_t algorithm = timing_recovery_get_algorithm_from_string(argv[2]); timing_recovery_algorithm_t algorithm = timing_recovery_get_algorithm_from_string(argv[2]);
@ -2568,11 +2568,22 @@ int main(int argc, char *argv[])
int add_q = !!(argc>=7 && !strcmp(argv[6], "--add_q")); int add_q = !!(argc>=7 && !strcmp(argv[6], "--add_q"));
int debug_n = 0; int debug_every_nth = -1;
int output_error = 0; int output_error = 0;
int output_indexes = 0; int output_indexes = 0;
if(argc+add_q>=8 && !strcmp(argv[6+add_q], "--octave")) debug_n = atoi(argv[7+add_q]); int octave_save = 0;
if(debug_n<0) return badsyntax("debug_n should be >= 0"); char* octave_save_path = NULL;
if(argc>=8+add_q && (!strcmp(argv[6+add_q], "--octave") || (octave_save = !strcmp(argv[6+add_q], "--octave_save"))))
{
debug_every_nth = atoi(argv[7+add_q]);
if(debug_every_nth<0) return badsyntax("debug_every_nth should be >= 0");
}
if(octave_save)
{
if(argc>=9+add_q) octave_save_path = argv[8+add_q];
else octave_save_path = "figs";
}
if(debug_every_nth<0) { errhead(); fprintf(stderr, "--add_q mode on\n"); }
if(argc>=(8+add_q) && !strcmp(argv[7+add_q], "--output_error")) output_error = 1; if(argc>=(8+add_q) && !strcmp(argv[7+add_q], "--output_error")) output_error = 1;
float* timing_error = NULL; float* timing_error = NULL;
@ -2585,17 +2596,13 @@ int main(int argc, char *argv[])
if(!initialize_buffers()) return -2; if(!initialize_buffers()) return -2;
sendbufsize(the_bufsize/decimation); sendbufsize(the_bufsize/decimation);
timing_recovery_state_t state = timing_recovery_init(algorithm, decimation, add_q, loop_gain, max_error); timing_recovery_state_t state = timing_recovery_init(algorithm, decimation, add_q, loop_gain, max_error, debug_every_nth, octave_save_path);
int debug_i=0;
state.debug_writefiles = 1;
state.debug_force = !!debug_n; //should remove that later
FREAD_C; FREAD_C;
unsigned buffer_start_counter = 0; unsigned buffer_start_counter = 0;
for(;;) for(;;)
{ {
FEOF_CHECK; FEOF_CHECK;
if(debug_n && ++debug_i%debug_n==0) timing_recovery_trigger_debug(&state, 3);
timing_recovery_cc((complexf*)input_buffer, (complexf*)output_buffer, the_bufsize, timing_error, (int*)sampled_indexes, &state); timing_recovery_cc((complexf*)input_buffer, (complexf*)output_buffer, the_bufsize, timing_error, (int*)sampled_indexes, &state);
//fprintf(stderr, "trcc is=%d, os=%d, ip=%d\n",the_bufsize, state.output_size, state.input_processed); //fprintf(stderr, "trcc is=%d, os=%d, ip=%d\n",the_bufsize, state.output_size, state.input_processed);
if(timing_error) fwrite(timing_error, sizeof(float), state.output_size, stdout); if(timing_error) fwrite(timing_error, sizeof(float), state.output_size, stdout);
@ -2819,9 +2826,9 @@ int main(int argc, char *argv[])
FILE* file_output_error = NULL; FILE* file_output_error = NULL;
FILE* file_output_dphase = NULL; FILE* file_output_dphase = NULL;
FILE* file_output_nco = NULL; FILE* file_output_nco = NULL;
if(!(argc>4+decision_directed+3)) { errhead(); return badsyntax("need required parameters after --output_combined: <error_file> <dphase_file> <nco_file>"); }
if(output_combined) if(output_combined)
{ {
if(!(argc>4+decision_directed+3)) { return badsyntax("need required parameters after --output_combined: <error_file> <dphase_file> <nco_file>"); }
file_output_error = fopen(argv[4+decision_directed+1], "w"); file_output_error = fopen(argv[4+decision_directed+1], "w");
file_output_dphase = fopen(argv[4+decision_directed+2], "w"); file_output_dphase = fopen(argv[4+decision_directed+2], "w");
file_output_nco = fopen(argv[4+decision_directed+3], "w"); file_output_nco = fopen(argv[4+decision_directed+3], "w");

View file

@ -257,7 +257,7 @@
</param> </param>
<param> <param>
<key>commandline</key> <key>commandline</key>
<value>csdr dsb_fc | csdr shift_addition_cc $(csdr =-2000./48e3) | csdr fir_decimate_cc 32 | csdr simple_agc_cc 0.0001 0.5</value> <value>csdr dsb_fc | csdr shift_addition_cc $(csdr =-2000./48e3) | csdr fir_decimate_cc 32</value>
</param> </param>
<param> <param>
<key>comment</key> <key>comment</key>
@ -304,7 +304,7 @@
</param> </param>
<param> <param>
<key>commandline</key> <key>commandline</key>
<value>csdr bpsk_costas_loop_cc 48</value> <value>csdr bpsk_costas_loop_cc 0.05 0.707</value>
</param> </param>
<param> <param>
<key>comment</key> <key>comment</key>
@ -316,7 +316,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>True</value> <value>0</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
@ -363,7 +363,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>1</value> <value>0</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
@ -390,6 +390,53 @@
<value>cc</value> <value>cc</value>
</param> </param>
</block> </block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr bandpass_fir_fft_cc $(csdr '=-(31.25)/1.5e3') $(csdr '=(31.25)/1.5e3') $(csdr '=31.25/1.5e3') | csdr simple_agc_cc 0.0001 0.5 </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>(568, 643)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0_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> <block>
<key>notebook</key> <key>notebook</key>
<param> <param>
@ -422,7 +469,7 @@
</param> </param>
<param> <param>
<key>labels</key> <key>labels</key>
<value>['tab1', 'tab2', 'tab3', 'tab4']</value> <value>['tab1', 'channel', 'tab3', 'tab4','bpf']</value>
</param> </param>
<param> <param>
<key>notebook</key> <key>notebook</key>
@ -667,7 +714,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>True</value> <value>0</value>
</param> </param>
<param> <param>
<key>fft_size</key> <key>fft_size</key>
@ -742,6 +789,109 @@
<value>10</value> <value>10</value>
</param> </param>
</block> </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>1</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(832, 563)</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_1_0</value>
</param>
<param>
<key>notebook</key>
<value>nb, 4</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/32</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>window.hamming</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block> <block>
<key>wxgui_scopesink2</key> <key>wxgui_scopesink2</key>
<param> <param>
@ -762,7 +912,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>True</value> <value>0</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
@ -849,7 +999,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>1</value> <value>0</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
@ -916,6 +1066,283 @@
<value>Counts</value> <value>Counts</value>
</param> </param>
</block> </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>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(832, 787)</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,4</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate/32</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>title</key>
<value>Scope Plot</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>
<block>
<key>wxgui_waterfallsink2</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>dynamic_range</key>
<value>100</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>fft_size</key>
<value>512</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(840, 907)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_waterfallsink2_0</value>
</param>
<param>
<key>notebook</key>
<value>nb,4</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate/32</value>
</param>
<param>
<key>title</key>
<value>Waterfall Plot</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>
</block>
<block>
<key>wxgui_waterfallsink2</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>dynamic_range</key>
<value>100</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>fft_size</key>
<value>512</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(1120, 43)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_waterfallsink2_0_0</value>
</param>
<param>
<key>notebook</key>
<value>nb,1</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate/32</value>
</param>
<param>
<key>title</key>
<value>Waterfall Plot</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>
</block>
<connection> <connection>
<source_block_id>audio_source_0</source_block_id> <source_block_id>audio_source_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0</sink_block_id> <sink_block_id>ha5kfu_execproc_xx_0</sink_block_id>
@ -946,12 +1373,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>blocks_float_to_complex_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection> <connection>
<source_block_id>blocks_float_to_complex_0</source_block_id> <source_block_id>blocks_float_to_complex_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0</sink_block_id> <sink_block_id>wxgui_fftsink2_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_float_to_complex_0</source_block_id>
<sink_block_id>wxgui_waterfallsink2_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection> <connection>
<source_block_id>ha5kfu_execproc_xx_0</source_block_id> <source_block_id>ha5kfu_execproc_xx_0</source_block_id>
<sink_block_id>blocks_deinterleave_0</sink_block_id> <sink_block_id>blocks_deinterleave_0</sink_block_id>
@ -982,4 +1421,22 @@
<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_0_1</source_block_id>
<sink_block_id>wxgui_fftsink2_0_1_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0_1</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>ha5kfu_execproc_xx_0_1</source_block_id>
<sink_block_id>wxgui_waterfallsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph> </flow_graph>

View file

@ -293,7 +293,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>True</value> <value>0</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
@ -336,7 +336,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>True</value> <value>0</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
@ -399,7 +399,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>True</value> <value>0</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
@ -446,7 +446,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>True</value> <value>0</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
@ -489,7 +489,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>True</value> <value>0</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
@ -575,6 +575,65 @@
<value>1</value> <value>1</value>
</param> </param>
</block> </block>
<block>
<key>blocks_vector_source_x</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>(32, 443)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_vector_source_x_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>repeat</key>
<value>True</value>
</param>
<param>
<key>tags</key>
<value>[]</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>vector</key>
<value>(1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1)</value>
</param>
</block>
<block> <block>
<key>digital_costas_loop_cc</key> <key>digital_costas_loop_cc</key>
<param> <param>
@ -650,7 +709,7 @@
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
<value>True</value> <value>1</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
@ -693,7 +752,7 @@
</param> </param>
<param> <param>
<key>commandline</key> <key>commandline</key>
<value>tee /s/costas_input | csdr bpsk_costas_loop_cc 0.1 0.707 --output_combined /s/costas_error /s/costas_dphase /s/costas_nco | tee /s/costas_output</value> <value>tee /s/costas_input | CSDR_FIXED_BUFSIZE=1 csdr bpsk_costas_loop_cc 0.1 0.707 --dd --output_combined /s/costas_error /s/costas_dphase /s/costas_nco | tee /s/costas_output</value>
</param> </param>
<param> <param>
<key>comment</key> <key>comment</key>
@ -948,6 +1007,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>blocks_vector_source_x_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> <connection>
<source_block_id>digital_costas_loop_cc_0</source_block_id> <source_block_id>digital_costas_loop_cc_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0_0_0</sink_block_id> <sink_block_id>wxgui_scopesink2_0_0_0</sink_block_id>

View file

@ -1894,7 +1894,7 @@ void pll_cc(pll_t* p, complexf* input, float* output_dphase, complexf* output_nc
} }
} }
void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error, int index, int correction_offset, int writefiles, int points_size, ...) void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error, int index, int correction_offset, char* writefiles_path, int points_size, ...)
{ {
static int figure_output_counter = 0; static int figure_output_counter = 0;
int* points_z = (int*)malloc(sizeof(int)*points_size); int* points_z = (int*)malloc(sizeof(int)*points_size);
@ -1906,7 +1906,7 @@ void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error
points_z[i] = va_arg(vl, int); points_z[i] = va_arg(vl, int);
points_color[i] = va_arg(vl, int); points_color[i] = va_arg(vl, int);
} }
if(writefiles && !figure_output_counter) fprintf(stderr, "cf=figure();\n"); if(writefiles_path && !figure_output_counter) fprintf(stderr, "cf=figure();\n");
fprintf(stderr, "N = %d;\nisig = [", signal_size); fprintf(stderr, "N = %d;\nisig = [", signal_size);
for(int i=0;i<signal_size;i++) fprintf(stderr, "%f ", iof(signal,i)); for(int i=0;i<signal_size;i++) fprintf(stderr, "%f ", iof(signal,i));
fprintf(stderr, "];\nqsig = ["); fprintf(stderr, "];\nqsig = [");
@ -1931,13 +1931,13 @@ void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error
(char)points_color[i]&0xff, (i<points_size-1)?',':' ' (char)points_color[i]&0xff, (i<points_size-1)?',':' '
); );
fprintf(stderr, ");\n"); fprintf(stderr, ");\n");
if(writefiles) fprintf(stderr, "print(cf, \"figs/%05d.png\", \"-S1024,1024\");\n", figure_output_counter++); if(writefiles_path) fprintf(stderr, "print(cf, \"%s/%05d.png\", \"-S1024,1024\");\n", writefiles_path, figure_output_counter++);
fflush(stderr); fflush(stderr);
free(points_z); free(points_z);
free(points_color); free(points_color);
} }
timing_recovery_state_t timing_recovery_init(timing_recovery_algorithm_t algorithm, int decimation_rate, int use_q, float loop_gain, float max_error) timing_recovery_state_t timing_recovery_init(timing_recovery_algorithm_t algorithm, int decimation_rate, int use_q, float loop_gain, float max_error, int debug_every_nth, char* debug_writefiles_path)
{ {
timing_recovery_state_t to_return; timing_recovery_state_t to_return;
to_return.algorithm = algorithm; to_return.algorithm = algorithm;
@ -1945,20 +1945,13 @@ timing_recovery_state_t timing_recovery_init(timing_recovery_algorithm_t algorit
to_return.loop_gain = loop_gain; to_return.loop_gain = loop_gain;
to_return.max_error = max_error; to_return.max_error = max_error;
to_return.use_q = use_q; to_return.use_q = use_q;
to_return.debug_phase = -1; to_return.debug_phase = to_return.debug_every_nth = debug_every_nth; //debug is effective if it is >=0
to_return.debug_count = 3;
to_return.debug_force = 0;
to_return.debug_writefiles = 0;
to_return.last_correction_offset = 0; to_return.last_correction_offset = 0;
to_return.earlylate_ratio = 0.25; //0..0.5 to_return.earlylate_ratio = 0.25; //0..0.5
to_return.debug_writefiles_path = debug_writefiles_path;
return to_return; return to_return;
} }
void timing_recovery_trigger_debug(timing_recovery_state_t* state, int debug_phase)
{
state->debug_phase=debug_phase;
}
#define MTIMINGR_HDEBUG 0 #define MTIMINGR_HDEBUG 0
void timing_recovery_cc(complexf* input, complexf* output, int input_size, float* timing_error, int* sampled_indexes, timing_recovery_state_t* state) void timing_recovery_cc(complexf* input, complexf* output, int input_size, float* timing_error, int* sampled_indexes, timing_recovery_state_t* state)
@ -1971,11 +1964,10 @@ void timing_recovery_cc(complexf* input, complexf* output, int input_size, float
int num_samples_halfbit = state->decimation_rate / 2; int num_samples_halfbit = state->decimation_rate / 2;
int num_samples_quarterbit = state->decimation_rate / 4; int num_samples_quarterbit = state->decimation_rate / 4;
int num_samples_earlylate_wing = num_samples_bit * state->earlylate_ratio; int num_samples_earlylate_wing = num_samples_bit * state->earlylate_ratio;
int debug_i = state->debug_count;
float error; float error;
int el_point_left_index, el_point_right_index, el_point_mid_index; int el_point_left_index, el_point_right_index, el_point_mid_index;
int si = 0; int si = 0;
if(state->debug_force) fprintf(stderr, "disp(\"begin timing_recovery_cc\");\n"); if(state->debug_every_nth>=0) fprintf(stderr, "disp(\"begin timing_recovery_cc\");\n");
if(MTIMINGR_HDEBUG) fprintf(stderr, "timing_recovery_cc started, nsb = %d, nshb = %d, nsqb = %d\n", num_samples_bit, num_samples_halfbit, num_samples_quarterbit); if(MTIMINGR_HDEBUG) fprintf(stderr, "timing_recovery_cc started, nsb = %d, nshb = %d, nsqb = %d\n", num_samples_bit, num_samples_halfbit, num_samples_quarterbit);
{ {
for(;;) for(;;)
@ -2026,20 +2018,23 @@ void timing_recovery_cc(complexf* input, complexf* output, int input_size, float
if(error>state->max_error) error=state->max_error; if(error>state->max_error) error=state->max_error;
if(error<-state->max_error) error=-state->max_error; if(error<-state->max_error) error=-state->max_error;
if( state->debug_force || (state->debug_phase >= si && debug_i) ) if(state->debug_every_nth>=0)
{ {
debug_i--; if(state->debug_every_nth==0 || state->debug_phase==0)
if(!debug_i) state->debug_phase = -1; {
octave_plot_point_on_cplxsig(input+current_bitstart_index, state->decimation_rate*2, state->debug_phase = state->debug_every_nth;
error, octave_plot_point_on_cplxsig(input+current_bitstart_index, state->decimation_rate*2,
current_bitstart_index, error,
correction_offset, current_bitstart_index,
state->debug_writefiles, correction_offset,
3, state->debug_writefiles_path,
el_point_left_index - current_bitstart_index, 'r', 3,
el_point_right_index - current_bitstart_index, 'r', el_point_left_index - current_bitstart_index, 'r',
el_point_mid_index - current_bitstart_index, 'r', el_point_right_index - current_bitstart_index, 'r',
0); el_point_mid_index - current_bitstart_index, 'r',
0);
}
else state->debug_phase--;
} }
int error_sign = (state->algorithm == TIMING_RECOVERY_ALGORITHM_GARDNER) ? -1 : 1; int error_sign = (state->algorithm == TIMING_RECOVERY_ALGORITHM_GARDNER) ? -1 : 1;
correction_offset = num_samples_halfbit * error_sign * error * state->loop_gain; correction_offset = num_samples_halfbit * error_sign * error * state->loop_gain;
@ -2085,6 +2080,7 @@ void init_bpsk_costas_loop_cc(bpsk_costas_loop_state_t* s, int decision_directed
s->alpha = (4*damping_factor*bandwidth_omega)/denomiator; s->alpha = (4*damping_factor*bandwidth_omega)/denomiator;
s->beta = (4*bandwidth_omega*bandwidth_omega)/denomiator; s->beta = (4*bandwidth_omega*bandwidth_omega)/denomiator;
s->iir_temp = s->dphase = s->nco_phase = 0; s->iir_temp = s->dphase = s->nco_phase = 0;
s->dphase_max=0.9*PI; //if it reached PI or -PI then it might actually hang and not come back
} }
void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, float* output_error, float* output_dphase, complexf* output_nco, bpsk_costas_loop_state_t* s) void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, float* output_error, float* output_dphase, complexf* output_nco, bpsk_costas_loop_state_t* s)
@ -2111,8 +2107,8 @@ void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, floa
if(output_error) output_error[i]=error; if(output_error) output_error[i]=error;
s->dphase = error * s->alpha + s->iir_temp; s->dphase = error * s->alpha + s->iir_temp;
s->iir_temp += error * s->beta; //iir_temp could be named current_freq. See Tom Rondeau's article for better understanding. s->iir_temp += error * s->beta; //iir_temp could be named current_freq. See Tom Rondeau's article for better understanding.
if(s->dphase>PI) s->dphase=PI; if(s->dphase>s->dphase_max) s->dphase=s->dphase_max;
if(s->dphase<-PI) s->dphase=-PI; if(s->dphase<-s->dphase_max) s->dphase=-s->dphase_max;
if(output_dphase) output_dphase[i]=s->dphase; if(output_dphase) output_dphase[i]=s->dphase;
//fprintf(stderr, " error = %f; dphase = %f; nco_phase = %f;\n", error, s->dphase, s->nco_phase); //fprintf(stderr, " error = %f; dphase = %f; nco_phase = %f;\n", error, s->dphase, s->nco_phase);

View file

@ -327,21 +327,19 @@ typedef struct timing_recovery_state_s
int input_processed; int input_processed;
int use_q; //use both I and Q for calculating the error int use_q; //use both I and Q for calculating the error
int debug_phase; int debug_phase;
int debug_count; int debug_every_nth;
int debug_force; char* debug_writefiles_path;
int debug_writefiles;
int last_correction_offset; int last_correction_offset;
float earlylate_ratio; float earlylate_ratio;
float loop_gain; float loop_gain;
float max_error; float max_error;
} timing_recovery_state_t; } timing_recovery_state_t;
timing_recovery_state_t timing_recovery_init(timing_recovery_algorithm_t algorithm, int decimation_rate, int use_q, float loop_gain, float max_error); timing_recovery_state_t timing_recovery_init(timing_recovery_algorithm_t algorithm, int decimation_rate, int use_q, float loop_gain, float max_error, int debug_every_nth, char* debug_writefiles_path);
void timing_recovery_cc(complexf* input, complexf* output, int input_size, float* timing_error, int* sampled_indexes, timing_recovery_state_t* state); void timing_recovery_cc(complexf* input, complexf* output, int input_size, float* timing_error, int* sampled_indexes, timing_recovery_state_t* state);
timing_recovery_algorithm_t timing_recovery_get_algorithm_from_string(char* input); timing_recovery_algorithm_t timing_recovery_get_algorithm_from_string(char* input);
char* timing_recovery_get_string_from_algorithm(timing_recovery_algorithm_t algorithm); char* timing_recovery_get_string_from_algorithm(timing_recovery_algorithm_t algorithm);
void timing_recovery_trigger_debug(timing_recovery_state_t* state, int debug_phase); void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error, int index, int correction_offset, char* writefiles_path, int points_size, ...);
void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error, int index, int correction_offset, int writefiles, int points_size, ...);
void psk_modulator_u8_c(unsigned char* input, complexf* output, int input_size, int n_psk); void psk_modulator_u8_c(unsigned char* input, complexf* output, int input_size, int n_psk);
void duplicate_samples_ntimes_u8_u8(unsigned char* input, unsigned char* output, int input_size_bytes, int sample_size_bytes, int ntimes); void duplicate_samples_ntimes_u8_u8(unsigned char* input, unsigned char* output, int input_size_bytes, int sample_size_bytes, int ntimes);
complexf psk31_interpolate_sine_cc(complexf* input, complexf* output, int input_size, int interpolation, complexf last_input); complexf psk31_interpolate_sine_cc(complexf* input, complexf* output, int input_size, int interpolation, complexf last_input);
@ -372,6 +370,7 @@ typedef struct bpsk_costas_loop_state_s
float iir_temp; float iir_temp;
float dphase; float dphase;
float nco_phase; float nco_phase;
float dphase_max;
} bpsk_costas_loop_state_t; } bpsk_costas_loop_state_t;
void plain_interpolate_cc(complexf* input, complexf* output, int input_size, int interpolation); void plain_interpolate_cc(complexf* input, complexf* output, int input_size, int interpolation);