re = real(s); im = imag(s);\r
l = length(s);\r
iq = zeros(1,2*l);\r
- iq(1:2:2*l) = 127 + re*(127/mx); \r
- iq(2:2:2*l) = 127 + im*(127/mx); \r
+ %iq(1:2:2*l) = 127 + re*(127/mx); \r
+ %iq(2:2:2*l) = 127 + im*(127/mx); \r
+ iq(1:2:2*l) = 127 + 32*re; \r
+ iq(2:2:2*l) = 127 + 32*im; \r
+ figure(3); clf; plot(iq);\r
fs = fopen(filename,"wb");\r
fwrite(fs,iq,"uchar");\r
fclose(fs);\r
endfunction\r
\r
\r
+% Oversamples by a factor of 2 using Octaves resample() function then\r
+% uses linear interpolation to achive fractional sample rate\r
+\r
+function rx_resample_fract = fractional_resample(rx, resample_rate);\r
+ assert(resample_rate < 2, "keep resample_rate between 0 and 2");\r
+ rx_resample2 = resample(rx, 2, 1);\r
+ l = length(rx_resample2);\r
+ rx_resample_fract = zeros(1,l);\r
+ k = 1;\r
+ step = 2/resample_rate;\r
+ for i=1:step:l-1\r
+ i_low = floor(i);\r
+ i_high = ceil(i);\r
+ f = i - i_low;\r
+ rx_resample_fract(k) = (1-f)*rx_resample2(i_low) + f*rx_resample2(i_high); \r
+ %printf("i: %f i_low: %d i_high: %d f: %f\n", i, i_low, i_high, f);\r
+ k++;\r
+ end\r
+ rx_resample_fract = rx_resample_fract(1:k-1);\r
+endfunction\r
+\r
+\r
% Using simulated SSTV packet, generate complex fsk mod signals, 8-bit\r
% unsigned IQ for feeding into demod chain\r
#{\r
todo: [X] uncoded BER\r
[X] octave fsk demod\r
[X] use C demod\r
- [ ] compared unsigned 8 bit IQ to regular 16-bit\r
- + modulate complex signal\r
- + check BER\r
- + feed into csdr stack\r
+ [ ] compare uncoded BER to unsigned 8 bit IQ to regular 16-bit\r
+ [ ] generate complex rx signal with noise\r
+ [ ] used cmd line utils to drive demod\r
[ ] test with resampler\r
[ ] measure effect on PER with coding\r
#}\r
function [n_uncoded_errs n_uncoded_bits] = run_sstv_sim(sim_in, EbNodB)\r
\r
frames = sim_in.frames;\r
- c_demod = sim_in.c_demod;\r
+ demod_type = sim_in.demod_type;\r
\r
% init LDPC code\r
\r
% note fixed frame of bits used for BER testing\r
\r
tx_codeword = gen_sstv_frame;\r
-\r
+ length(tx_codeword)\r
% init FSK modem\r
\r
fsk_horus_as_a_lib = 1;\r
fsk_horus;\r
states = fsk_horus_init_hbr(9600, 8, 1200, 2, length(tx_codeword));\r
- states.ftx = [1200 2400];\r
states.df(1:states.M) = 0;\r
states.dA(1:states.M) = 1;\r
- states.tx_real = 0;\r
+ states.tx_real = 0; % Octave fsk_mod generates complex valued output\r
+\r
+ % Set up simulated tx tones to sit in teh middle of cdsr passband\r
+\r
+ filt_low_norm = 0.1; filt_high_norm = 0.4;\r
+ fc = states.Fs*(filt_low_norm + filt_high_norm)/2;\r
+ %fc = 1800;\r
+ f1 = fc - states.Rs/2\r
+ f2 = fc + states.Rs/2\r
+ states.ftx = [f1 f2];\r
\r
% set up AWGN channel \r
\r
% start simulation ----------------------------------------\r
\r
tx_bit_stream = [];\r
- for i=1:frames+1\r
+ for i=1:frames\r
tx_bit_stream = [tx_bit_stream tx_codeword];\r
end\r
\r
\r
% demodulate\r
\r
- if c_demod\r
- if states.tx_real\r
- rx = tx + noise_real;\r
- else\r
- rx = 2*real(tx) + noise_real;\r
- end\r
- SNRdB = 10*log10(var(tx)/var(noise_real));\r
- rx_scaled = 1000*real(rx);\r
- f = fopen("fsk_demod.raw","wb"); fwrite(f, rx_scaled, "short"); fclose(f);\r
- system("../build_linux/src/fsk_demod 2X 8 9600 1200 fsk_demod.raw fsk_demod.bin");\r
- f = fopen("fsk_demod.bin","rb"); rx_bit_stream = fread(f, "uint8")'; fclose(f);\r
- else\r
+ if demod_type == 1\r
+\r
+ % Octave demod\r
+\r
if states.tx_real\r
rx = tx + noise_real;\r
else\r
\r
% demodulate to stream of bits\r
\r
- states.f = [1200 2400];\r
+ states.f = [f1 f2];\r
[rx_bits states] = fsk_horus_demod(states, sf);\r
rx_bit_stream = [rx_bit_stream rx_bits];\r
rx_sd_stream = [rx_sd_stream states.rx_bits_sd];\r
end\r
end\r
\r
- % state machine. Look for SSTV UW. When found count bit errors over one frame of bits\r
+ if demod_type == 2\r
+ % baseline C demod\r
+\r
+ if states.tx_real\r
+ rx = tx + noise_real;\r
+ else\r
+ rx = 2*real(tx) + noise_real;\r
+ end\r
+ SNRdB = 10*log10(var(tx)/var(noise_real));\r
+ rx_scaled = 1000*real(rx);\r
+ f = fopen("fsk_demod.raw","wb"); fwrite(f, rx_scaled, "short"); fclose(f);\r
+ system("../build_linux/src/fsk_demod 2X 8 9600 1200 fsk_demod.raw fsk_demod.bin");\r
+ f = fopen("fsk_demod.bin","rb"); rx_bit_stream = fread(f, "uint8")'; fclose(f);\r
+ end\r
+\r
+ if demod_type == 3\r
+ % C demod driven by command line kung fu\r
+\r
+ assert(states.tx_real == 0, "need complex signal for this test");\r
+ rx = tx + noise_complex;\r
+ SNRdB = 10*log10(var(tx)/var(noise_real));\r
+ save_rtlsdr("fsk_demod.iq", rx);\r
+ system("cat fsk_demod.iq | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr realpart_cf | csdr convert_f_s16 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - fsk_demod.bin");\r
+ f = fopen("fsk_demod.bin","rb"); rx_bit_stream = fread(f, "uint8")'; fclose(f);\r
+ end\r
+\r
+ if demod_type == 4\r
+ % C demod with resampler ....... getting closer to Mark's real time cmd line\r
+\r
+ assert(states.tx_real == 0, "need complex signal for this test");\r
+ rx = tx + noise_complex;\r
+ SNRdB = 10*log10(var(tx)/var(noise_real));\r
+ \r
+ % interpolate by factor or 2, then use straight line interpolation\r
+\r
+ printf("resampling ...\n");\r
+ rx_resample_fract = fractional_resample(rx, 1.08331);\r
+ %rx_resample_fract = fractional_resample(rx_resample_fract, 1/1.08331);\r
+ save_rtlsdr("fsk_demod_resample.iq", rx_resample_fract);\r
+\r
+ printf("run C cmd line chain ...\n");\r
+% system("cat fsk_demod_resample.iq | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr realpart_cf | csdr convert_f_s16 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - fsk_demod.bin");\r
+ system("cat fsk_demod_resample.iq | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr realpart_cf | csdr convert_f_s16 | ../unittest/tsrc - - 0.9230968 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - fsk_demod.bin");\r
+% system("cat fsk_demod_resample.iq | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr fractional_decimator_ff 1.08331 | csdr realpart_cf | csdr convert_f_s16 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - fsk_demod.bin");\r
+ f = fopen("fsk_demod.bin","rb"); rx_bit_stream = fread(f, "uint8")'; fclose(f);\r
+ end\r
+\r
+ % state machine. Look for SSTV UW. When found count bit errors over one frame of bits\r
\r
state = "wait for uw";\r
- start_uw_ind = 16*10+1; end_uw_ind = start_uw_ind + 2*10 - 1;\r
+ start_uw_ind = 16*10+1; end_uw_ind = start_uw_ind + 5*10 - 1;\r
uw_rs232 = tx_codeword(start_uw_ind:end_uw_ind); luw = length(uw_rs232);\r
start_frame_ind = end_uw_ind + 1;\r
nbits = length(rx_bit_stream);\r
- uw_thresh = 0;\r
+ uw_thresh = 5;\r
n_uncoded_errs = 0;\r
n_uncoded_bits = 0;\r
+ n_packets_rx = 0;\r
+ last_i = 0;\r
\r
% might as well include RS232 framing bits in uncoded error count\r
\r
nbits_frame = code_param.data_bits_per_frame*10/8; \r
\r
+ uw_errs = zeros(1, nbits);\r
+ for i=luw:nbits\r
+ uw_errs(i) = sum(xor(rx_bit_stream(i-luw+1:i), uw_rs232));\r
+ end\r
+\r
for i=luw:nbits\r
next_state = state;\r
if strcmp(state, 'wait for uw')\r
- uw_errs = xor(rx_bit_stream(i-luw+1:i), uw_rs232);\r
- if uw_errs <= uw_thresh\r
+ if uw_errs(i) <= uw_thresh\r
next_state = 'count errors';\r
tx_frame_ind = start_frame_ind;\r
rx_frame_ind = i + 1;\r
n_uncoded_errs_this_frame = 0;\r
%printf("%d %s %s\n", i, state, next_state);\r
+ if last_i\r
+ printf("i: %d i-last_i: %d ", i, i-last_i);\r
+ end\r
end\r
end\r
if strcmp(state, 'count errors')\r
%tx_codeword(start_frame_ind+1:start_frame_ind+10)\r
%frame_rx232_rx(1:10)\r
sstv_checksum(frame_rx232_rx);\r
+ last_i = i;\r
+ n_packets_rx++;\r
next_state = 'wait for uw';\r
end\r
end\r
end\r
\r
uncoded_ber = n_uncoded_errs/n_uncoded_bits;\r
- printf("EbNodB: %4.1f SNRdB: %4.1f n_uncoded_bits: %d n_uncoded_errs: %d BER: %4.3f\n", \r
- EbNodB, SNRdB, n_uncoded_bits, n_uncoded_errs, uncoded_ber); \r
+ printf("EbNodB: %4.1f SNRdB: %4.1f pkts: %d bits: %d errs: %d BER: %4.3f\n", \r
+ EbNodB, SNRdB, n_packets_rx, n_uncoded_bits, n_uncoded_errs, uncoded_ber); \r
+\r
+ figure(2);\r
+ plot(uw_errs);\r
+\r
endfunction\r
\r
% Start simulation --------------------------------------------------------\r
\r
\r
if demo == 10\r
- sim_in.frames = 3;\r
- EbNodBvec = 9;\r
- \r
- sim_in.c_demod = 0;\r
+ sim_in.frames = 100;\r
+ EbNodBvec = 7;\r
+\r
+ sim_in.demod_type = 4;\r
ber_octave = [];\r
for i = 1:length(EbNodBvec)\r
[n_uncoded_errs n_uncoded_bits] = run_sstv_sim(sim_in, EbNodBvec(i));\r
ber_octave(i) = n_uncoded_errs/n_uncoded_bits;\r
end\r
-\r
- sim_in.c_demod = 1;\r
+ #{\r
+ sim_in.demod_type = 4;\r
ber_c = [];\r
for i = 1:length(EbNodBvec)\r
[n_uncoded_errs n_uncoded_bits] = run_sstv_sim(sim_in, EbNodBvec(i));\r
\r
figure(1);\r
clf;\r
- semilogy(EbNodBvec, ber_octave, '+-;Octave demod;')\r
+ semilogy(EbNodBvec, ber_octave, '+-;first test;')\r
grid;\r
xlabel('Eb/No (dB)')\r
ylabel('BER')\r
\r
hold on;\r
- semilogy(EbNodBvec, ber_c, 'g+-;C demod;')\r
+ semilogy(EbNodBvec, ber_c, 'g+-;second test;')\r
legend("boxoff");\r
hold off;\r
+ #}\r
end\r
\r