Added BPSK31 S-curve generator script, added repeat_u8 and error output fortiming_recovery_cc

This commit is contained in:
ha7ilm 2017-04-28 14:20:14 +02:00
parent 22bd8baa15
commit d391ea2ef6
6 changed files with 81 additions and 5 deletions

View file

@ -828,6 +828,23 @@ For this input, the output of `psk31_varicode_encoder_u8_u8` will be the followi
----
### [repeat_u8](#repeat_u8)
Syntax:
repeat_u8 <taps_length> [resonator_rate × N]\n"
It repeatedly outputs a set of data bytes (given with decimal numbers).
For example, `csdr repeat_u8 1 1 0 0` will output:
```
01 01 00 00 01 01 00 00
01 01 00 00 01 01 00 00
```
----
### [?](#search_the_function_list)
Syntax:

25
csdr.c
View file

@ -139,6 +139,7 @@ char usage[]=
" simple_agc_cc <rate> [reference [max_gain]]\n"
" firdes_resonator_c <rate> <length> [window [--octave]]\n"
" resonators_fir_cc <taps_length> [resonator_rate × N]\n"
" repeat_u8 <data_bytes × N>\n"
" ?<search_the_function_list>\n"
" =<evaluate_python_expression>\n"
" \n"
@ -2516,7 +2517,7 @@ int main(int argc, char *argv[])
}
}
if(!strcmp(argv[1],"timing_recovery_cc")) //<algorithm> <decimation> [--add_q [--octave <debug_n>]]
if(!strcmp(argv[1],"timing_recovery_cc")) //<algorithm> <decimation> [--add_q [--output_error | --octave <debug_n>]]
{
if(argc<=2) return badsyntax("need required parameter (algorithm)");
timing_recovery_algorithm_t algorithm = timing_recovery_get_algorithm_from_string(argv[2]);
@ -2530,8 +2531,12 @@ int main(int argc, char *argv[])
int add_q = (argc>=5 && !strcmp(argv[4], "--add_q"));
int debug_n = 0;
int output_error = 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;
float* timing_error = NULL;
if(output_error) timing_error = (float*)malloc(sizeof(float)*the_bufsize);
if(!initialize_buffers()) return -2;
sendbufsize(the_bufsize/decimation);
@ -2546,9 +2551,10 @@ int main(int argc, char *argv[])
{
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, &state);
timing_recovery_cc((complexf*)input_buffer, (complexf*)output_buffer, the_bufsize, timing_error, &state);
//fprintf(stderr, "trcc is=%d, os=%d, ip=%d\n",the_bufsize, state.output_size, state.input_processed);
fwrite(output_buffer, sizeof(complexf), state.output_size, stdout);
if(timing_error) fwrite(timing_error, sizeof(float), state.output_size, stdout);
else fwrite(output_buffer, sizeof(complexf), state.output_size, stdout);
TRY_YIELD;
//fprintf(stderr, "state.input_processed = %d\n", state.input_processed);
memmove((complexf*)input_buffer,((complexf*)input_buffer)+state.input_processed,(the_bufsize-state.input_processed)*sizeof(complexf)); //memmove lets the source and destination overlap
@ -2867,6 +2873,19 @@ int main(int argc, char *argv[])
}
}
if(!strcmp(argv[1], "repeat_u8"))
{
if(argc<=2) badsyntax("no data to repeat");
unsigned char* repeat_buffer = (unsigned char*)malloc(sizeof(unsigned char)*(argc-2));
for(int i=0;i<argc-2;i++)
{
int current_val;
sscanf(argv[i+2], "%d", &current_val);
repeat_buffer[i]=current_val;
}
for(;;) fwrite(repeat_buffer, sizeof(unsigned char), argc-2, stdout);
}
if(!strcmp(argv[1],"none"))
{
return 0;

38
grc_tests/bpsk31_scurve.m Executable file
View file

@ -0,0 +1,38 @@
#!/usr/bin/octave
%{
function [output]=fgc(path, type)
if(type(1)=='f')
elseif(type(1)=='c')
end
end
%}
function output=shrunf(cmd)
SIGTERM=15;
output=[];
[pin, pout, pid]=popen2('bash',{'-c', cmd});
%fclose(pin);
sleep(0.1)
do
current_output=fread(pout, Inf, 'float32');
output=[output; current_output];
until(feof(pout))
waitpid(pid);
%kill(pid, SIGTERM);
end
function error_value=run_tr(skip)
out_vect=shrunf(sprintf('dd bs=8 skip=%d if=grc_tests/bpsk31_baseband_sample_complex_8000_sps_010101.raw | csdr timing_recovery_cc EARLYLATE 256 --add_q --output_error',skip));
error_value=out_vect(2);
end
skips=0:400
error_values=[]
for skip=skips
error_values=[error_values run_tr(skip)];
end
error_values
plot(skips, error_values);
pause

View file

@ -1919,7 +1919,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, timing_recovery_state_t* state)
void timing_recovery_cc(complexf* input, complexf* output, int input_size, float* timing_error, 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.
@ -1977,6 +1977,8 @@ void timing_recovery_cc(complexf* input, complexf* output, int input_size, timin
}
//Original correction method: this version can only move a single sample in any direction
//current_bitstart_index += num_samples_halfbit * 2 + (error)?((error<0)?1:-1):0;
if(timing_error) timing_error[si-1]=error; //it is not written if NULL
if(error>2) error=2;
if(error<-2) error=-2;

View file

@ -334,7 +334,7 @@ typedef struct timing_recovery_state_s
} timing_recovery_state_t;
timing_recovery_state_t timing_recovery_init(timing_recovery_algorithm_t algorithm, int decimation_rate, int use_q);
void timing_recovery_cc(complexf* input, complexf* output, int input_length, timing_recovery_state_t* state);
void timing_recovery_cc(complexf* input, complexf* output, int input_size, float* timing_error, timing_recovery_state_t* state);
timing_recovery_algorithm_t timing_recovery_get_algorithm_from_string(char* input);
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);