Edited Makefile

Changed functionality of pack_bits_8to1_u8_u8
Added pack_bits_1to8_u8_u8, pattern_search_u8_u8, dbpsk_decoder_c_u8, bfsk_demod_cf
This commit is contained in:
ha7ilm 2017-05-18 23:43:40 +02:00
parent 117ee8e3a8
commit f9a6535e10
7 changed files with 271 additions and 22 deletions

View file

@ -42,6 +42,7 @@ PARAMS_MISC = -Wno-unused-result
#DEBUG_ON = 0 #debug is always on by now (anyway it could be compiled with `make DEBUG_ON=1`)
#PARAMS_DEBUG = $(if $(DEBUG_ON),-g,)
FFTW_PACKAGE = fftw-3.3.3
PARSEVECT ?= yes
.PHONY: clean-vect clean codequality
all: codequality csdr nmux
@ -51,7 +52,9 @@ libcsdr.so: fft_fftw.c fft_rpi.c libcsdr_wrapper.c libcsdr.c libcsdr_gpl.c fastd
@echo
rm -f dumpvect*.vect
gcc -std=gnu99 $(PARAMS_LOOPVECT) $(PARAMS_SIMD) $(LIBSOURCES) $(PARAMS_LIBS) $(PARAMS_MISC) -fpic -shared -o libcsdr.so
ifeq ($(PARSEVECT),yes)
-./parsevect dumpvect*.vect
endif
csdr: csdr.c libcsdr.so
gcc -std=gnu99 $(PARAMS_LOOPVECT) $(PARAMS_SIMD) csdr.c $(PARAMS_LIBS) -L. -lcsdr $(PARAMS_MISC) -o csdr
ddcd: ddcd.cpp libcsdr.so ddcd.h

View file

@ -832,7 +832,7 @@ For this input, the output of `psk31_varicode_encoder_u8_u8` will be the followi
Syntax:
csdr repeat_u8 <taps_length> [resonator_rate × N]\n"
csdr repeat_u8 <data_bytes × N>
It repeatedly outputs a set of data bytes (given with decimal numbers).
@ -871,6 +871,16 @@ Syntax:
csdr pack_bits_8to1_u8_u8
TODO
----
### [pack_bits_1to8_u8_u8](#pack_bits_1to8_u8_u8)
Syntax:
csdr pack_bits_1to8_u8_u8
It serializes the bytes on the input: it outputs each bit of the input byte as a single byte valued 0x00 or 0x01, starting from the lowest bit and going to the highest bit.
The output is 8 times as large in size as the input.

173
csdr.c
View file

