From d391ea2ef62c0d4335b8096a2abd3422a7d9370a Mon Sep 17 00:00:00 2001 From: ha7ilm Date: Fri, 28 Apr 2017 14:20:14 +0200 Subject: [PATCH] Added BPSK31 S-curve generator script, added repeat_u8 and error output fortiming_recovery_cc --- README.md | 17 ++++++++ csdr.c | 25 ++++++++++-- ...aseband_sample_complex_8000_sps_010101.raw | Bin 0 -> 20608 bytes grc_tests/bpsk31_scurve.m | 38 ++++++++++++++++++ libcsdr.c | 4 +- libcsdr.h | 2 +- 6 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 grc_tests/bpsk31_baseband_sample_complex_8000_sps_010101.raw create mode 100755 grc_tests/bpsk31_scurve.m diff --git a/README.md b/README.md index 90445c3..576e757 100755 --- a/README.md +++ b/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 [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: diff --git a/csdr.c b/csdr.c index 1283254..4e3aec8 100755 --- a/csdr.c +++ b/csdr.c @@ -139,6 +139,7 @@ char usage[]= " simple_agc_cc [reference [max_gain]]\n" " firdes_resonator_c [window [--octave]]\n" " resonators_fir_cc [resonator_rate × N]\n" +" repeat_u8 \n" " ?\n" " =\n" " \n" @@ -2516,7 +2517,7 @@ int main(int argc, char *argv[]) } } - if(!strcmp(argv[1],"timing_recovery_cc")) // [--add_q [--octave ]] + if(!strcmp(argv[1],"timing_recovery_cc")) // [--add_q [--output_error | --octave ]] { 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}Z%5#qz1MobpAT!V^^)Wt zS@64`ARqkeYWJli|H!^?&go6Z{Yv^CY5Nid7d3Tt`}ze6t{URHvof5LIxltA>k~#k z2S0Ib{;3Nk<#=2NcXg&PyVx~hY$pmU{ML24K?h2pN3N<9A(V2Vz7?>z9VJCHwL-cF zQ|{q**1%iO(auKQtdIA$q<_ZuwVs{SoQ|I!Y~5@XL_ST%SfN(}snPgJ)@^qHCAnu= z{l+(<;tPwcfo=Th`0`|{enkUHU7KRz1!^)|ul)p?RD`o#Z*>OOw6&Lf19P*s9miqrF1Md`BKbQO< z$K;h*w?6t#o?Cjsa*wt*SKHsZ}IYot4_op>~8l?=HUB2E^3AjkIXAj*0t%fQr5 zqBMEAjJn-f{N=NS@@n6%;&k~Ong2nU=n?XkEG-Vl^-PiXYP~2ze~Xpv`n)9iEq+z@ zpV3?R1->Httm`YjEE*yoWm)1>N`E=y?B7NAsVX4i+sAgvfv|BSqw|tz~6Fv=}t9x%AyJOpGjUEQ6Q4BDRe6mtxpR5%aj79MWvG zD9x)W!>^1H?OXrht=K$P+^W3m9W^9IbgOmK`}W<}#rTM8-WI8`qCE4GcTATFqH5?l zZyhyJgtjj7wi`4_R5%Vx%j zWU7ybozs^kY?yLW{Sa3PX+c0{j$oqY+cj9}qg#Z3&-c*_`2A&w}-Ch?~uTGqHt@F_iBUrVsHP3UcX24MU9vm-ZNJh zh?jDI^3=;;C@yTj>^ZagA0lVk8BgWtMPk2SwkJJcu?X9++q3=bV$tB?29NK&CE{NH zWRD75D(+sL?m3^aRQ&u$l&53gWr8ZgJf)v66Wca5^JMf{F4{Nr^_)ArTtt3ao)yyg zU9liHJIkB!u6TLo#;o{L?~2Q_;<94=6UES8-Lv9{CyHyme6up%PZWP%&(3Tl6UFAW zahd5~C5rYh`(_UK(RrQGs47u>V8uud}8T$LT4)Aq;K72!5 zrhdN{E3z~7`w#E!>wMlM{dxHO#MyDq^+e%%^!4q+_37)KhwIhXAA;-G_fv%X(f5~+ z`_uOu^k0 zR>PT(!tinJ zL)Xha)Qhg47N{RxPg_t=F{rP$s4rb_lTmNF{_3LsbUoUrM_r#?P@lS9eTJQL>bDH_ z%k`}5I~4V;>%9W?uIs-e>R;!f7aYA zY2IB2@0fp@hY8@J=3_AU$h_42Oanieryao8ufW$5@HQ8`y$SxNgTHy;aWr_$e0~MI zUIkt=zx#pbq2PH5_`VH%XWj>a|38BNk?_G{_@EQ~Fdcrl17ECyFW4W?!Y8NT6ZXr8 z@Xbv4raSy|0{&?WABDq5>?iisdH8Dp{KY;CfZuMxZ|pnvANz1O{I~{wq$j>ie&SE| zDf^Xu>w);zk9*wUE%ZfPyEil{~!N5zYoCw1qWjy zwEqjc?CY=nUpV`>0ownCVCc@rk-@vy^pOws31&V22EyV|JxmhCldT`uggm!_}@NKx`I#-_Wbf>g8%KaH{K)o-`;coeM0@% zfBLK>_}@O~_aULa>{^Xe2>!RXHD5*Wzn#+hBZB|!<84Q=jt3H7Ur zgVz%3S(Ub0N2qW0ebe=XdRGC@Y#`LX8d!THArET7!;OS|DEIA61pljpS5gW2QRyX{ z33*bJkA6bPm#W;JM#!6bb!9ri|0-eT7D67C815$IQ{{HuO316a)NmUiziQ2mZG=3l zOD8@h?H6&)$!j&;DgF6-$n4h%HF%1;D6O*)*b>+RB_l| z0$@k9W zR6HFc_(%<_lS}ZEIx;qw;48ItPcFesyAcv3BFWy*W?rYshZ~H6MU*RT+b)?RV}PnK=8jR3N0Y`S1pPxAoyQx zoQBuK6IH;n0)nsA{dENd|0~zd0)o%g_ZbBQzpJ}P@&8qc>WzW|{QjS$y4wGJ&0pv5 z=bz{IEOIH?BXfN3Kt z&JX8_^9BE_P~?sC$9d#@a$ezoC%^E&I*L4VzB%ulfB0Wjfd|Y7<^}VEdBS{Q-oXEA z4*0`7Vm>jim|yU}Isl$A->@5C1#-hyNWP!2gaP;D5&#><{?geh8niU*LboH}JpXANb$#5&MaK z1^?U4;VAkl{~#4F5ZRhW{O3 z!~cbI;BWZ9up4|1{}&v9-{F6={x|D?v;H^hf3yBK>wmNUH|u}1{x|FYr|Sc={x|D? z{k*`e|Er%Lne~75^F*`$uYSI4*8gVz-|YXJ{eQFnZ}$Jq{=eD(H~ar)|KIHYoBjW% z`_pFs-#M>f_W!HTubBORv;VKpvzh&WbN=6)|2OCV&G~nGxbN@K^lXHJLuQ$2>-1Prf|2+bJ nKEcl``1u7t&*0}9{Jg{T|5yM03)BB!{r6Bz|Ns9-|NnmgC4HxD literal 0 HcmV?d00001 diff --git a/grc_tests/bpsk31_scurve.m b/grc_tests/bpsk31_scurve.m new file mode 100755 index 0000000..5e0b3a8 --- /dev/null +++ b/grc_tests/bpsk31_scurve.m @@ -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 diff --git a/libcsdr.c b/libcsdr.c index e0a6851..2901331 100755 --- a/libcsdr.c +++ b/libcsdr.c @@ -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; diff --git a/libcsdr.h b/libcsdr.h index 0a0febf..8617282 100644 --- a/libcsdr.h +++ b/libcsdr.h @@ -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);