Added BPSK31 S-curve generator script, added repeat_u8 and error output fortiming_recovery_cc
This commit is contained in:
parent
22bd8baa15
commit
d391ea2ef6
6 changed files with 81 additions and 5 deletions
17
README.md
17
README.md
|
@ -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)
|
### [?](#search_the_function_list)
|
||||||
|
|
||||||
Syntax:
|
Syntax:
|
||||||
|
|
25
csdr.c
25
csdr.c
|
@ -139,6 +139,7 @@ char usage[]=
|
||||||
" simple_agc_cc <rate> [reference [max_gain]]\n"
|
" simple_agc_cc <rate> [reference [max_gain]]\n"
|
||||||
" firdes_resonator_c <rate> <length> [window [--octave]]\n"
|
" firdes_resonator_c <rate> <length> [window [--octave]]\n"
|
||||||
" resonators_fir_cc <taps_length> [resonator_rate × N]\n"
|
" resonators_fir_cc <taps_length> [resonator_rate × N]\n"
|
||||||
|
" repeat_u8 <data_bytes × N>\n"
|
||||||
" ?<search_the_function_list>\n"
|
" ?<search_the_function_list>\n"
|
||||||
" =<evaluate_python_expression>\n"
|
" =<evaluate_python_expression>\n"
|
||||||
" \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)");
|
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]);
|
||||||
|
@ -2530,8 +2531,12 @@ int main(int argc, char *argv[])
|
||||||
int add_q = (argc>=5 && !strcmp(argv[4], "--add_q"));
|
int add_q = (argc>=5 && !strcmp(argv[4], "--add_q"));
|
||||||
|
|
||||||
int debug_n = 0;
|
int debug_n = 0;
|
||||||
|
int output_error = 0;
|
||||||
if(argc>=7 && !strcmp(argv[5], "--octave")) debug_n = atoi(argv[6]);
|
if(argc>=7 && !strcmp(argv[5], "--octave")) debug_n = atoi(argv[6]);
|
||||||
if(debug_n<0) badsyntax("debug_n should be >= 0");
|
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;
|
if(!initialize_buffers()) return -2;
|
||||||
sendbufsize(the_bufsize/decimation);
|
sendbufsize(the_bufsize/decimation);
|
||||||
|
@ -2546,9 +2551,10 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
FEOF_CHECK;
|
FEOF_CHECK;
|
||||||
if(debug_n && ++debug_i%debug_n==0) timing_recovery_trigger_debug(&state, 3);
|
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);
|
//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;
|
TRY_YIELD;
|
||||||
//fprintf(stderr, "state.input_processed = %d\n", state.input_processed);
|
//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
|
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", ¤t_val);
|
||||||
|
repeat_buffer[i]=current_val;
|
||||||
|
}
|
||||||
|
for(;;) fwrite(repeat_buffer, sizeof(unsigned char), argc-2, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
if(!strcmp(argv[1],"none"))
|
if(!strcmp(argv[1],"none"))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
BIN
grc_tests/bpsk31_baseband_sample_complex_8000_sps_010101.raw
Normal file
BIN
grc_tests/bpsk31_baseband_sample_complex_8000_sps_010101.raw
Normal file
Binary file not shown.
38
grc_tests/bpsk31_scurve.m
Executable file
38
grc_tests/bpsk31_scurve.m
Executable 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
|
|
@ -1919,7 +1919,7 @@ void timing_recovery_trigger_debug(timing_recovery_state_t* state, int debug_pha
|
||||||
|
|
||||||
#define MTIMINGR_HDEBUG 0
|
#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.
|
//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.
|
//Last time we consumed that much from the input samples that it is there.
|
||||||
|
@ -1978,6 +1978,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
|
//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;
|
//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;
|
||||||
if(error<-2) error=-2;
|
if(error<-2) error=-2;
|
||||||
if( state->debug_force || (state->debug_phase >= si && debug_i) )
|
if( state->debug_force || (state->debug_phase >= si && debug_i) )
|
||||||
|
|
|
@ -334,7 +334,7 @@ typedef struct timing_recovery_state_s
|
||||||
} 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);
|
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);
|
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 timing_recovery_trigger_debug(timing_recovery_state_t* state, int debug_phase);
|
||||||
|
|
Loading…
Reference in a new issue