@ -146,6 +146,7 @@ char usage[]=
" gaussian_noise_c\n"
" awgn_cc <snr_db> [--snrshow]\n"
" pack_bits_8to1_u8_u8\n"
" pack_bits_1to8_u8_u8\n"
" firdes_pulse_shaping_filter_f (RRC <samples_per_symbol> <num_taps> <beta> | COSINE <samples_per_symbol>)\n"
" pulse_shaping_filter_cc (RRC <samples_per_symbol> <num_taps> <beta> | COSINE <samples_per_symbol>)\n"
" add_n_zero_samples_at_beginning_f <n_zero_samples>\n"
@ -154,6 +155,9 @@ char usage[]=
" add_const_cc <i> <q>\n"
" tee <path> [buffers]\n"
" pll_cc (1 [alpha] |2 [bandwidth [damping_factor [ko [kd]]]])\n"
" pattern_search_u8_u8 <values_after> <pattern_values × N>\n"
" dbpsk_decoder_c_u8\n"
" bfsk_demod_cf <spacing> <filter_length>\n"
" ?<search_the_function_list>\n"
" =<evaluate_python_expression>\n"
" \n"
@ -2723,7 +2727,7 @@ int main(int argc, char *argv[])
}
}
if(!strcmp(argv[1],"pack_bits_8to1_u8_u8"))
if(!strcmp(argv[1],"pack_bits_1to8_u8_u8"))
{
if(!initialize_buffers()) return -2;
sendbufsize(the_bufsize*8);
@ -2733,12 +2737,27 @@ int main(int argc, char *argv[])
{
FEOF_CHECK;
fread((void*)local_input_buffer, sizeof(unsigned char), the_bufsize, stdin);
pack_bits_8to1_u8_u8(local_input_buffer, local_output_buffer, the_bufsize);
pack_bits_1to8_u8_u8(local_input_buffer, local_output_buffer, the_bufsize);
fwrite((void*)local_output_buffer, sizeof(unsigned char), the_bufsize*8, stdout);
TRY_YIELD;
}
}
if(!strcmp(argv[1],"pack_bits_8to1_u8_u8"))
{
if(!initialize_buffers()) return -2;
sendbufsize(1);
char local_input_buffer[8];
for(;;)
{
FEOF_CHECK;
fread((void*)local_input_buffer, sizeof(unsigned char), 8, stdin);
unsigned char c = pack_bits_8to1_u8_u8(local_input_buffer);
fwrite(&c, sizeof(unsigned char), 1, stdout);
TRY_YIELD;
}
}
if(!strcmp(argv[1],"psk31_varicode_encoder_u8_u8"))
{
if(!initialize_buffers()) return -2;
@ -2914,7 +2933,7 @@ int main(int argc, char *argv[])
complexf* taps=(complexf*)malloc(sizeof(complexf)*length);
//Make the filter
firdes_add_resonator_c(taps, length, rate, window, 0, 1);
firdes_add_peak_c(taps, length, rate, window, 0, 1);
//Do the output
if(octave) printf("taps=[");
@ -2960,7 +2979,7 @@ int main(int argc, char *argv[])
for(int i=0; i<num_peaks; i++)
{
//fprintf(stderr, "nr = %d\n", i==num_peaks-1);
firdes_add_resonator_c(taps, taps_length, peak_rate[i], window, 1, i==num_peaks-1);
firdes_add_peak_c(taps, taps_length, peak_rate[i], window, 1, i==num_peaks-1);
}
int output_size=0;
@ -3215,6 +3234,53 @@ int main(int argc, char *argv[])
return 0;
}
if(!strcmp(argv[1], "dbpsk_decoder_c_u8"))
{
if(!sendbufsize(initialize_buffers())) return -2;
unsigned char* local_output_buffer = (unsigned char*)malloc(sizeof(unsigned char)*the_bufsize);
for(;;)
{
FEOF_CHECK;
FREAD_C;
dbpsk_decoder_c_u8((complexf*)input_buffer, local_output_buffer, the_bufsize);
fwrite(local_output_buffer, sizeof(unsigned char), the_bufsize, stdout);
TRY_YIELD;
}
return 0;
}
if(!strcmp(argv[1], "bfsk_demod_cf")) //<spacing> <filter_length>
{
float frequency_shift = 0;
if(argc<=2) return badsyntax("required parameter <frequency_shift> is missing.");
sscanf(argv[2],"%f",&frequency_shift);
int filter_length = 0;
if(argc<=3) return badsyntax("required parameter <filter_length> is missing.");
sscanf(argv[3],"%d",&filter_length);
complexf* mark_filter = (complexf*)malloc(sizeof(complexf)*filter_length);
complexf* space_filter = (complexf*)malloc(sizeof(complexf)*filter_length);
firdes_add_peak_c(mark_filter, filter_length, frequency_shift/2, WINDOW_DEFAULT, 0, 1);
firdes_add_peak_c(space_filter, filter_length, -frequency_shift/2, WINDOW_DEFAULT, 0, 1);
if(!sendbufsize(initialize_buffers())) return -2;
int input_skip=0;
int output_size=0;
FREAD_C;
for(;;)
{
FEOF_CHECK;
output_size=bfsk_demod_cf((complexf*)input_buffer, output_buffer, the_bufsize, mark_filter, space_filter, filter_length);
fwrite(output_buffer, sizeof(float), output_size, stdout);
TRY_YIELD;
memmove((complexf*)input_buffer,((complexf*)input_buffer)+output_size,(the_bufsize-output_size)*sizeof(complexf));
fread(((complexf*)input_buffer)+(the_bufsize-output_size), sizeof(complexf), output_size, stdin);
}
return 0;
}
if(!strcmp(argv[1], "add_const_cc")) //<i> <q>
{
complexf x;
@ -3411,6 +3477,105 @@ int main(int argc, char *argv[])
TRY_YIELD;
}
}
/*
if(!strcmp(argv[1],"syncword_search"))
{
if(argc<3) return badsyntax("need required parameter (syncword)");
unsigned long syncword=0UL;
int syncword_length=strlen(argv[2]);
for(int i=0; i<sycword_len;i++)
{
syncword<<=4;
char c=argv[2][i];
unsigned char cval = 0;
if(c<='9'&&c>='0') cval = c-'0';
if(c<='f'&&c>='a') cval = c-'a'+10;
syncword|=cval;
}
errhead(); fprintf("syncword = 0x%0x, syncword_length=%d\n", syncword, syncword_length);
if(argc<4) return badsyntax("need required parameter (bits_after)");
int bits_after = 0;
sscanf(argv[3], &bits_after);
if(bits_after<0) return badsyntax("bits_after should be >0");
unsigned char* syncword_bits = malloc(sizeof(unsigned char)*syncword_length*4);
int k=0;
for(int i=0;i<syncword_length;i++)
{
for(int j=7;j;j--)
{
syncword_bits[k++]=syncword[i]>>j
}
}
malloc
}
*/
if(!strcmp(argv[1],"pattern_search_u8_u8")) //<values_after> <pattern_values × N>
{
if(argc<3) return badsyntax("need required parameter (values_after)");
int values_after = 0;
sscanf(argv[2], "%d", &values_after);
if(argc<4) return badsyntax("need required parameter (pattern_values × N)");
int pattern_values_length = argc-3;
unsigned* pattern_values = (unsigned*)malloc(sizeof(unsigned)*pattern_values_length);
for(int i=0;i<pattern_values_length;i++)
sscanf(argv[3+i],"%u",pattern_values+i);
errhead(); fprintf(stderr,"pattern values: ");
for(int i=0;i<pattern_values_length;i++)
fprintf(stderr, "%x ", *(pattern_values+i));
fprintf(stderr,"\n");
unsigned char* input_buffer = (unsigned char*)malloc(sizeof(unsigned char)*pattern_values_length); //circular buffer
unsigned char* output_buffer = (unsigned char*)malloc(sizeof(unsigned char)*values_after);
int input_index = 0;
int valid_values = 0;
for(;;)
{
FEOF_CHECK;
unsigned char cchar = input_buffer[input_index++]=(unsigned char)fgetc(stdin);
if(valid_values<pattern_values_length) { valid_values++; continue; }
if(input_index>=pattern_values_length) input_index=0;
int match=1;
//fprintf(stderr, "ov1: ");
//for(int i=0;i<pattern_values_length;i++) fprintf(stderr, "%02x ", input_buffer[i]);
//fprintf(stderr, "\nov2: ");
//for(int i=0;i<pattern_values_length;i++) fprintf(stderr, "%02x ", pattern_values[i]);
//fprintf(stderr, "\n");
//fprintf(stderr, "v1: ");
//for(int i=input_index;i<pattern_values_length;i++) fprintf(stderr, "%s%02x ", ((input_buffer[i])?"\x1B[34m":"\x1B[0m"), input_buffer[i]);
//for(int i=0;i<input_index;i++) fprintf(stderr, "%s%02x ", ((input_buffer[i])?"\x1B[34m":"\x1B[0m"), input_buffer[i]);
//fprintf(stderr, "\x1B[0m %02x\n", cchar);
//fprintf(stderr, "========\n");
int j=0;
for(int i=input_index;i<pattern_values_length;i++)
{
//fprintf(stderr, "%02x ~ %02x\n", input_buffer[i], pattern_values[j]);
if(input_buffer[i]!=pattern_values[j++]) { match=0; break;}
}
//fprintf(stderr, "~~~~~~~~\n");
if(input_index!=0 && match)
{
for(int i=0;i<input_index;i++)
{
//fprintf(stderr, "%02x ~ %02x\n", input_buffer[i], pattern_values[j]);
if(input_buffer[i]!=pattern_values[j++]) { match=0; break;}
}
}
//if(match) fprintf(stderr, "j=%d\n", j);
if(match )
{
valid_values = 0;
//fprintf(stderr,"matched!\n");
fread(output_buffer, sizeof(unsigned char), values_after, stdin);
fwrite(output_buffer, sizeof(unsigned char), values_after, stdout);
}
TRY_YIELD;
}
}
if(!strcmp(argv[1],"none"))
{

View file

@ -14,15 +14,19 @@ function g=gbb(t) %impulse response of pulse shaping filter
end
end
global padding=[-2 2];
function [toreturny, plotrange]=y(s)
global Tb
global padding
slen=size(s)(2)
plotrange=(-3*Tb):(slen+2)*Tb-1;
plotrange=((padding(1)-1)*Tb):(slen+padding(2))*Tb-1;
plotlen=size(plotrange)(2)
toreturny=zeros(1,plotlen);
for i=1:slen %sum of (symbol[i] * filter impulse response) for all symbols
toreturny+=s(i)*gbb(plotrange.-(i-1)*Tb);
end
plotrange=plotrange/Tb
end
function fmtplot(h)
@ -36,15 +40,31 @@ end
h=figure(1);
subplot(2, 1, 1);
plot(y([1]), 'linewidth', 2)
title(sprintf("Impulse response of pulse shaping filter\n(1 symbol = %d samples)", Tb))
xlabel('t [1/Ts]')
[a b]=y([1]);
plot(b, a, 'linewidth', 2)
title(sprintf("Impulse response of pulse shaping filter"))
xlabel('t/Ts')
ylabel('h(t)')
subplot(2, 1, 2);
plot(y([1 1 -1 -1 1 1 1 -1 1 -1 1 1]), 'linewidth', 2)
[a b]=y([1 1 -1 -1 1 1 1 -1 1 -1 1 1]);
plot(b, a, 'linewidth', 2)
title("Baseband signal for modulator input\nbit sequence: 110011101011") %assuming that differential encoding has already been performed
xlabel('t [1/Ts]')
xlabel('t/Ts')
ylabel('s(t)')
xbounds = xlim;
set(gca,'XTick',xbounds(1):xbounds(2));
fmtplot(h);
pause
exit
%fourier analisys of baseband signal
h2=figure(2);
padding=[-1 1]
plot(y([1]))
h3=figure(3);
fftvals=abs(fft(y([1])));
sizefftvals=size(fftvals)(2)
fftvals=[fftvals(sizefftvals/2:sizefftvals) fftvals(2:sizefftvals/2)]
plot(fftvals, "-")
pause

View file

@ -4,6 +4,7 @@ sox -r 48k -t f32 -c 1 /s/costas_error -t wav -e floating-point /s/costas_error.
sox -r 48k -t f32 -c 1 /s/costas_dphase -t wav -e floating-point --norm=-6 /s/costas_dphase.wav
sox -r 48k -t f32 -c 2 /s/costas_input -t wav -e floating-point /s/costas_input.wav
sox -r 48k -t f32 -c 2 /s/costas_output -t wav -e floating-point /s/costas_output.wav
sox -r 48k -t f32 -c 2 /s/tr_input -t wav -e floating-point /s/tr_input.wav
ls -al /s/costas_nco.wav /s/costas_error.wav /s/costas_dphase.wav /s/costas_output.wav /s/costas_input.wav

View file

@ -1798,13 +1798,24 @@ complexf psk31_interpolate_sine_cc(complexf* input, complexf* output, int input_
return last_input;
}
void pack_bits_8to1_u8_u8(unsigned char* input, unsigned char* output, int input_size)
void pack_bits_1to8_u8_u8(unsigned char* input, unsigned char* output, int input_size)
{ //output size should be input_size × 8
for(int i=0; i<input_size; i++)
for(int bi=0; bi<8; bi++) //bi: bit index
*(output++)=(input[i]>>bi)&1;
}
unsigned char pack_bits_8to1_u8_u8(unsigned char* input)
{
unsigned char output;
for(int i=0;i<8;i++)
{
output<<=1;
output|=!!input[i];
}
return output;
}
unsigned char differential_codec(unsigned char* input, unsigned char* output, int input_size, int encode, unsigned char state)
{
if(!encode)
@ -2081,7 +2092,8 @@ void init_bpsk_costas_loop_cc(bpsk_costas_loop_state_t* s, int decision_directed
s->alpha = (4*damping_factor*bandwidth_omega)/denomiator;
s->beta = (4*bandwidth_omega*bandwidth_omega)/denomiator;
s->current_freq = s->dphase = s->nco_phase = 0;
s->dphase_max=bandwidth*PI; //this has been determined by experiment: if dphase is out of [-dphase_max; dphase_max] it might actually hang and not come back
s->dphase_max=bandwidth_omega; //this has been determined by experiment: if dphase is out of [-dphase_max; dphase_max] it might actually hang and not come back
s->dphase_max_reset_to_zero=0;
}
void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, float* output_error, float* output_dphase, complexf* output_nco, bpsk_costas_loop_state_t* s)
@ -2108,8 +2120,8 @@ void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, floa
if(output_error) output_error[i]=error;
s->current_freq += error * s->beta;
s->dphase = error * s->alpha + s->current_freq;
if(s->dphase>s->dphase_max) s->dphase=s->dphase_max;
if(s->dphase<-s->dphase_max) s->dphase=-s->dphase_max;
if(s->dphase>s->dphase_max) s->dphase = (s->dphase_max_reset_to_zero) ? 0 : s->dphase_max;
if(s->dphase<-s->dphase_max) s->dphase = (s->dphase_max_reset_to_zero) ? 0 : -s->dphase_max;
if(output_dphase) output_dphase[i]=s->dphase;
//fprintf(stderr, " error = %f; dphase = %f; nco_phase = %f;\n", error, s->dphase, s->nco_phase);
@ -2195,7 +2207,7 @@ void simple_agc_cc(complexf* input, complexf* output, int input_size, float rate
}
}
void firdes_add_resonator_c(complexf* output, int length, float rate, window_t window, int add, int normalize)
void firdes_add_peak_c(complexf* output, int length, float rate, window_t window, int add, int normalize)
{
//add=0: malloc output previously
//add=1: calloc output previously
@ -2203,7 +2215,7 @@ void firdes_add_resonator_c(complexf* output, int length, float rate, window_t w
int middle=length/2;
float phase = 0, phase_addition = -rate*M_PI*2;
float (*window_function)(float) = firdes_get_window_kernel(window);
for(int i=0; i<length; i++) //@@firdes_add_resonator_c: calculate taps
for(int i=0; i<length; i++) //@@firdes_add_peak_c: calculate taps
{
e_powj(&taps[i], phase);
float window_multiplier = window_function(fabs((float)(middle-i)/middle));
@ -2225,11 +2237,11 @@ void firdes_add_resonator_c(complexf* output, int length, float rate, window_t w
if(normalize)
{
float sum=0;
for(int i=0;i<length;i++) //@firdes_add_resonator_c: normalize pass 1
for(int i=0;i<length;i++) //@firdes_add_peak_c: normalize pass 1
{
sum+=sqrt(output[i].i*output[i].i + output[i].q*output[i].q);
}
for(int i=0;i<length;i++) //@firdes_add_resonator_c: normalize pass 2
for(int i=0;i<length;i++) //@firdes_add_peak_c: normalize pass 2
{
output[i].i/=sum;
output[i].q/=sum;
@ -2295,6 +2307,40 @@ float normalized_timing_variance_u32_f(unsigned* input, float* temp, int input_s
return result;
}
void dbpsk_decoder_c_u8(complexf* input, unsigned char* output, int input_size)
{
static complexf last_input;
for(int i=0;i<input_size;i++)
{
float phase = atan2(qof(input,i), iof(input,i));
float last_phase = atan2(qofv(last_input), iofv(last_input));
float dphase = phase-last_phase;
while(dphase<-PI) dphase+=2*PI;
while(dphase>=PI) dphase-=2*PI;
if( (dphase>(PI/2)) || (dphase<(-PI/2)) ) output[i]=0;
else output[i]=1;
last_input = input[i];
}
}
int bfsk_demod_cf(complexf* input, float* output, int input_size, complexf* mark_filter, complexf* space_filter, int taps_length)
{
complexf acc_space, acc_mark;
for(int i=0; i<input_size-taps_length+1; i++)
{
csetnull(&acc_space);
csetnull(&acc_mark);
for(int ti=0;ti<taps_length;ti++)
{
cmultadd(&acc_space, &input[i+ti], &space_filter[ti]);
cmultadd(&acc_mark, &input[i+ti], &mark_filter[ti]);
}
output[i] = - ( iofv(acc_space)*iofv(acc_space)+qofv(acc_space)*qofv(acc_space) ) +
( iofv(acc_mark)*iofv(acc_mark)+qofv(acc_mark)*qofv(acc_mark) );
}
return input_size-taps_length+1;
}
/*
_____ _ _
| __ \ | | (_)

View file

@ -343,7 +343,6 @@ void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error
void psk_modulator_u8_c(unsigned char* input, complexf* output, int input_size, int n_psk);
void duplicate_samples_ntimes_u8_u8(unsigned char* input, unsigned char* output, int input_size_bytes, int sample_size_bytes, int ntimes);
complexf psk31_interpolate_sine_cc(complexf* input, complexf* output, int input_size, int interpolation, complexf last_input);
void pack_bits_8to1_u8_u8(unsigned char* input, unsigned char* output, int input_size);
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);
unsigned char differential_codec(unsigned char* input, unsigned char* output, int input_size, int encode, unsigned char state);
@ -371,6 +370,7 @@ typedef struct bpsk_costas_loop_state_s
float dphase;
float nco_phase;
float dphase_max;
int dphase_max_reset_to_zero;
} bpsk_costas_loop_state_t;
void plain_interpolate_cc(complexf* input, complexf* output, int input_size, int interpolation);
@ -378,7 +378,7 @@ void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, floa
void init_bpsk_costas_loop_cc(bpsk_costas_loop_state_t* s, int decision_directed, float damping_factor, float bandwidth);
void simple_agc_cc(complexf* input, complexf* output, int input_size, float rate, float reference, float max_gain, float* current_gain);
void firdes_add_resonator_c(complexf* output, int length, float rate, window_t window, int add, int normalize);
void firdes_add_peak_c(complexf* output, int length, float rate, window_t window, int add, int normalize);
int apply_fir_cc(complexf* input, complexf* output, int input_size, complexf* taps, int taps_length);
@ -406,3 +406,7 @@ void generic_slicer_f_u8(float* input, unsigned char* output, int input_size, in
void plain_interpolate_cc(complexf* input, complexf* output, int input_size, int interpolation);;
void normalize_fir_f(float* input, float* output, int length);
float* add_const_cc(complexf* input, complexf* output, int input_size, complexf x);
void pack_bits_1to8_u8_u8(unsigned char* input, unsigned char* output, int input_size);
unsigned char pack_bits_8to1_u8_u8(unsigned char* input);
void dbpsk_decoder_c_u8(complexf* input, unsigned char* output, int input_size);
int bfsk_demod_cf(complexf* input, float* output, int input_size, complexf* mark_filter, complexf* space_filter, int taps_length);