From d3a7c6e12ba9d6b65c40d5868c73198d25a4985d Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Mon, 27 Mar 2017 13:44:01 +0200 Subject: [PATCH] Working PSK31 generator --- README.md | 34 ++++++++++++++++++++++++++++++++-- csdr.c | 41 +++++++++++++++++++++++++++++++++++++---- libcsdr.c | 43 +++++++++++++++++++++++++++++++++---------- libcsdr.h | 1 + 4 files changed, 103 insertions(+), 16 deletions(-) mode change 100644 => 100755 csdr.c diff --git a/README.md b/README.md index e0f2ddc..9215045 100644 --- a/README.md +++ b/README.md @@ -185,20 +185,34 @@ Else, after outputing `buf_times` number of buffers (the size of which is stated Along with copying its input samples to the output, it prints a warning message to *stderr* if it finds any IEEE floating point NaN values among the samples. - floatdump_f + dump_f + +It prints all floating point input samples as text. -It prints any floating point input samples. The format string used is `"%g "`. +You can also use it to print complex float values, then you will see the I and Q samples interleaved, like: `I Q I Q I Q ...` + +Alternatively, you can use the `od` command (built into most Linux distributions). To display a list of floating point values with their addresses as well, you can use: `od -vf` + + dump_u8 + +It prints all input bytes as text, in hexadecimal form. + +Alternatively, you can use the `xxd` command (built into most Linux distributions). To display a hexadecimal dump of the standard input (with addresses at the beginning of rows), you can use: `xxd -g1` + flowcontrol It limits the data rate of a stream to a given `data_rate` number of bytes per second. + It copies `data_rate / reads_per_second` bytes from the input to the output, doing it `reads_per_second` times every second. shift_math_cc It shifts the signal in the frequency domain by `rate`. + `rate` is a floating point number between -0.5 and 0.5. + `rate` is relative to the sampling rate. Internally, a sine and cosine wave is generated to perform this function, and this function uses `math.h` for this purpose, which is quite accurate, but not always very fast. @@ -417,6 +431,22 @@ This is a controllable squelch, which reads the squelch level input from ` [buf_times]\n" " detect_nan_ff\n" -" floatdump_f\n" +" dump_f\n" " flowcontrol [prebuffer_sec] [thrust]\n" " shift_math_cc \n" " shift_math_cc --fifo \n" @@ -124,6 +124,14 @@ char usage[]= " serial_line_decoder_sy_u8\n" " octave_complex_c \n" " timing_recovery_cc [--add_q]\n" +" psk31_varicode_encoder_u8_u8\n" +" differential_encoder_u8_u8\n" +" differential_decoder_u8_u8\n" +" dump_u8\n" +" psk_modulator_u8_c \n" +" psk31_interpolate_sine_cc\n" +" duplicate_samples_ntimes_u8_u8 \n" +" ?\n" " \n" ; @@ -2405,6 +2413,8 @@ int main(int argc, char *argv[]) int out_of_n_samples = 0; sscanf(argv[3], "%d", &out_of_n_samples); if(out_of_n_samples4) mode2d = !strcmp(argv[4], "--2d"); complexf* read_buf = (complexf*)malloc(sizeof(complexf)*the_bufsize); if(!sendbufsize(initialize_buffers())) return -2; @@ -2415,7 +2425,9 @@ int main(int argc, char *argv[]) for(int i=0;i { - int sample_size_bytes, ntimes; + int sample_size_bytes = 0, ntimes = 0; if(argc<=2) return badsyntax("need required parameter (sample_size_bytes)"); sscanf(argv[2],"%d",&sample_size_bytes); + if(sample_size_bytes<=0) badsyntax("sample_size_bytes should be >0"); if(argc<=3) return badsyntax("need required parameter (ntimes)"); sscanf(argv[3],"%d",&ntimes); + if(ntimes<=0) badsyntax("ntimes should be >0"); if(!initialize_buffers()) return -2; sendbufsize(the_bufsize*ntimes); unsigned char* local_input_buffer = (unsigned char*)malloc(sizeof(unsigned char)*the_bufsize*sample_size_bytes); @@ -2463,7 +2477,7 @@ int main(int argc, char *argv[]) { FEOF_CHECK; fread((void*)local_input_buffer, sizeof(unsigned char), the_bufsize*sample_size_bytes, stdin); - duplicate_samples_ntimes_u8_u8(local_input_buffer, local_input_buffer, the_bufsize*sample_size_bytes, sample_size_bytes, ntimes); + duplicate_samples_ntimes_u8_u8(local_input_buffer, local_output_buffer, the_bufsize*sample_size_bytes, sample_size_bytes, ntimes); fwrite((void*)local_output_buffer, sizeof(unsigned char), the_bufsize*sample_size_bytes*ntimes, stdout); TRY_YIELD; } @@ -2520,6 +2534,7 @@ int main(int argc, char *argv[]) for(;;) { psk31_varicode_encoder_u8_u8(local_input_buffer, local_output_buffer, the_bufsize, output_max_size, &input_processed, &output_size); + //fprintf(stderr, "os = %d\n", output_size); fwrite((void*)local_output_buffer, sizeof(unsigned char), output_size, stdout); FEOF_CHECK; memmove(local_input_buffer, local_input_buffer+input_processed, the_bufsize-input_processed); @@ -2542,6 +2557,24 @@ int main(int argc, char *argv[]) } } + int differential_codec_encode = 0; + if( (differential_codec_encode = !strcmp(argv[1],"differential_encoder_u8_u8")) || (!strcmp(argv[1],"differential_decoder_u8_u8")) ) + { + if(!initialize_buffers()) return -2; + sendbufsize(the_bufsize); + unsigned char* local_input_buffer = (unsigned char*)malloc(sizeof(unsigned char)*the_bufsize); + unsigned char* local_output_buffer = (unsigned char*)malloc(sizeof(unsigned char)*the_bufsize); + unsigned char state = 0; + for(;;) + { + FEOF_CHECK; + fread((void*)local_input_buffer, sizeof(unsigned char), the_bufsize, stdin); + state = differential_codec(local_input_buffer, local_output_buffer, the_bufsize, differential_codec_encode, state); + fwrite((void*)local_output_buffer, sizeof(unsigned char), the_bufsize, stdout); + TRY_YIELD; + } + } + if(!strcmp(argv[1],"none")) { return 0; diff --git a/libcsdr.c b/libcsdr.c index b3e5e50..50e808b 100644 --- a/libcsdr.c +++ b/libcsdr.c @@ -1415,19 +1415,22 @@ char psk31_varicode_decoder_push(unsigned long long* status_shr, unsigned char s void psk31_varicode_encoder_u8_u8(unsigned char* input, unsigned char* output, int input_size, int output_max_size, int* input_processed, int* output_size) { - *output_size=0; - for(*input_processed=0; *input_processed>(current_varicode.bitcount-bi-1))&1; - *output_size++; + //fprintf(stderr, "bi = %d\n", bi); + output[*output_size] = (bi>(current_varicode.bitcount-bi-1))&1 : 0; + (*output_size)++; output_max_size--; } break; @@ -1598,9 +1601,10 @@ void binary_slicer_f_u8(float* input, unsigned char* output, int input_size) void psk_modulator_u8_c(unsigned char* input, complexf* output, int input_size, int n_psk) { //outputs one complex sample per input symbol + float phase_increment = (2*M_PI)/n_psk; for(int i=0;i>bi)&1; } +unsigned char differential_codec(unsigned char* input, unsigned char* output, int input_size, int encode, unsigned char state) +{ + if(!encode) + for(int i=0;i