From 80ee1645eccd97915a5352d84b2a9aa490af4690 Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Sat, 29 Apr 2017 18:10:53 +0200 Subject: [PATCH] Added normalized_timing_variance_u32_f, ??, etc. --- README.md | 36 ++++++++++++++++++++++++++ csdr.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++------ libcsdr.c | 28 +++++++++++++++++++- libcsdr.h | 3 ++- 4 files changed, 133 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 6da9ce1..55349ef 100755 --- a/README.md +++ b/README.md @@ -855,6 +855,32 @@ It outputs white noise within the range [-1.0, 1.0]. ---- +### [pack_bits_8to1_u8_u8](#pack_bits_8to1_u8_u8) + +Syntax: + + csdr pack_bits_8to1_u8_u8 + +It serializes the bytes on the input: it outputs each bit of the input byte as a single byte valued 0x00 or 0x01, starting from the lowest bit and going to the highest bit. + +The output is 8 times as large in size as the input. + +For example, the input byte 0x43 will result in eight bytes at the output: + +``` +01 01 00 00 00 00 01 00 +``` + +For consequtive 0x02, 0x03, 0xff bytes on the input, the output will be: + +``` +00 01 00 00 00 00 00 00 +01 01 00 00 00 00 00 00 +01 01 01 01 01 01 01 01 +``` + +---- + ### [awgn_cc](#awgn_cc) Syntax: @@ -867,6 +893,16 @@ If the `--snrshow` switch is given, it also shows the actual SNR based on the ca ---- +### [add_n_zero_samples_at_beginning_f](#add_n_zero_samples_at_beginning_f) + +Syntax: + + csdr add_n_zero_samples_at_beginning_f + +When the function is executed, it furst writes `` 32-bit floating point zeros at the output, after that it just clones the input at the output. + +---- + ### [?](#search_the_function_list) Syntax: diff --git a/csdr.c b/csdr.c index 98e3604..069a6db 100755 --- a/csdr.c +++ b/csdr.c @@ -75,7 +75,6 @@ char usage[]= " yes_f [buf_times]\n" " detect_nan_ff\n" " dump_f\n" -" flowcontrol [prebuffer_sec] [thrust]\n" " shift_math_cc \n" " shift_math_cc --fifo \n" " shift_addition_cc \n" @@ -125,7 +124,7 @@ char usage[]= " rtty_baudot2ascii_u8_u8\n" " serial_line_decoder_u8_u8\n" " octave_complex_c \n" -" timing_recovery_cc [--add_q] [--octave ]\n" +" timing_recovery_cc [--add_q [--output_error | --output_indexes | --octave ]] \n" " psk31_varicode_encoder_u8_u8\n" " psk31_varicode_decoder_u8_u8\n" " differential_encoder_u8_u8\n" @@ -142,6 +141,8 @@ char usage[]= " repeat_u8 \n" " noise_f\n" " awgn_cc [--snrshow]\n" +" pack_bits_8to1_u8_u8\n" +" add_n_zero_samples_at_beginning_f \n" " ?\n" " =\n" " \n" @@ -2519,7 +2520,7 @@ int main(int argc, char *argv[]) } } - if(!strcmp(argv[1],"timing_recovery_cc")) // [--add_q [--output_error | --octave ]] + if(!strcmp(argv[1],"timing_recovery_cc")) // [--add_q [--output_error | --output_indexes | --octave ]] { if(argc<=2) return badsyntax("need required parameter (algorithm)"); timing_recovery_algorithm_t algorithm = timing_recovery_get_algorithm_from_string(argv[2]); @@ -2534,12 +2535,18 @@ int main(int argc, char *argv[]) int debug_n = 0; int output_error = 0; + int output_indexes = 0; if(argc>=7 && !strcmp(argv[5], "--octave")) debug_n = atoi(argv[6]); if(debug_n<0) badsyntax("debug_n should be >= 0"); - if(argc>=6 && !strcmp(argv[5], "--output_error")) output_error = 1; + + if(argc>=6 && !strcmp(argv[5], "--output_error")) output_error = 1; float* timing_error = NULL; if(output_error) timing_error = (float*)malloc(sizeof(float)*the_bufsize); + if(argc>=6 && !strcmp(argv[5], "--output_indexes")) output_indexes = 1; + unsigned* sampled_indexes = NULL; + if(output_indexes) sampled_indexes = (unsigned*)malloc(sizeof(float)*the_bufsize); + if(!initialize_buffers()) return -2; sendbufsize(the_bufsize/decimation); @@ -2549,16 +2556,23 @@ int main(int argc, char *argv[]) state.debug_writefiles = 1; state.debug_force = !!debug_n; //should remove that later FREAD_C; + unsigned buffer_start_counter = 0; for(;;) { 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, &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); if(timing_error) fwrite(timing_error, sizeof(float), state.output_size, stdout); + else if(sampled_indexes) + { + for(int i=0;i + { + int samples_per_symbol = 0; + if(argc<=2) badsyntax("required parameter is missing."); + sscanf(argv[2],"%d",&samples_per_symbol); + + int initial_sample_offset = 0; + if(argc<=3) badsyntax("required parameter is missing."); + sscanf(argv[3],"%d",&initial_sample_offset); + + if(!initialize_buffers()) return -2; + sendbufsize(the_bufsize); + float* temp_buffer = (float*)malloc(sizeof(float)*the_bufsize); + for(;;) + { + FEOF_CHECK; + FREAD_R; //doesn't count, reads 4 bytes per sample anyway + float nv = normalized_timing_variance_u32_f((unsigned*)input_buffer, temp_buffer, the_bufsize, samples_per_symbol, initial_sample_offset); + fwrite(&nv, sizeof(float), 1, stdout); + fprintf(stderr, "csdr normalized_timing_variance_u32_f: normalized variance = %f\n", nv); + FWRITE_R; + TRY_YIELD; + } + } + + if(!strcmp(argv[1], "add_n_zero_samples_at_beginning_f")) // + { + int n_zero_samples = 0; + if(argc<=2) badsyntax("required parameter is missing."); + sscanf(argv[2],"%d",&n_zero_samples); + if(!sendbufsize(initialize_buffers())) return -2; + float* zeros=(float*)calloc(sizeof(float),n_zero_samples); + fwrite(zeros, sizeof(float), n_zero_samples, stdout); + clone_(the_bufsize); + } + + if(!strcmp(argv[1],"none")) { return 0; } + if(argv[1][0]=='?' && argv[1][1]=='?') + { + char buffer[1000]; + snprintf(buffer, 1000-1, "xdg-open https://github.com/simonyiszk/csdr/blob/master/README.md#$(csdr ?%s | head -n1 | awk '{print $1;}')", argv[1]+2); + fprintf(stderr, "csdr ??: %s\n", buffer); + system(buffer); + return 0; + } + if(argv[1][0]=='?') { - char buffer[100]; - snprintf(buffer, 100-1, "csdr 2>&1 | grep %s", argv[1]+1); + char buffer[1000]; + snprintf(buffer, 1000-1, "csdr 2>&1 | grep %s", argv[1]+1); fprintf(stderr, "csdr ?: %s\n", buffer); system(buffer); return 0; diff --git a/libcsdr.c b/libcsdr.c index 304870c..5503e37 100755 --- a/libcsdr.c +++ b/libcsdr.c @@ -1925,7 +1925,7 @@ void timing_recovery_trigger_debug(timing_recovery_state_t* state, int debug_pha #define MTIMINGR_HDEBUG 0 -void timing_recovery_cc(complexf* input, complexf* output, int input_size, float* timing_error, 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) { //We always assume that the input starts at center of the first symbol cross before the first symbol. //Last time we consumed that much from the input samples that it is there. @@ -1963,6 +1963,7 @@ void timing_recovery_cc(complexf* input, complexf* output, int input_size, float el_point_right_index = current_bitstart_index + num_samples_earlylate_wing * 3; el_point_left_index = current_bitstart_index + num_samples_earlylate_wing * 1 - correction_offset; el_point_mid_index = current_bitstart_index + num_samples_halfbit; + if(sampled_indexes) sampled_indexes[si]=el_point_mid_index; output[si++] = input[el_point_mid_index]; } else if(state->algorithm == TIMING_RECOVERY_ALGORITHM_GARDNER) @@ -1971,6 +1972,7 @@ void timing_recovery_cc(complexf* input, complexf* output, int input_size, float el_point_right_index = current_bitstart_index + num_samples_halfbit * 3; el_point_left_index = current_bitstart_index + num_samples_halfbit * 1; el_point_mid_index = current_bitstart_index + num_samples_halfbit * 2; + if(sampled_indexes) sampled_indexes[si]=el_point_left_index; output[si++] = input[el_point_left_index]; } else break; @@ -2167,7 +2169,31 @@ int apply_fir_cc(complexf* input, complexf* output, int input_size, complexf* ta return i; } +float normalized_timing_variance_u32_f(unsigned* input, float* temp, int input_size, int samples_per_symbol, int initial_sample_offset) +{ + float *ndiff_rad = temp; + float ndiff_rad_mean = 0; + for(int i=0;isamples_per_symbol/2) sinearest++; + unsigned sicorrect = initial_sample_offset+(sinearest*samples_per_symbol); //the sample offset which input[i] should have been, in order to sample at the maximum effect point + int sidiff = abs(sicorrect-input[i]); + float ndiff = sidiff/samples_per_symbol; + fprintf(stderr, "ndiff = %f\n", ndiff); + ndiff_rad[i] = ndiff*PI; + ndiff_rad_mean = ndiff_rad_mean*(((float)i-1)/i)+(ndiff_rad[i]/i); + } + fprintf(stderr, "ndiff_rad_mean = %f\n", ndiff_rad_mean); + + float result = 0; + for(int i=0;i