% then switch to a more robust tracking algorithm. If we lose sync we switch
% back to acquire mode for fast-requisition.
-function [track state bad_sync] = freq_state(sync_bit, state, bad_sync)
+function [entered_track track state bad_sync] = freq_state(sync_bit, state, bad_sync)
+
+ entered_track = 0;
% acquire state, look for 6 symbol 010101 sequence from sync bit
end
if state == 5
if sync_bit == 1
+ entered_track = 1;
next_state = 6;
bad_sync = 0;
else
track = 0;
fest_state = 0;
bad_sync = 0;
+ sync_track = 0;
+ entered_track_log = [];
% spectrum states
[foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin);
if track == 0
- foff = foff_coarse;
+ foff = foff_coarse = 0;
end
foff_log = [ foff_log foff ];
foff_rect = exp(j*2*pi*foff/Fs);
% optionally save output symbols
- if (nargin == 5) && (track == 1)
- if sync == 1
+ if (nargin == 5)
+
+ % this free runs, and is reset by an "entered sync" state
+
+ if (sync_track == 0)
+ sync_track = 1;
+ else
+ sync_track = 0;
+ end
+
+ if (track == 1) && (sync_track == 1)
dual_rx_symbols(Nc+1:2*Nc) = rx_symbols(1:Nc).*conj(prev_rx_symbols(1:Nc)./abs(prev_rx_symbols(1:Nc)));
dual_rx_symbols_float32 = []; k = 1;
for i=1:2*Nc
end
fwrite(fm, dual_rx_symbols_float32, "float32");
dual_rx_bits(Nc*Nb+1:2*Nc*Nb) = rx_bits;
- dump_bits(dual_rx_bits);
+ %dump_bits(dual_rx_bits);
else
dual_rx_symbols(1:Nc) = rx_symbols(1:Nc).*conj(prev_rx_symbols(1:Nc)./abs(prev_rx_symbols(1:Nc)));
dual_rx_bits(1:Nc*Nb) = rx_bits;
% freq est state machine
- [track fest_state bad_sync] = freq_state(sync, fest_state, bad_sync);
+ [entered_track track fest_state bad_sync] = freq_state(sync, fest_state, bad_sync);
track_log = [track_log track];
+ if (entered_track == 1)
+ sync_track = 1;
+ end
+ entered_track_log = [entered_track_log entered_track];
% count bit errors if we find a test frame
test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
end
+ if nargin == 5
+ fclose(fm);
+ etfilename = strcat(strtok(symbolfilename,"."),"_et.bin");
+ fet = fopen(etfilename, "wb");
+ fwrite(fet, entered_track_log, "short");
+ fclose(fet);
+ end
+
% ---------------------------------------------------------------------
% Print Stats
% ---------------------------------------------------------------------
% ldpc.m\r
-% ldpc functions\r
-\r
-% LDPC demo; Bill Cowley \r
-% Call the CML routines and simulate one set of SNRs. See test_ldpc1.m\r
-%\r
-% sim_in the input parameter structure\r
-% sim_out contains BERs and other stats for each value of SNR\r
-% resfile is the result file\r
-%\r
-% 4/oct/2013: edited to use the WiMax eIRA codes \r
-% see 'help InitializeWiMaxLDPC' for parameter values \r
+% LDPC functions\r
\r
1;\r
\r
spacing = 2*lframein/luw;\r
\r
frameout = [];\r
- mod_uw = [];\r
\r
pin = 1; pout = 1; puw = 1;\r
while (luw)\r
pin += spacing; \r
pout += spacing;\r
frameout(pout:pout+1) = uw(puw:puw+1);\r
- mod_uw(pout:pout+1) = qpsk_mod(uw(puw:puw+1));\r
puw += 2;\r
pout += 2;\r
luw -= 2;\r
endfunction\r
\r
\r
+% removes a unique word from a frame of symbols. The UW symbols are spread\r
+% throughout the input frame 1 symbol at a time.\r
+\r
+function framesymbolsout = remove_uw_symbols(framesymbolsin, ldatasymbols, luwsymbols)\r
+\r
+ spacing = ldatasymbols/luwsymbols;\r
+\r
+ framesymbolsout = [];\r
+\r
+ pin = 1; pout = 1;\r
+ while (luwsymbols)\r
+ %printf("pin %d pout %d luw %d ", pin, pout, luwsymbols);\r
+ %printf("pin+spacing-1 %d ldatasymbols %d lframein: %d\n", pin+spacing-1, ldatasymbols, length(framesymbolsin));\r
+ framesymbolsout(pout:pout+spacing-1) = framesymbolsin(pin:pin+spacing-1);\r
+ pin += spacing + 1; \r
+ pout += spacing;\r
+ luwsymbols--;\r
+ end\r
+\r
+endfunction\r
+\r
+\r
+\r
% builds up a sparse QPSK modulated version version of the UW for use\r
% in UW sync at the rx\r
\r
end\r
endfunction\r
\r
+\r
+% symbol interleaver that acts on bits 2 at a time\r
+\r
+function y = interleave_bits(interleaver, x)\r
+ y = zeros(1,length(x));\r
+ for i = 1:length(interleaver)\r
+ dst = interleaver(i);\r
+ y(2*(dst-1)+1:2*dst) = x(2*(i-1)+1:2*(i));\r
+ end\r
+endfunction\r
+\r
+% symbol de-interleaver\r
+\r
+function x = deinterleave_symbols(interleaver, y)\r
+ for i = 1:length(interleaver)\r
+ x(i) = y(interleaver(i));\r
+ end\r
+endfunction\r
% LDPC decoder test program, given a file of QPSK symbols (IQIQ floats), \r
% performs frame sync, decodes, and measures BER.\r
\r
-% Start CML library\r
+function ldpcdec(filename)\r
\r
-currentdir = pwd;\r
-addpath '/home/david/tmp/cml/mat' % assume the source files stored here\r
-cd /home/david/tmp/cml\r
-CmlStartup % note that this is not in the cml path!\r
-cd(currentdir)\r
+ % Start CML library\r
\r
-% Our LDPC library\r
+ currentdir = pwd;\r
+ addpath '/home/david/tmp/cml/mat' % assume the source files stored here\r
+ cd /home/david/tmp/cml\r
+ CmlStartup % note that this is not in the cml path!\r
+ cd(currentdir)\r
\r
-ldpc;\r
+ % Our LDPC library\r
\r
-% Start simulation\r
+ ldpc;\r
\r
-rand('state',1);\r
+ % Start simulation\r
\r
-rate = 3/4; \r
-framesize = 576; \r
+ rand('state',1);\r
\r
-mod_order = 4; \r
-modulation = 'QPSK';\r
-mapping = 'gray';\r
+ rate = 3/4; \r
+ framesize = 576; \r
\r
-demod_type = 0;\r
-decoder_type = 0;\r
-max_iterations = 100;\r
-EsNo = 10;\r
-Eprob = 0.0;\r
+ mod_order = 4; \r
+ modulation = 'QPSK';\r
+ mapping = 'gray';\r
\r
-vocoderframesize = 52;\r
-nvocoderframes = 8;\r
-nbitspermodemframe = 72;\r
+ demod_type = 0;\r
+ decoder_type = 0;\r
+ max_iterations = 100;\r
+ EsNo = 4;\r
+ Eprob = 0.0;\r
\r
-code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);\r
-code_param.code_bits_per_frame = 576;\r
+ nbitspervocoderframe = 52;\r
+ nvocoderframes = 8;\r
+ nbitspermodemframe = 72;\r
\r
-data = [];\r
-r = []; \r
+ code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);\r
+ code_param.code_bits_per_frame = 576;\r
\r
-Nframes = 100;\r
-uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];\r
+ data = [];\r
+ r = []; \r
+ load interleaver.txt\r
+ interleaver = interleaver + 1;\r
\r
-% repeat same simulated vocoder data to ease testing\r
+ Nframes = 100;\r
+ uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];\r
\r
-vd = round( rand( 1, vocoderframesize*nvocoderframes) );\r
+ % repeat same simulated vocoder data to ease testing\r
\r
-% Decoder: Sync with LDPC frames, LDPC decode, strip off UW, measure BER -------\r
+ vd = round( rand( 1, nbitspervocoderframe*nvocoderframes) );\r
\r
-fm=fopen("modcodeword.bin","rb");\r
+ % Decoder: Sync with LDPC frames, de-interleave, LDPC decode, strip off UW, measure BER -------\r
\r
-mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw));\r
+ mcwfilename = strcat(filename,"_modcodeword.bin");\r
+ fm=fopen(mcwfilename,"rb");\r
+ etfilename = strcat(filename,"_et.bin");\r
+ fet=fopen(etfilename ,"rb");\r
+ epfilename = strcat(filename,".err");\r
+ fep=fopen(epfilename ,"wb");\r
+ printf("Input QPSK symbols: %s\n", mcwfilename);\r
+ if (fet == -1)\r
+ printf("Input entered track file: none\n");\r
+ else\r
+ printf("Input entered track file: %s\n", etfilename);\r
+ end\r
+ printf("Output error pattern file: %s\n", epfilename);\r
\r
-mod_codeword = zeros(1, code_param.code_bits_per_frame/2);\r
-lmod_codeword = code_param.code_bits_per_frame/2;\r
+ mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw));\r
\r
-Terrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = [];\r
-corr = []; n = 0;\r
-sync_state = 0; sync_count = 0;\r
-mod_unpackedmodem_log = [];\r
+ mod_codeword = zeros(1, code_param.code_bits_per_frame/2);\r
+ lmod_codeword = code_param.code_bits_per_frame/2;\r
\r
-[mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32");\r
-while (count == nbitspermodemframe)\r
- n++;\r
+ Terrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = [];\r
+ corr = []; n = 0;\r
+ sync_state = 0; sync_count = 0;\r
+ mod_unpackedmodem_log = [];\r
+ sync_state_log = [];\r
+ entered_track_log = [];\r
\r
- mod_unpackedmodem = mod_unpackedmodem_float32(1:2:nbitspermodemframe) + j*mod_unpackedmodem_float32(2:2:nbitspermodemframe);\r
- mod_unpackedmodem_log = [mod_unpackedmodem_log mod_unpackedmodem];\r
- erasures = rand(1,length(mod_unpackedmodem)) < Eprob; \r
- mod_unpackedmodem(erasures) = 0;\r
+ [mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32");\r
+ if (fet == -1)\r
+ entered_track = 0;\r
+ else\r
+ entered_track = fread(fet, 1, "int");\r
+ end\r
\r
- % keep buffer of one entire codeword\r
+ while (count == nbitspermodemframe)\r
+ n++;\r
\r
- mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword);\r
- mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem;\r
+ mod_unpackedmodem = mod_unpackedmodem_float32(1:2:nbitspermodemframe) + j*mod_unpackedmodem_float32(2:2:nbitspermodemframe);\r
+ mod_unpackedmodem_log = [mod_unpackedmodem_log mod_unpackedmodem];\r
+ erasures = rand(1,length(mod_unpackedmodem)) < Eprob; \r
+ mod_unpackedmodem(erasures) = 0;\r
\r
- [uw_sync corr(n)] = look_for_uw(mod_codeword(1:length(mod_uw)), mod_uw);\r
- if (uw_sync)\r
- sync_state = 1;\r
- end\r
+ % keep buffer of one entire codeword\r
\r
- if (sync_state && (sync_count == 0))\r
- Tframes++;\r
+ mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword);\r
+ mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem;\r
\r
- % force UW symbols as they are known (is this needed?)\r
+ [uw_sync corr(n)] = look_for_uw(mod_codeword(1:length(mod_uw)), mod_uw);\r
\r
- % LDPC decode\r
+ next_sync_state = sync_state;\r
+ if ((sync_state == 0) && (uw_sync == 1))\r
+ next_sync_state = 1;\r
+ sync_count = 0;\r
+ end\r
+ if ((sync_state == 1) && (entered_track != 0))\r
+ next_sync_state = 0;\r
+ end\r
+ sync_state = next_sync_state;\r
+ sync_state_log = [sync_state_log sync_state];\r
+ entered_track_log = [entered_track_log entered_track];\r
\r
- detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, mod_codeword, EsNo);\r
-\r
- % unpack payload data, removing UW\r
-\r
- vd_rx = remove_uw(detected_data(1:code_param.data_bits_per_frame), length(vd), length(uw));\r
-\r
- % measure BER\r
-\r
- error_positions = xor(vd, vd_rx);\r
- Nerrs = sum(error_positions);\r
- if Nerrs>0, fprintf(1,'x'); Ferrs++; , else fprintf(1,'.'), end\r
- Tbits += length(vd);\r
- Terrs += Nerrs;\r
- nerr(Tframes) = Nerrs;\r
-\r
- % save packed payload data to disk\r
- end\r
-\r
- if (sync_state)\r
- sync_count++;\r
- if (sync_count == 8)\r
- sync_count = 0;\r
- end\r
- end\r
-\r
- % read in one modulated modem frame at a time\r
-\r
- [mod_unpackedmodem_float32, count] = fread(fm, nbitspermodemframe, "float32");\r
-end\r
-\r
-fprintf(1,"\nFrames: %d bits: %d errors: %d BER = %f FER = %f\n", Tframes, Tbits, Terrs, Terrs/Tbits, Ferrs/Tframes);\r
-%subplot(211)\r
-%plot(corr);\r
-%subplot(212)\r
-%plot(nerr);\r
-figure(1)\r
-clf;\r
-[n m] = size(mod_unpackedmodem_log);\r
-plot( real(mod_unpackedmodem_log), imag(mod_unpackedmodem_log), '+')\r
-axis([-2 2 -2 2]);\r
-title('Scatter Diagram');\r
+ if (sync_state && (sync_count == 0))\r
+ Tframes++;\r
+\r
+ % remove UW symbols\r
+\r
+ mod_codeword_no_uw = remove_uw_symbols(mod_codeword, code_param.data_bits_per_frame/2 - length(uw)/2, length(uw)/2);\r
+ mod_codeword_no_uw = [mod_codeword_no_uw mod_codeword((code_param.data_bits_per_frame/2+1):code_param.code_bits_per_frame/2)];\r
+\r
+ % de-interleave\r
+\r
+ tmp = deinterleave_symbols(interleaver, mod_codeword_no_uw);\r
+ \r
+ % insert known symbols at end of data\r
+\r
+ mod_codeword_deinter = [ tmp(1:(code_param.data_bits_per_frame/2 - length(uw)/2)) ...\r
+ ones(1,length(uw)/2) * qpsk_mod([0 0]) ...\r
+ tmp((code_param.data_bits_per_frame/2 - length(uw)/2+1):length(tmp)) ];\r
+ \r
+ % LDPC decode\r
+\r
+ detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, mod_codeword_deinter, EsNo);\r
+\r
+ % unpack payload data, removing UW\r
+\r
+ vd_rx = detected_data(1:(code_param.data_bits_per_frame - length(uw)));\r
+\r
+ % measure BER\r
+\r
+ error_positions = xor(vd, vd_rx);\r
+ Nerrs = sum(error_positions);\r
+ if Nerrs>0, fprintf(1,'x'); Ferrs++; , else fprintf(1,'.'), end\r
+ Tbits += length(vd);\r
+ Terrs += Nerrs;\r
+ nerr(Tframes) = Nerrs;\r
+\r
+ % save error patterns is simulated vocoder data to disk\r
+\r
+ fwrite(fep, error_positions, "short");\r
+ \r
+ end\r
+\r
+ if (sync_state)\r
+ sync_count++;\r
+ if (sync_count == 8)\r
+ sync_count = 0;\r
+ end\r
+ end\r
+\r
+ % read in one modulated modem frame at a time\r
+\r
+ [mod_unpackedmodem_float32, count] = fread(fm, nbitspermodemframe, "float32");\r
+ if (fet == -1)\r
+ entered_track = 0;\r
+ else\r
+ entered_track = fread(fet, 1, "int");\r
+ end\r
+ end\r
+\r
+ fclose(fep);\r
+\r
+ fprintf(1,"\nFrames: %d bits: %d errors: %d BER = %f FER = %f\n", Tframes, Tbits, Terrs, Terrs/Tbits, Ferrs/Tframes);\r
+\r
+ figure(8)\r
+ clf;\r
+ [n m] = size(mod_unpackedmodem_log);\r
+ plot( real(mod_unpackedmodem_log), imag(mod_unpackedmodem_log), '+')\r
+ axis([-2 2 -2 2]);\r
+ title('Scatter Diagram');\r
+\r
+ figure(9)\r
+ subplot(311)\r
+ plot(sync_state_log);\r
+ subplot(312)\r
+ plot(entered_track_log);\r
+ subplot(313)\r
+ plot(nerr);\r
+endfunction\r
% ldpcenc.m\r
% David Rowe 20 Dec 2013\r
% \r
-% LDPC encoder test program. Encodes and modulates a random data stream \r
+% LDPC encoder function. Takes a random data pattern, LDPC Encodes and\r
+% inserts Unique Word (UW) sync bits and ouputs this as a packed\r
+% binary file suitable for the Nc=18 carrier FDMDV modulator,\r
+% fdmdv_mod. Also produces a "modulated" output file of QPSK\r
+% symbols, suitable for feeding into ldpcdec for testing.\r
\r
-% Start CML library\r
+function ldpcenc(filename)\r
\r
-currentdir = pwd;\r
-addpath '/home/david/tmp/cml/mat' % assume the source files stored here\r
-cd /home/david/tmp/cml\r
-CmlStartup % note that this is not in the cml path!\r
-cd(currentdir)\r
+ % Start CML library\r
\r
-% Our LDPC library\r
+ currentdir = pwd;\r
+ addpath '/home/david/tmp/cml/mat' % assume the source files stored here\r
+ cd /home/david/tmp/cml\r
+ CmlStartup % note that this is not in the cml path!\r
+ cd(currentdir)\r
+ \r
+ % Our LDPC library\r
\r
-ldpc;\r
+ ldpc;\r
\r
-% Start simulation\r
+ % Start simulation\r
\r
-rand('state',1);\r
+ rand('state',1);\r
\r
-rate = 3/4; \r
-framesize = 576; \r
+ rate = 3/4; \r
+ framesize = 576; \r
\r
-mod_order = 4; \r
-modulation = 'QPSK';\r
-mapping = 'gray';\r
+ mod_order = 4; \r
+ modulation = 'QPSK';\r
+ mapping = 'gray';\r
\r
-demod_type = 0;\r
-decoder_type = 0;\r
-max_iterations = 100;\r
-EsNo = 10;\r
-Eprob = 0.15;\r
+ demod_type = 0;\r
+ decoder_type = 0;\r
+ max_iterations = 100;\r
\r
-vocoderframesize = 52;\r
-nvocoderframes = 8;\r
-nbitspermodemframe = 72;\r
+ nbitspervocoderframe = 52;\r
+ nvocoderframes = 8;\r
+ nbitspermodemframe = 72;\r
\r
-code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);\r
+ code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);\r
\r
-data = [];\r
-r = []; \r
+ data = [];\r
+ r = []; \r
+ load interleaver.txt\r
+ interleaver = interleaver + 1;\r
\r
-% Encoder: Generate simulated vocoder data, insert UW, and LPDC encode ---------------\r
+ % Encoder: Generate simulated vocoder data\r
+ % LPDC encode\r
+ % interleave \r
+ % insert UW bits\r
\r
-Nframes = 100;\r
-uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];\r
+ Nframes = 100;\r
+ uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];\r
\r
-% repeat same simulated vocoder data to ease testing\r
+ % repeat same simulated vocoder data to ease testing\r
\r
-vd = round( rand( 1, vocoderframesize*nvocoderframes) );\r
-d = insert_uw(vd, uw);\r
+ vd = round( rand( 1, nbitspervocoderframe*nvocoderframes) );\r
\r
-data = [data d];\r
-[codeword, s] = ldpc_enc(d, code_param);\r
-code_param.code_bits_per_frame = length(codeword);\r
-code_param.symbols_per_frame = length(s);\r
-packedcodeword = packmsb(codeword);\r
+ % pad data with zeros the size of UW\r
\r
-fc=fopen("codeword.bin","wb");\r
-for nn = 1: Nframes \r
- fwrite(fc,packedcodeword,"uchar");\r
-end\r
-fclose(fc);\r
+ vdpad = [vd zeros(1, length(uw))];\r
\r
-%printf("framesize: %d data_bits_per_frame: %d code_bits_per_frame: %d\n", ...\r
-% framesize, code_param.data_bits_per_frame, code_param.code_bits_per_frame);\r
+ % LDPC encode\r
\r
-printf("Encoded %d LDPC frames\n", Nframes);\r
+ [codewordpad, s] = ldpc_enc(vdpad, code_param);\r
+ code_param.code_bits_per_frame = length(codewordpad);\r
+ code_param.symbols_per_frame = length(s);\r
\r
-% Modulator: Modulate to QPSK symbols ------------------------------------------\r
+ % remove padded zeros after encoding to leave room for UW bits (code\r
+ % is systematic)\r
\r
-lpackedcodeword=length(packedcodeword);\r
-fc=fopen("codeword.bin","rb");\r
-fm=fopen("modcodeword.bin","wb");\r
-lpackedmodem = nbitspermodemframe/8;\r
-n = 0;\r
+ codeword = [ codewordpad(1:length(vd)) codewordpad((length(vd)+length(uw)+1):length(codewordpad)) ];\r
\r
-[packedmodem, count] = fread(fc,lpackedmodem,"uchar");\r
-while (count == lpackedmodem)\r
- n++;\r
- unpackedmodem = unpackmsb(packedmodem);\r
+ % interleave, insert UW bits, and pack bits (as C modulator likes packed bits)\r
\r
- ii = 1;\r
- for i=1:2:length(unpackedmodem)\r
- mod_unpackedmodem(ii) = qpsk_mod(unpackedmodem(i:i+1));\r
- mod_unpackedmodem_float32(i) = real(mod_unpackedmodem(ii));\r
- mod_unpackedmodem_float32(i+1) = imag(mod_unpackedmodem(ii));\r
- ii += 1;\r
- end\r
+ codeword_interleaved = interleave_bits(interleaver, codeword);\r
+ codeword_interleaved_uw = [insert_uw(codeword_interleaved(1:length(vd)), uw) codeword_interleaved(length(vd)+1:length(codeword_interleaved)) ];\r
+ packedcodeword = packmsb(codeword_interleaved_uw);\r
\r
- fwrite(fm, mod_unpackedmodem_float32, "float32");\r
- [packedmodem, count] = fread(fc,lpackedmodem,"uchar");\r
-end\r
-fclose(fc);\r
-fclose(fm);\r
-printf("Modulated %d modem frames\n", n);\r
+ cwfilename = strcat(filename,"_codeword.bin");\r
+ fc=fopen(cwfilename,"wb");\r
+ for nn = 1: Nframes \r
+ fwrite(fc,packedcodeword,"uchar");\r
+ end\r
+ fclose(fc);\r
\r
+ %printf("framesize: %d data_bits_per_frame: %d code_bits_per_frame: %d\n", ...\r
+ % framesize, code_param.data_bits_per_frame, code_param.code_bits_per_frame);\r
\r
-% Decoder: Sync with LDPC frames, LDPC decode, strip off UW, measure BER -------\r
+ printf("Encoded %d LDPC codewords, saved in packed file: %s\n", Nframes, cwfilename);\r
\r
-fm=fopen("modcodeword.bin","rb");\r
+ % Modulator: Modulate to QPSK symbols ------------------------------------------\r
\r
-mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw));\r
+ nbytespackedcodeword=length(packedcodeword);\r
+ fc=fopen(cwfilename,"rb");\r
+ mcwfilename = strcat(filename,"_modcodeword.bin");\r
+ fm=fopen(mcwfilename,"wb");\r
+ nbytespackedmodemframe = nbitspermodemframe/8;\r
+ n = 0;\r
\r
-mod_codeword = zeros(1, code_param.code_bits_per_frame/2);\r
-lmod_codeword = code_param.code_bits_per_frame/2;\r
+ [packedmodem, count] = fread(fc,nbytespackedmodemframe,"uchar");\r
+ while (count == nbytespackedmodemframe)\r
+ n++;\r
+ unpackedmodem = unpackmsb(packedmodem);\r
\r
-Terrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = [];\r
-corr = []; n = 0;\r
-sync_state = 0; sync_count = 0;\r
+ ii = 1;\r
+ for i=1:2:length(unpackedmodem)\r
+ mod_unpackedmodem(ii) = qpsk_mod(unpackedmodem(i:i+1));\r
+ mod_unpackedmodem_float32(i) = real(mod_unpackedmodem(ii));\r
+ mod_unpackedmodem_float32(i+1) = imag(mod_unpackedmodem(ii));\r
+ ii += 1;\r
+ end\r
\r
-[mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32");\r
-while (count == nbitspermodemframe)\r
- n++;\r
+ fwrite(fm, mod_unpackedmodem_float32, "float32");\r
+ [packedmodem, count] = fread(fc,nbytespackedmodemframe,"uchar");\r
+ end\r
+ fclose(fc);\r
+ fclose(fm);\r
+ printf("Modulated %d modem frames to file: %s\n", n, mcwfilename);\r
+endfunction\r
\r
- mod_unpackedmodem = mod_unpackedmodem_float32(1:2:nbitspermodemframe) + j*mod_unpackedmodem_float32(2:2:nbitspermodemframe);\r
- erasures = rand(1,length(mod_unpackedmodem)) < Eprob; \r
- mod_unpackedmodem(erasures) = 0;\r
\r
- % keep buffer of one entire codeword\r
-\r
- mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword);\r
- mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem;\r
-\r
- [uw_sync corr(n)] = look_for_uw(mod_codeword(1:length(mod_uw)), mod_uw);\r
- if (uw_sync)\r
- sync_state = 1;\r
- end\r
-\r
- if (sync_state && (sync_count == 0))\r
- Tframes++;\r
-\r
- % force UW symbols as they are known (is this needed?)\r
-\r
- % LDPC decode\r
-\r
- detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, mod_codeword, EsNo);\r
-\r
- % unpack payload data, removing UW\r
-\r
- vd_rx = remove_uw(detected_data(1:code_param.data_bits_per_frame), length(vd), length(uw));\r
-\r
- % measure BER\r
-\r
- error_positions = xor(vd, vd_rx);\r
- Nerrs = sum(error_positions);\r
- if Nerrs>0, fprintf(1,'x'); Ferrs++; , else fprintf(1,'.'), end\r
- Tbits += length(vd);\r
- Terrs += Nerrs;\r
- nerr(Tframes) = Nerrs;\r
-\r
- % save packed payload data to disk\r
- end\r
-\r
- if (sync_state)\r
- sync_count++;\r
- if (sync_count == 8)\r
- sync_count = 0;\r
- end\r
- end\r
-\r
- % read in one modulated modem frame at a time\r
-\r
- [mod_unpackedmodem_float32, count] = fread(fm, nbitspermodemframe, "float32");\r
-end\r
-\r
-fprintf(1,"\nFrames: %d bits: %d errors: %d BER = %f FER = %f\n", Tframes, Tbits, Terrs, Terrs/Tbits, Ferrs/Tframes);\r
-subplot(211)\r
-plot(corr);\r
-subplot(212)\r
-plot(nerr);\r
% This program is distributed under the terms of the GNU General Public License
% Version 2
-function pl2(samname1, samname2, start_sam, end_sam, pngname)
+function pl2(samname1, samname2, start_sam, end_sam, offset)
fs1=fopen(samname1,"rb");
s1=fread(fs1,Inf,"short");
fs2=fopen(samname2,"rb");
s2=fread(fs2,Inf,"short");
- st = 1;
- en = length(s1);
+ st1 = st2 = 1;
+ en1 = en2 = length(s1);
if (nargin >= 3)
- st = start_sam;
+ st1 = st2 = start_sam;
endif
if (nargin >= 4)
- en = end_sam;
+ en1 = en2 = end_sam;
+ endif
+
+ if (nargin == 5)
+ st2 += offset
+ en2 += offset
endif
figure(1);
clf;
subplot(211);
l1 = strcat("r;",samname1,";");
- plot(s1(st:en), l1);
- axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
+ plot(s1(st1:en1), l1);
+ axis([1 en1-st1 min(s1(st1:en1)) max(s1(st1:en1))]);
subplot(212);
l2 = strcat("r;",samname2,";");
- plot(s2(st:en),l2);
- axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
+ plot(s2(st2:en2),l2);
+ axis([1 en2-st2 min(s1(st2:en2)) max(s1(st2:en2))]);
figure(2)
- plot(s1(st:en)-s2(st:en));
- max(s1(st:en)-s2(st:en))
+ plot(s1(st1:en1)-s2(st2:en2));
- if (nargin == 5)
-
- % small image
-
- __gnuplot_set__ terminal png size 420,300
- s = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
- eval(s)
- replot;
-
- % larger image
-
- __gnuplot_set__ terminal png size 800,600
- s = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
- eval(s)
- replot;
-
- endif
endfunction