From: drowe67 Date: Thu, 30 Jan 2014 04:28:56 +0000 (+0000) Subject: ldpc simulation working, but perf not that great in ccir poor 4dB channel X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=da899ae006db1b9745594fe78e3e84613b5ebb77;p=freetel-svn-tracking.git ldpc simulation working, but perf not that great in ccir poor 4dB channel git-svn-id: https://svn.code.sf.net/p/freetel/code@1394 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/fdmdv.m b/codec2-dev/octave/fdmdv.m index a0b9b6a5..f64fe895 100644 --- a/codec2-dev/octave/fdmdv.m +++ b/codec2-dev/octave/fdmdv.m @@ -805,7 +805,9 @@ endfunction % 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 @@ -845,6 +847,7 @@ function [track state bad_sync] = freq_state(sync_bit, state, bad_sync) end if state == 5 if sync_bit == 1 + entered_track = 1; next_state = 6; bad_sync = 0; else diff --git a/codec2-dev/octave/fdmdv_demod.m b/codec2-dev/octave/fdmdv_demod.m index 2fe42702..dc553127 100644 --- a/codec2-dev/octave/fdmdv_demod.m +++ b/codec2-dev/octave/fdmdv_demod.m @@ -52,6 +52,8 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb track = 0; fest_state = 0; bad_sync = 0; + sync_track = 0; + entered_track_log = []; % spectrum states @@ -93,7 +95,7 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb [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); @@ -128,8 +130,17 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb % 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 @@ -138,7 +149,7 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb 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; @@ -156,8 +167,12 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb % 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 @@ -196,6 +211,14 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb 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 % --------------------------------------------------------------------- diff --git a/codec2-dev/octave/ldpc.m b/codec2-dev/octave/ldpc.m index 2e9cf125..a8bbedbc 100644 --- a/codec2-dev/octave/ldpc.m +++ b/codec2-dev/octave/ldpc.m @@ -1,15 +1,5 @@ % ldpc.m -% ldpc functions - -% LDPC demo; Bill Cowley -% Call the CML routines and simulate one set of SNRs. See test_ldpc1.m -% -% sim_in the input parameter structure -% sim_out contains BERs and other stats for each value of SNR -% resfile is the result file -% -% 4/oct/2013: edited to use the WiMax eIRA codes -% see 'help InitializeWiMaxLDPC' for parameter values +% LDPC functions 1; @@ -42,7 +32,6 @@ function frameout = insert_uw(framein, uw) spacing = 2*lframein/luw; frameout = []; - mod_uw = []; pin = 1; pout = 1; puw = 1; while (luw) @@ -51,7 +40,6 @@ function frameout = insert_uw(framein, uw) pin += spacing; pout += spacing; frameout(pout:pout+1) = uw(puw:puw+1); - mod_uw(pout:pout+1) = qpsk_mod(uw(puw:puw+1)); puw += 2; pout += 2; luw -= 2; @@ -80,6 +68,29 @@ function frameout = remove_uw(framein, lvd, luw) endfunction +% removes a unique word from a frame of symbols. The UW symbols are spread +% throughout the input frame 1 symbol at a time. + +function framesymbolsout = remove_uw_symbols(framesymbolsin, ldatasymbols, luwsymbols) + + spacing = ldatasymbols/luwsymbols; + + framesymbolsout = []; + + pin = 1; pout = 1; + while (luwsymbols) + %printf("pin %d pout %d luw %d ", pin, pout, luwsymbols); + %printf("pin+spacing-1 %d ldatasymbols %d lframein: %d\n", pin+spacing-1, ldatasymbols, length(framesymbolsin)); + framesymbolsout(pout:pout+spacing-1) = framesymbolsin(pin:pin+spacing-1); + pin += spacing + 1; + pout += spacing; + luwsymbols--; + end + +endfunction + + + % builds up a sparse QPSK modulated version version of the UW for use % in UW sync at the rx @@ -166,3 +177,21 @@ function unpacked = unpackmsb(packed) end endfunction + +% symbol interleaver that acts on bits 2 at a time + +function y = interleave_bits(interleaver, x) + y = zeros(1,length(x)); + for i = 1:length(interleaver) + dst = interleaver(i); + y(2*(dst-1)+1:2*dst) = x(2*(i-1)+1:2*(i)); + end +endfunction + +% symbol de-interleaver + +function x = deinterleave_symbols(interleaver, y) + for i = 1:length(interleaver) + x(i) = y(interleaver(i)); + end +endfunction diff --git a/codec2-dev/octave/ldpcdec.m b/codec2-dev/octave/ldpcdec.m index 6e261cd1..91e89411 100644 --- a/codec2-dev/octave/ldpcdec.m +++ b/codec2-dev/octave/ldpcdec.m @@ -4,130 +4,192 @@ % LDPC decoder test program, given a file of QPSK symbols (IQIQ floats), % performs frame sync, decodes, and measures BER. -% Start CML library +function ldpcdec(filename) -currentdir = pwd; -addpath '/home/david/tmp/cml/mat' % assume the source files stored here -cd /home/david/tmp/cml -CmlStartup % note that this is not in the cml path! -cd(currentdir) + % Start CML library -% Our LDPC library + currentdir = pwd; + addpath '/home/david/tmp/cml/mat' % assume the source files stored here + cd /home/david/tmp/cml + CmlStartup % note that this is not in the cml path! + cd(currentdir) -ldpc; + % Our LDPC library -% Start simulation + ldpc; -rand('state',1); + % Start simulation -rate = 3/4; -framesize = 576; + rand('state',1); -mod_order = 4; -modulation = 'QPSK'; -mapping = 'gray'; + rate = 3/4; + framesize = 576; -demod_type = 0; -decoder_type = 0; -max_iterations = 100; -EsNo = 10; -Eprob = 0.0; + mod_order = 4; + modulation = 'QPSK'; + mapping = 'gray'; -vocoderframesize = 52; -nvocoderframes = 8; -nbitspermodemframe = 72; + demod_type = 0; + decoder_type = 0; + max_iterations = 100; + EsNo = 4; + Eprob = 0.0; -code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping); -code_param.code_bits_per_frame = 576; + nbitspervocoderframe = 52; + nvocoderframes = 8; + nbitspermodemframe = 72; -data = []; -r = []; + code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping); + code_param.code_bits_per_frame = 576; -Nframes = 100; -uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0]; + data = []; + r = []; + load interleaver.txt + interleaver = interleaver + 1; -% repeat same simulated vocoder data to ease testing + Nframes = 100; + uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0]; -vd = round( rand( 1, vocoderframesize*nvocoderframes) ); + % repeat same simulated vocoder data to ease testing -% Decoder: Sync with LDPC frames, LDPC decode, strip off UW, measure BER ------- + vd = round( rand( 1, nbitspervocoderframe*nvocoderframes) ); -fm=fopen("modcodeword.bin","rb"); + % Decoder: Sync with LDPC frames, de-interleave, LDPC decode, strip off UW, measure BER ------- -mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw)); + mcwfilename = strcat(filename,"_modcodeword.bin"); + fm=fopen(mcwfilename,"rb"); + etfilename = strcat(filename,"_et.bin"); + fet=fopen(etfilename ,"rb"); + epfilename = strcat(filename,".err"); + fep=fopen(epfilename ,"wb"); + printf("Input QPSK symbols: %s\n", mcwfilename); + if (fet == -1) + printf("Input entered track file: none\n"); + else + printf("Input entered track file: %s\n", etfilename); + end + printf("Output error pattern file: %s\n", epfilename); -mod_codeword = zeros(1, code_param.code_bits_per_frame/2); -lmod_codeword = code_param.code_bits_per_frame/2; + mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw)); -Terrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = []; -corr = []; n = 0; -sync_state = 0; sync_count = 0; -mod_unpackedmodem_log = []; + mod_codeword = zeros(1, code_param.code_bits_per_frame/2); + lmod_codeword = code_param.code_bits_per_frame/2; -[mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32"); -while (count == nbitspermodemframe) - n++; + Terrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = []; + corr = []; n = 0; + sync_state = 0; sync_count = 0; + mod_unpackedmodem_log = []; + sync_state_log = []; + entered_track_log = []; - mod_unpackedmodem = mod_unpackedmodem_float32(1:2:nbitspermodemframe) + j*mod_unpackedmodem_float32(2:2:nbitspermodemframe); - mod_unpackedmodem_log = [mod_unpackedmodem_log mod_unpackedmodem]; - erasures = rand(1,length(mod_unpackedmodem)) < Eprob; - mod_unpackedmodem(erasures) = 0; + [mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32"); + if (fet == -1) + entered_track = 0; + else + entered_track = fread(fet, 1, "int"); + end - % keep buffer of one entire codeword + while (count == nbitspermodemframe) + n++; - mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword); - mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem; + mod_unpackedmodem = mod_unpackedmodem_float32(1:2:nbitspermodemframe) + j*mod_unpackedmodem_float32(2:2:nbitspermodemframe); + mod_unpackedmodem_log = [mod_unpackedmodem_log mod_unpackedmodem]; + erasures = rand(1,length(mod_unpackedmodem)) < Eprob; + mod_unpackedmodem(erasures) = 0; - [uw_sync corr(n)] = look_for_uw(mod_codeword(1:length(mod_uw)), mod_uw); - if (uw_sync) - sync_state = 1; - end + % keep buffer of one entire codeword - if (sync_state && (sync_count == 0)) - Tframes++; + mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword); + mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem; - % force UW symbols as they are known (is this needed?) + [uw_sync corr(n)] = look_for_uw(mod_codeword(1:length(mod_uw)), mod_uw); - % LDPC decode + next_sync_state = sync_state; + if ((sync_state == 0) && (uw_sync == 1)) + next_sync_state = 1; + sync_count = 0; + end + if ((sync_state == 1) && (entered_track != 0)) + next_sync_state = 0; + end + sync_state = next_sync_state; + sync_state_log = [sync_state_log sync_state]; + entered_track_log = [entered_track_log entered_track]; - detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, mod_codeword, EsNo); - - % unpack payload data, removing UW - - vd_rx = remove_uw(detected_data(1:code_param.data_bits_per_frame), length(vd), length(uw)); - - % measure BER - - error_positions = xor(vd, vd_rx); - Nerrs = sum(error_positions); - if Nerrs>0, fprintf(1,'x'); Ferrs++; , else fprintf(1,'.'), end - Tbits += length(vd); - Terrs += Nerrs; - nerr(Tframes) = Nerrs; - - % save packed payload data to disk - end - - if (sync_state) - sync_count++; - if (sync_count == 8) - sync_count = 0; - end - end - - % read in one modulated modem frame at a time - - [mod_unpackedmodem_float32, count] = fread(fm, nbitspermodemframe, "float32"); -end - -fprintf(1,"\nFrames: %d bits: %d errors: %d BER = %f FER = %f\n", Tframes, Tbits, Terrs, Terrs/Tbits, Ferrs/Tframes); -%subplot(211) -%plot(corr); -%subplot(212) -%plot(nerr); -figure(1) -clf; -[n m] = size(mod_unpackedmodem_log); -plot( real(mod_unpackedmodem_log), imag(mod_unpackedmodem_log), '+') -axis([-2 2 -2 2]); -title('Scatter Diagram'); + if (sync_state && (sync_count == 0)) + Tframes++; + + % remove UW symbols + + mod_codeword_no_uw = remove_uw_symbols(mod_codeword, code_param.data_bits_per_frame/2 - length(uw)/2, length(uw)/2); + 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)]; + + % de-interleave + + tmp = deinterleave_symbols(interleaver, mod_codeword_no_uw); + + % insert known symbols at end of data + + mod_codeword_deinter = [ tmp(1:(code_param.data_bits_per_frame/2 - length(uw)/2)) ... + ones(1,length(uw)/2) * qpsk_mod([0 0]) ... + tmp((code_param.data_bits_per_frame/2 - length(uw)/2+1):length(tmp)) ]; + + % LDPC decode + + detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, mod_codeword_deinter, EsNo); + + % unpack payload data, removing UW + + vd_rx = detected_data(1:(code_param.data_bits_per_frame - length(uw))); + + % measure BER + + error_positions = xor(vd, vd_rx); + Nerrs = sum(error_positions); + if Nerrs>0, fprintf(1,'x'); Ferrs++; , else fprintf(1,'.'), end + Tbits += length(vd); + Terrs += Nerrs; + nerr(Tframes) = Nerrs; + + % save error patterns is simulated vocoder data to disk + + fwrite(fep, error_positions, "short"); + + end + + if (sync_state) + sync_count++; + if (sync_count == 8) + sync_count = 0; + end + end + + % read in one modulated modem frame at a time + + [mod_unpackedmodem_float32, count] = fread(fm, nbitspermodemframe, "float32"); + if (fet == -1) + entered_track = 0; + else + entered_track = fread(fet, 1, "int"); + end + end + + fclose(fep); + + fprintf(1,"\nFrames: %d bits: %d errors: %d BER = %f FER = %f\n", Tframes, Tbits, Terrs, Terrs/Tbits, Ferrs/Tframes); + + figure(8) + clf; + [n m] = size(mod_unpackedmodem_log); + plot( real(mod_unpackedmodem_log), imag(mod_unpackedmodem_log), '+') + axis([-2 2 -2 2]); + title('Scatter Diagram'); + + figure(9) + subplot(311) + plot(sync_state_log); + subplot(312) + plot(entered_track_log); + subplot(313) + plot(nerr); +endfunction diff --git a/codec2-dev/octave/ldpcenc.m b/codec2-dev/octave/ldpcenc.m index 4a1e28f4..023c5172 100644 --- a/codec2-dev/octave/ldpcenc.m +++ b/codec2-dev/octave/ldpcenc.m @@ -1,172 +1,125 @@ % ldpcenc.m % David Rowe 20 Dec 2013 % -% LDPC encoder test program. Encodes and modulates a random data stream +% LDPC encoder function. Takes a random data pattern, LDPC Encodes and +% inserts Unique Word (UW) sync bits and ouputs this as a packed +% binary file suitable for the Nc=18 carrier FDMDV modulator, +% fdmdv_mod. Also produces a "modulated" output file of QPSK +% symbols, suitable for feeding into ldpcdec for testing. -% Start CML library +function ldpcenc(filename) -currentdir = pwd; -addpath '/home/david/tmp/cml/mat' % assume the source files stored here -cd /home/david/tmp/cml -CmlStartup % note that this is not in the cml path! -cd(currentdir) + % Start CML library -% Our LDPC library + currentdir = pwd; + addpath '/home/david/tmp/cml/mat' % assume the source files stored here + cd /home/david/tmp/cml + CmlStartup % note that this is not in the cml path! + cd(currentdir) + + % Our LDPC library -ldpc; + ldpc; -% Start simulation + % Start simulation -rand('state',1); + rand('state',1); -rate = 3/4; -framesize = 576; + rate = 3/4; + framesize = 576; -mod_order = 4; -modulation = 'QPSK'; -mapping = 'gray'; + mod_order = 4; + modulation = 'QPSK'; + mapping = 'gray'; -demod_type = 0; -decoder_type = 0; -max_iterations = 100; -EsNo = 10; -Eprob = 0.15; + demod_type = 0; + decoder_type = 0; + max_iterations = 100; -vocoderframesize = 52; -nvocoderframes = 8; -nbitspermodemframe = 72; + nbitspervocoderframe = 52; + nvocoderframes = 8; + nbitspermodemframe = 72; -code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping); + code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping); -data = []; -r = []; + data = []; + r = []; + load interleaver.txt + interleaver = interleaver + 1; -% Encoder: Generate simulated vocoder data, insert UW, and LPDC encode --------------- + % Encoder: Generate simulated vocoder data + % LPDC encode + % interleave + % insert UW bits -Nframes = 100; -uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0]; + Nframes = 100; + uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0]; -% repeat same simulated vocoder data to ease testing + % repeat same simulated vocoder data to ease testing -vd = round( rand( 1, vocoderframesize*nvocoderframes) ); -d = insert_uw(vd, uw); + vd = round( rand( 1, nbitspervocoderframe*nvocoderframes) ); -data = [data d]; -[codeword, s] = ldpc_enc(d, code_param); -code_param.code_bits_per_frame = length(codeword); -code_param.symbols_per_frame = length(s); -packedcodeword = packmsb(codeword); + % pad data with zeros the size of UW -fc=fopen("codeword.bin","wb"); -for nn = 1: Nframes - fwrite(fc,packedcodeword,"uchar"); -end -fclose(fc); + vdpad = [vd zeros(1, length(uw))]; -%printf("framesize: %d data_bits_per_frame: %d code_bits_per_frame: %d\n", ... -% framesize, code_param.data_bits_per_frame, code_param.code_bits_per_frame); + % LDPC encode -printf("Encoded %d LDPC frames\n", Nframes); + [codewordpad, s] = ldpc_enc(vdpad, code_param); + code_param.code_bits_per_frame = length(codewordpad); + code_param.symbols_per_frame = length(s); -% Modulator: Modulate to QPSK symbols ------------------------------------------ + % remove padded zeros after encoding to leave room for UW bits (code + % is systematic) -lpackedcodeword=length(packedcodeword); -fc=fopen("codeword.bin","rb"); -fm=fopen("modcodeword.bin","wb"); -lpackedmodem = nbitspermodemframe/8; -n = 0; + codeword = [ codewordpad(1:length(vd)) codewordpad((length(vd)+length(uw)+1):length(codewordpad)) ]; -[packedmodem, count] = fread(fc,lpackedmodem,"uchar"); -while (count == lpackedmodem) - n++; - unpackedmodem = unpackmsb(packedmodem); + % interleave, insert UW bits, and pack bits (as C modulator likes packed bits) - ii = 1; - for i=1:2:length(unpackedmodem) - mod_unpackedmodem(ii) = qpsk_mod(unpackedmodem(i:i+1)); - mod_unpackedmodem_float32(i) = real(mod_unpackedmodem(ii)); - mod_unpackedmodem_float32(i+1) = imag(mod_unpackedmodem(ii)); - ii += 1; - end + codeword_interleaved = interleave_bits(interleaver, codeword); + codeword_interleaved_uw = [insert_uw(codeword_interleaved(1:length(vd)), uw) codeword_interleaved(length(vd)+1:length(codeword_interleaved)) ]; + packedcodeword = packmsb(codeword_interleaved_uw); - fwrite(fm, mod_unpackedmodem_float32, "float32"); - [packedmodem, count] = fread(fc,lpackedmodem,"uchar"); -end -fclose(fc); -fclose(fm); -printf("Modulated %d modem frames\n", n); + cwfilename = strcat(filename,"_codeword.bin"); + fc=fopen(cwfilename,"wb"); + for nn = 1: Nframes + fwrite(fc,packedcodeword,"uchar"); + end + fclose(fc); + %printf("framesize: %d data_bits_per_frame: %d code_bits_per_frame: %d\n", ... + % framesize, code_param.data_bits_per_frame, code_param.code_bits_per_frame); -% Decoder: Sync with LDPC frames, LDPC decode, strip off UW, measure BER ------- + printf("Encoded %d LDPC codewords, saved in packed file: %s\n", Nframes, cwfilename); -fm=fopen("modcodeword.bin","rb"); + % Modulator: Modulate to QPSK symbols ------------------------------------------ -mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw)); + nbytespackedcodeword=length(packedcodeword); + fc=fopen(cwfilename,"rb"); + mcwfilename = strcat(filename,"_modcodeword.bin"); + fm=fopen(mcwfilename,"wb"); + nbytespackedmodemframe = nbitspermodemframe/8; + n = 0; -mod_codeword = zeros(1, code_param.code_bits_per_frame/2); -lmod_codeword = code_param.code_bits_per_frame/2; + [packedmodem, count] = fread(fc,nbytespackedmodemframe,"uchar"); + while (count == nbytespackedmodemframe) + n++; + unpackedmodem = unpackmsb(packedmodem); -Terrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = []; -corr = []; n = 0; -sync_state = 0; sync_count = 0; + ii = 1; + for i=1:2:length(unpackedmodem) + mod_unpackedmodem(ii) = qpsk_mod(unpackedmodem(i:i+1)); + mod_unpackedmodem_float32(i) = real(mod_unpackedmodem(ii)); + mod_unpackedmodem_float32(i+1) = imag(mod_unpackedmodem(ii)); + ii += 1; + end -[mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32"); -while (count == nbitspermodemframe) - n++; + fwrite(fm, mod_unpackedmodem_float32, "float32"); + [packedmodem, count] = fread(fc,nbytespackedmodemframe,"uchar"); + end + fclose(fc); + fclose(fm); + printf("Modulated %d modem frames to file: %s\n", n, mcwfilename); +endfunction - mod_unpackedmodem = mod_unpackedmodem_float32(1:2:nbitspermodemframe) + j*mod_unpackedmodem_float32(2:2:nbitspermodemframe); - erasures = rand(1,length(mod_unpackedmodem)) < Eprob; - mod_unpackedmodem(erasures) = 0; - % keep buffer of one entire codeword - - mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword); - mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem; - - [uw_sync corr(n)] = look_for_uw(mod_codeword(1:length(mod_uw)), mod_uw); - if (uw_sync) - sync_state = 1; - end - - if (sync_state && (sync_count == 0)) - Tframes++; - - % force UW symbols as they are known (is this needed?) - - % LDPC decode - - detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, mod_codeword, EsNo); - - % unpack payload data, removing UW - - vd_rx = remove_uw(detected_data(1:code_param.data_bits_per_frame), length(vd), length(uw)); - - % measure BER - - error_positions = xor(vd, vd_rx); - Nerrs = sum(error_positions); - if Nerrs>0, fprintf(1,'x'); Ferrs++; , else fprintf(1,'.'), end - Tbits += length(vd); - Terrs += Nerrs; - nerr(Tframes) = Nerrs; - - % save packed payload data to disk - end - - if (sync_state) - sync_count++; - if (sync_count == 8) - sync_count = 0; - end - end - - % read in one modulated modem frame at a time - - [mod_unpackedmodem_float32, count] = fread(fm, nbitspermodemframe, "float32"); -end - -fprintf(1,"\nFrames: %d bits: %d errors: %d BER = %f FER = %f\n", Tframes, Tbits, Terrs, Terrs/Tbits, Ferrs/Tframes); -subplot(211) -plot(corr); -subplot(212) -plot(nerr); diff --git a/codec2-dev/octave/pl2.m b/codec2-dev/octave/pl2.m index 50d82262..17671c08 100644 --- a/codec2-dev/octave/pl2.m +++ b/codec2-dev/octave/pl2.m @@ -2,53 +2,40 @@ % 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