aboutsummaryrefslogtreecommitdiff
path: root/octave/qam16_test.m
diff options
context:
space:
mode:
Diffstat (limited to 'octave/qam16_test.m')
-rw-r--r--octave/qam16_test.m141
1 files changed, 0 insertions, 141 deletions
diff --git a/octave/qam16_test.m b/octave/qam16_test.m
deleted file mode 100644
index c613214..0000000
--- a/octave/qam16_test.m
+++ /dev/null
@@ -1,141 +0,0 @@
-% qam16_test.m
-% David Rowe May 2020
-%
-% Octave symbol rate QAM16/LDPC experiments
-
-% Libraries we need
-
-1;
-qam16;
-ldpc;
-
-function test_qam16(fg=2)
- printf("QAM16 ----------------------------------------\n");
-
- mod_order = 16; bps = log2(mod_order);
- modulation = 'QAM'; mapping = ""; demod_type = 0; decoder_type = 0;
- max_iterations = 100; EsNo_dec = 10;
- qam16_const = [
- 1 + j, 1 + j*3, 3 + j, 3 + j*3;
- 1 - j, 1 - j*3, 3 - j, 3 - j*3;
- -1 + j, -1 + j*3, -3 + j, -3 + j*3;
- -1 - j, -1 - j*3, -3 - j, -3 - j*3];
- rms = sqrt(qam16_const(:)'*qam16_const(:)/16);
- qam16_const = qam16_const/rms;
- constellation_source = 'custom';
- test_qam16_mod_demod(qam16_const);
-
- load HRA_504_396.txt
- if strcmp(constellation_source,'cml')
- code_param = ldpc_init_user(HRA_504_396, modulation, mod_order, mapping);
- else
- code_param = ldpc_init_user(HRA_504_396, modulation, mod_order, mapping, reshape(qam16_const,1,16));
- end
- rate = code_param.ldpc_data_bits_per_frame/code_param.ldpc_coded_bits_per_frame;
-
- printf("EbNodB Tbits Terrs BER Tcbits Tcerrs Perrs CBER CPER\n");
- EbNodBvec = 3:10; Ntrials = 1000;
- for i=1:length(EbNodBvec)
- EbNodB = EbNodBvec(i);
- EsNodB = EbNodB + 10*log10(rate) + 10*log10(bps); EsNodBvec(i) = EsNodB;
- EsNo = 10^(EsNodB/10);
- variance = 1/EsNo;
- Terrs = Tbits = 0; Tcerrs = 0; Tcbits = 0; Perrs = 0; rx_symbols_log = [];
- for nn = 1:Ntrials
- tx_bits = round(rand(1, code_param.ldpc_data_bits_per_frame));
- [tx_codeword, tx_symbols] = ldpc_enc(tx_bits, code_param);
- noise = sqrt(variance*0.5)*(randn(1,length(tx_symbols)) + j*randn(1,length(tx_symbols)));
- rx_symbols = tx_symbols + noise;
- rx_symbols_log = [rx_symbols_log rx_symbols];
-
- % uncoded decode/demod and count errors
- rx_codeword = zeros(1,code_param.ldpc_coded_bits_per_frame);
- for s=1:length(rx_symbols)
- rx_codeword((s-1)*bps+1:s*bps) = qam16_demod(qam16_const,rx_symbols(s));
- end
- Nerr = sum(xor(tx_codeword,rx_codeword));
- Terrs += Nerr;
- Tbits += code_param.ldpc_coded_bits_per_frame;
-
- % LDPC demod/decode and count errors
- dec_rx_codeword = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, rx_symbols, EsNo_dec, ones(1,length(rx_symbols)));
- errors_positions = xor(tx_bits, dec_rx_codeword(1:code_param.ldpc_data_bits_per_frame));
- Ncerr = sum(errors_positions);
- Tcbits += code_param.ldpc_data_bits_per_frame; Tcerrs += Ncerr;
- if Ncerr Perrs++; end
- end
- figure(fg); clf; plot(rx_symbols_log,"."); axis([-1.5 1.5 -1.5 1.5]); drawnow;
- printf("%5.1f %6d %6d %5.2f %6d %6d %6d %5.2f %5.2f\n",
- EbNodB, Tbits, Terrs, Terrs/Tbits, Tcbits, Tcerrs, Perrs, Tcerrs/Tcbits, Perrs/Ntrials);
- ber(i) = Terrs/Tbits; cber(i) = Tcerrs/Tcbits; cper(i) = Perrs/Ntrials;
- end
- print("qam64_scatter.png","-dpng");
-
- figure(fg+1); clf; title('QAM16 Uncoded');
- uncoded_EbNodBvec = EbNodBvec + 10*log10(rate);
- ber_theory = ber_qam(uncoded_EbNodBvec);
- semilogy(uncoded_EbNodBvec,ber_theory,'b+-;uncoded QAM16 BER theory;','markersize', 10, 'linewidth', 2); hold on;
- semilogy(uncoded_EbNodBvec,ber+1E-10,'g+-;uncoded QAM16 BER;','markersize', 10, 'linewidth', 2); hold on;
- grid; axis([min(uncoded_EbNodBvec) max(uncoded_EbNodBvec) 1E-5 1]); xlabel('Uncoded Eb/No (dB)');
- print("qam16_uncoded_ber.png","-dpng");
-
- figure(fg+2); clf; title('QAM16 with LDPC (504,396)');
- semilogy(EbNodBvec,cber+1E-10,'b+-;QAM16 coded BER;','markersize', 10, 'linewidth', 2); hold on;
- semilogy(EbNodBvec,cper+1E-10,'g+-;QAM16 coded PER;','markersize', 10, 'linewidth', 2); hold off;
- grid; axis([min(EbNodBvec) max(EbNodBvec) 1E-5 1]); xlabel('Eb/No (dB)');
-
- figure(fg+3); clf; title('QAM16 with LDPC (504,396)');
- semilogy(EsNodBvec,cber+1E-10,'b+-;QAM16 coded BER;','markersize', 10, 'linewidth', 2); hold on;
- semilogy(EsNodBvec,cper+1E-10,'g+-;QAM16 coded PER;','markersize', 10, 'linewidth', 2); hold off;
- grid; axis([min(EsNodBvec) max(EsNodBvec) 1E-5 1]); xlabel('Es/No (dB)');
- print("qam16_504_396.png","-dpng");
-endfunction
-
-
-% Thanks Bill VK5DSP, for the QAM BER functions
-
-function p = ber_qam(ebn0)
- % Calculate the bit error rate (BER) for square 16QAM in AWGN
- % given the Eb/N0 in dB, ebn0 can be a scalar or vector
- % (assuming coherent detection, uncoded)
- % [section 5.3 Webb and Hanzo text]
-
- e = 4*10.^(ebn0/10); % Es/N0 vector in linear
- b2 = qfn(sqrt(e/5));
- b1 = (qfn(sqrt(e/5)) + qfn(3*sqrt(e/5)))/2;
- p = (b1+b2)/2;
-endfunction
-
-function tail=qfn(a)
- % Usage: tail=qfn(a)
- % where: tail=area under the tail of the normal dist. from a to inf.
- % for zero mean, unit variance distribution
- %
- % If no argument is given, plot Q(x) for x = 0 to 5
-
- % use erfc instead of 1-erf to avoid truncation errors! April 2010
-
- fact = 1 / sqrt(2);
- if exist('a')
-
- % tail = 0.5 * ( 1 - erf(a * fact));
- tail = 0.5 * erfc(a * fact);
- else
- x=(0: 0.1: 6); semilogy(x, 0.5*( erfc(x * fact)));
- title('Q function plot');
- xlabel('x'); ylabel('Q(x)');
- end
-endfunction
-
-
-% --------------------------------------------------------------------------------
-% START SIMULATIONS
-% --------------------------------------------------------------------------------
-
-more off;
-format;
-
-% Start CML library (see CML set up instructions in ldpc.m)
-init_cml();
-
-test_qam16(1)