--- /dev/null
+% ldpcdec.m\r
+% David Rowe 31 Dec 2013\r
+% \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
+\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
+\r
+% Start simulation\r
+\r
+rand('state',1);\r
+\r
+rate = 3/4; \r
+framesize = 576; \r
+\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
+\r
+vocoderframesize = 52;\r
+nvocoderframes = 8;\r
+nbitspermodemframe = 72;\r
+\r
+code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);\r
+code_param.code_bits_per_frame = 576;\r
+\r
+data = [];\r
+r = []; \r
+\r
+% Encoder: Generate simulated vocoder data, insert UW, and LPDC encode ---------------\r
+\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
+\r
+vd = round( rand( 1, vocoderframesize*nvocoderframes) );\r
+\r
+% Decoder: Sync with LDPC frames, LDPC decode, strip off UW, measure BER -------\r
+\r
+fm=fopen("modcodeword.bin","rb");\r
+\r
+mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw));\r
+\r
+mod_codeword = zeros(1, code_param.code_bits_per_frame/2);\r
+lmod_codeword = code_param.code_bits_per_frame/2;\r
+\r
+Terrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = [];\r
+corr = []; n = 0;\r
+sync_state = 0; sync_count = 0;\r
+\r
+[mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32");\r
+while (count == nbitspermodemframe)\r
+ n++;\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