From 44c539c1af8238ad5ccb867fce4ea8f088cbbe67 Mon Sep 17 00:00:00 2001 From: "David.O" Date: Wed, 9 Jun 2021 18:18:58 +0100 Subject: [PATCH 1/3] add binary_decoder_f_u8 and binary_to_ascii_u8_u8 to support basic binary data decoding --- README.md | 25 +++++++++++++++++++++++ csdr.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ libcsdr.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ libcsdr.h | 9 ++++++++ 4 files changed, 145 insertions(+) diff --git a/README.md b/README.md index cbc77214..b76d4ae6 100755 --- a/README.md +++ b/README.md @@ -1040,6 +1040,31 @@ Syntax: ---- +### [binary_decoder_f_u8](#binary_decoder_f_u8) + +Syntax: + + csdr binary_decoder_f_u8 [min_samples_per_symbol] + +It tries to find symbol boundaries then has an algorithm for deciding whether each symbol is a 1 or a 0 the result of which it then outputs. +For this to function, a data preamble of either 5's or A's is helpful. + +If a symbol boundary occurs before samples_per_symbol samples have been processed since the last symbol boundary, what has been processed so far is output as a valid symbol only if at least min_samples_per_symbol have been processed (otherwise it is discarded). +min_samples_per_symbol defaults to 3/4 of samples_per_symbol. + +---- + +### [binary_to_ascii_u8_u8](#binary_to_ascii_u8_u8) + +Syntax: + + csdr binary_to_ascii_u8_u8 + +* If the input sample is 0, it outputs '0' (0x30). +* If the input sample is not 0, it outputs '1' (0x31). + +---- + ### [serial_line_decoder_f_u8](#serial_line_decoder_f_u8) Syntax: diff --git a/csdr.c b/csdr.c index 27dbf6dc..dab79c03 100755 --- a/csdr.c +++ b/csdr.c @@ -138,6 +138,8 @@ char usage[]= " duplicate_samples_ntimes_u8_u8 \n" " bpsk_costas_loop_cc [--dd | --decision_directed] [--output_error | --output_dphase | --output_nco | --output_combined ]\n" " binary_slicer_f_u8\n" +" binary_decoder_f_u8 [min_samples_per_symbol]\n" +" binary_to_ascii_u8_u8\n" " simple_agc_cc [reference [max_gain]]\n" " firdes_peak_c [window [--octave]]\n" " peaks_fir_cc [peak_rate × N]\n" @@ -2487,6 +2489,54 @@ int main(int argc, char *argv[]) return 0; } + if(!strcmp(argv[1],"binary_decoder_f_u8")) + { + int samples_per_symbol; + int min_samples_per_symbol; + int output_size; + + if(argc<=2) return badsyntax("need required parameter (samples_per_symbol)"); + sscanf(argv[2],"%d",&samples_per_symbol); + + if(argc>3) + { + sscanf(argv[3],"%d",&min_samples_per_symbol); + } + else + { + min_samples_per_symbol = (samples_per_symbol*3)/4; + } + + if(!sendbufsize(initialize_buffers())) return -2; + for(;;) + { + FEOF_CHECK; + if(!FREAD_R) break; + output_size = binary_decoder_f_u8( input_buffer, + (unsigned char*)output_buffer, + the_bufsize, + samples_per_symbol, + min_samples_per_symbol); + fwrite(output_buffer, sizeof(unsigned char), output_size, stdout); + TRY_YIELD; + } + return 0; + } + + if(!strcmp(argv[1],"binary_to_ascii_u8_u8")) + { + if(!sendbufsize(initialize_buffers())) return -2; + for(;;) + { + FEOF_CHECK; + if(!FREAD_U8) break; + binary_to_ascii_u8_u8((unsigned char*)input_buffer, (unsigned char*)output_buffer, the_bufsize); + FWRITE_U8; + TRY_YIELD; + } + return 0; + } + if(!strcmp(argv[1],"serial_line_decoder_f_u8")) // [databits [stopbits]] { bigbufs=1; diff --git a/libcsdr.c b/libcsdr.c index 9751bba4..2163007f 100755 --- a/libcsdr.c +++ b/libcsdr.c @@ -1769,6 +1769,67 @@ void binary_slicer_f_u8(float* input, unsigned char* output, int input_size) for(int i=0;i 0; } +int binary_decoder_f_u8(float* input, + unsigned char* output, + int input_size, + int samples_per_symbol, + int min_samples_per_symbol) +{ + static float previous_sample; + static float sample_accumulator; + static int sample_offset; + + int i; + int output_size = 0; + float sample; + + //notice rising edges crossing zero and assume they coincide with a symbol boundary. + //add all samples within a symbol and base the output on whether this accumulation is overall positive or negative. + + for(i=0;i= 0)) + { + //if we've almost got a symbol, accept it and publish early. + if(sample_offset >= min_samples_per_symbol) + { + output[output_size] = (sample_accumulator > 0); + output_size++; + //fprintf(stderr, "symbol (%d:%f:%d)\n", sample_offset, sample_accumulator, output[output_size]); + } + + sample_accumulator = 0; + sample_offset = 0; + } + + sample_accumulator += sample; + sample_offset++; + if(sample_offset == samples_per_symbol) + { + output[output_size] = (sample_accumulator > 0); + output_size++; + //fprintf(stderr, "symbol (%d:%f:%d)\n", sample_offset, sample_accumulator, output[output_size]); + + sample_accumulator = 0; + sample_offset = 0; + } + + previous_sample = input[i]; + } + + return(output_size); +} + +void binary_to_ascii_u8_u8(unsigned char* input, + unsigned char* output, + int input_size) +{ + for(int i=0;i Date: Wed, 9 Jun 2021 21:49:53 +0100 Subject: [PATCH 2/3] adjust changes to match pre-existing white space convention --- csdr.c | 36 ++++++++--------- libcsdr.c | 114 +++++++++++++++++++++++++++--------------------------- libcsdr.h | 12 +++--- 3 files changed, 81 insertions(+), 81 deletions(-) diff --git a/csdr.c b/csdr.c index dab79c03..fe5c026d 100755 --- a/csdr.c +++ b/csdr.c @@ -2491,32 +2491,32 @@ int main(int argc, char *argv[]) if(!strcmp(argv[1],"binary_decoder_f_u8")) { - int samples_per_symbol; - int min_samples_per_symbol; - int output_size; + int samples_per_symbol; + int min_samples_per_symbol; + int output_size; - if(argc<=2) return badsyntax("need required parameter (samples_per_symbol)"); + if(argc<=2) return badsyntax("need required parameter (samples_per_symbol)"); sscanf(argv[2],"%d",&samples_per_symbol); - if(argc>3) - { - sscanf(argv[3],"%d",&min_samples_per_symbol); - } - else - { - min_samples_per_symbol = (samples_per_symbol*3)/4; - } + if(argc>3) + { + sscanf(argv[3],"%d",&min_samples_per_symbol); + } + else + { + min_samples_per_symbol = (samples_per_symbol*3)/4; + } - if(!sendbufsize(initialize_buffers())) return -2; + if(!sendbufsize(initialize_buffers())) return -2; for(;;) { - FEOF_CHECK; + FEOF_CHECK; if(!FREAD_R) break; output_size = binary_decoder_f_u8( input_buffer, - (unsigned char*)output_buffer, - the_bufsize, - samples_per_symbol, - min_samples_per_symbol); + (unsigned char*)output_buffer, + the_bufsize, + samples_per_symbol, + min_samples_per_symbol); fwrite(output_buffer, sizeof(unsigned char), output_size, stdout); TRY_YIELD; } diff --git a/libcsdr.c b/libcsdr.c index 2163007f..063db994 100755 --- a/libcsdr.c +++ b/libcsdr.c @@ -1277,10 +1277,10 @@ void apply_precalculated_window_c(complexf* input, complexf* output, int size, f void apply_precalculated_window_f(float* input, float* output, int size, float *windowt) { - for(int i=0;i= 0)) - { - //if we've almost got a symbol, accept it and publish early. - if(sample_offset >= min_samples_per_symbol) - { - output[output_size] = (sample_accumulator > 0); - output_size++; - //fprintf(stderr, "symbol (%d:%f:%d)\n", sample_offset, sample_accumulator, output[output_size]); - } - - sample_accumulator = 0; - sample_offset = 0; - } - - sample_accumulator += sample; - sample_offset++; - if(sample_offset == samples_per_symbol) - { - output[output_size] = (sample_accumulator > 0); - output_size++; - //fprintf(stderr, "symbol (%d:%f:%d)\n", sample_offset, sample_accumulator, output[output_size]); - - sample_accumulator = 0; - sample_offset = 0; - } - - previous_sample = input[i]; - } - - return(output_size); + unsigned char* output, + int input_size, + int samples_per_symbol, + int min_samples_per_symbol) +{ + static float previous_sample; + static float sample_accumulator; + static int sample_offset; + + int i; + int output_size = 0; + float sample; + + //notice rising edges crossing zero and assume they coincide with a symbol boundary. + //add all samples within a symbol and base the output on whether this accumulation is overall positive or negative. + + for(i=0;i= 0)) + { + //if we've almost got a symbol, accept it and publish early. + if(sample_offset >= min_samples_per_symbol) + { + output[output_size] = (sample_accumulator > 0); + output_size++; + //fprintf(stderr, "symbol (%d:%f:%d)\n", sample_offset, sample_accumulator, output[output_size]); + } + + sample_accumulator = 0; + sample_offset = 0; + } + + sample_accumulator += sample; + sample_offset++; + if(sample_offset == samples_per_symbol) + { + output[output_size] = (sample_accumulator > 0); + output_size++; + //fprintf(stderr, "symbol (%d:%f:%d)\n", sample_offset, sample_accumulator, output[output_size]); + + sample_accumulator = 0; + sample_offset = 0; + } + + previous_sample = input[i]; + } + + return(output_size); } void binary_to_ascii_u8_u8(unsigned char* input, - unsigned char* output, - int input_size) + unsigned char* output, + int input_size) { for(int i=0;i Date: Wed, 14 Jul 2021 13:49:01 +0000 Subject: [PATCH 3/3] now compiles on an arm64 Raspberry Pi 4 --- Makefile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 4db95f1d..e86c7480 100644 --- a/Makefile +++ b/Makefile @@ -29,11 +29,17 @@ LIBSOURCES = fft_fftw.c libcsdr_wrapper.c #SOURCES = csdr.c $(LIBSOURCES) cpufeature = $(if $(findstring $(1),$(shell cat /proc/cpuinfo)),$(2)) +kcmdfeature = $(if $(findstring $(1),$(shell cat /proc/cmdline)),$(2)) +dpkghostarch = $(if $(findstring $(1),$(shell dpkg --print-architecture)),$(2)) PARAMS_SSE = $(call cpufeature,sse,-msse) $(call cpufeature,sse2,-msse2) $(call cpufeature,sse3,-msse3) $(call cpufeature,sse4a,-msse4a) $(call cpufeature,sse4_1,-msse4.1) $(call cpufeature,sse4_2,-msse4.2 -msse4) -mfpmath=sse PARAMS_NEON = -mfloat-abi=hard -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mvectorize-with-neon-quad -funsafe-math-optimizations -Wformat=0 -DNEON_OPTS #tnx Jan Szumiec for the Raspberry Pi support -PARAMS_RASPI = -mfloat-abi=hard -mcpu=arm1176jzf-s -mfpu=vfp -funsafe-math-optimizations -Wformat=0 -PARAMS_ARM = $(if $(call cpufeature,BCM2708,dummy-text),$(PARAMS_RASPI),$(PARAMS_NEON)) +PARAMS_RASPI_3 = -mfloat-abi=hard -mcpu=arm1176jzf-s -mfpu=vfp -funsafe-math-optimizations -Wformat=0 +PARAMS_RASPI_4_ARMHF = -mcpu=cortex-a72 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mneon-for-64bits -mtune=cortex-a72 -funsafe-math-optimizations -Wformat=0 +PARAMS_RASPI_4_ARM64 = -mcpu=cortex-a72 -mtune=cortex-a72 -funsafe-math-optimizations -Wformat=0 +PARAMS_RASPI_4 = $(if $(call dpkghostarch,arm64,dummy-text),$(PARAMS_RASPI_4_ARM64),$(PARAMS_RASPI_4_ARMHF)) +PARAMS_RASPI = $(if $(call kcmdfeature,bcm2709,dummy-text),$(PARAMS_RASPI_4),$(PARAMS_RASPI_3)) +PARAMS_ARM = $(if $(call kcmdfeature,bcm270,dummy-text),$(PARAMS_RASPI),$(PARAMS_NEON)) PARAMS_SIMD = $(if $(call cpufeature,sse,dummy-text),$(PARAMS_SSE),$(PARAMS_ARM)) PARAMS_LOOPVECT = -O3 -ffast-math -fdump-tree-vect-details -dumpbase dumpvect PARAMS_LIBS = -g -lm -lrt -lfftw3f -DUSE_FFTW -DLIBCSDR_GPL -DUSE_IMA_ADPCM