function slide=vitsimdemo
% Convolutional encoder and Viterbi decoder demonstration
%   VITSIMDEMO is a slideshow demonstration of convolution forward error
%   correction coding and the Viteri decoding algorithm.  It demonstrates how to
%   use a convolutional encoder and decoder in a simulation of a communications
%   link. It also shows error correcting capability of convolutional codes.
%   This demonstrates the new convolutional trellis generator, POLY2TRELLIS,
%   encoder, CONVENC, and decoder, VITDEC.   It also demonstrates the use of,
%   DMODCE, DDEMODCE, SYMERR, BITERR, RANDSRC and AWGN.  The latter functions
%   are described in greater detail in the "Simulation of Phase Shift Keying in
%   Gaussian noise" demo, BASICSIMDEMO.  Finally, this demo displays empirical
%   performance curves for QPSK with Gray coding using data generated by the
%   example, VITSIMEXAMPLE.

%   Copyright 1996-2000 The MathWorks, Inc.
%   $Revision: 1.4 $ $Date: 2000/09/13 20:38:14 $


if nargout<1,
  playshow vitsimdemo
else
  %========== Slide 1 ==========

  slide(1).code={
    'cla;',
    'fig = gcf;',
    'sp = get(fig,''position'');',
    'ss = get(0,''ScreenSize'');',
    'fp1 = [ss(3)*0.55-sp(3)*0.55  ss(4)*.75-sp(4) sp(3)*1.32 sp(4)*1.43];',
    'if ichange == 0  & size(slideData.param,2) == 1; set(gcf,''position'',fp1); end;',
    'SNRpBit = [4.5:.5:7]; linSNRpB = 10.^(SNRpBit(:).*0.1);'
    'M = 4; codeRate = 1/2; constlen = 7; k = log2(M); '
    'dist = [10:2:16];  numErr = [36 211 1404 11633];'
    'expBER = 0.5.*erfc(sqrt(linSNRpB*codeRate));'
    'expVitBER = vitproberrdemo(expBER,dist,numErr);'
    'semilogy(SNRpBit,expVitBER,''g-'');  xlabel(''Eb/No (dB)''); ylabel(''BER'');'
    'title(''Performance for R=1/2, K=7 Conv. Code and QPSK with Hard Decision'' ); grid on;',
    'axis([4 8 10e-7 10e-3]); legend(''Union Bound'',0);',
    ''
	};
  slide(1).text={
    'This demo shows how to create a simulation of a QPSK communication system that demonstrates the error correction capabilities of convolutional encoding and compare them to the union bound performance estimates shown above. ',
    '',
    'SNRpBit = [4.5:.5:7]; linSNRpB = 10.^(SNRpBit(:).*0.1);'
    'M = 4; codeRate = 1/2; constlen = 7; k = log2(M); '
    'dist = [10:16];  numErr = [36  0 211 0 1404 0 11633];'
    'expBER = 0.5.*erfc(sqrt(linSNRpB*codeRate));'
    'expVitBER = vitproberrdemo(expBER,dist,numErr);'
    'semilogy(SNRpBit,expVitBER,''g-'');  xlabel(''Eb/No per bit (dB)''); ylabel(''BER'');'
    'title(''Performance for R=1/2, K=7 Conv. Code and QPSK with Hard Decision'' ); grid on;'
    'axis([4 8 10e-7 10e-3]); legend(''Union Bound'',0);',
   ''
   };
  %========== Slide 2 ==========

  slide(2).code={
	'Fd = 1; Fs = 4; N = Fs/Fd; numSymb = 100; numPlot = 20;',
	'SNRpBitDemo = 3; SNR = SNRpBitDemo*k;                     ',
	'seed = [12345678 87654321];              ',
	'rand(''state'', seed(1));  randn(''state'', seed(2));              ',
	'msg_orig = randsrc(numSymb,1,[0:1]);                      ',
	'stem([0:numPlot-1], msg_orig(1:numPlot),''bx'');                      ',
	'axis([ 0 numPlot -0.2 1.2]);  xlabel(''Time''); ylabel(''Amplitude'');'
    'title(''Binary Symbols Before Convolutional Encoding'' ); '
	};
  slide(2).text={
    'First start by setting parameters needed for the simulation.  Then generate binary data using RANDSRC.  The first 20 points of this data are plotted above.',
   '',
	'Fd = 1; Fs = 4; N = Fs/Fd; numSymb = 100; numPlot = 20;',
	'SNRpBitDemo = 3; SNR = SNRpBitDemo*k;                     ',
	'seed = [654321 123456];              ',
	'rand(''state'', seed(1));  randn(''state'', seed(2));              ',
	'msg_orig = randsrc(numSymb,1,[0:1]);                      ',
	'stem([0:numPlot-1], msg_orig(1:numPlot),''bx'');                      ',
	'axis([ 0 numPlot -0.2 1.2]);  xlabel(''Time''); ylabel(''Amplitude'');'
    'title(''Binary Symbols Before Convolutional Encoding'' ); '
   };

  %========== Slide 3 ==========

  slide(3).code={
    'constlen = [7]; codegen = [171 133];  tblen = 32; codeRate = 1/2;',
    'trel = poly2trellis(constlen, codegen);',
    '[msg_enc_bi] = convenc(msg_orig, trel);',
	'numEncPlot = numPlot ./ codeRate; tEnc = [0:numEncPlot-1] * codeRate;',
	'stem(tEnc, msg_enc_bi(1:length(tEnc)),''rx'');',
	'axis([ min(tEnc) max(tEnc) -0.2 1.2]);  xlabel(''Time''); ylabel(''Amplitude''); '
    'title(''Binary Symbols After Convolutional Encoding'' ); '
	};
  slide(3).text={
    'Define the constraint length, generator polynomial, traceback length, and code rate for convolutional coding.  Then, use POLY2TRELLIS to generate the convolutional code trellis.  Then use CONVENC to encode the information symbols. The plot above shows the coded symbols.  Note that the encoded symbol rate is twice that of the information symbol rate.',
   '',
    'constlen = [7]; codegen = [171 133];  tblen = 32; codeRate = 1/2;',
    'trel = poly2trellis(constlen, codegen);',
    '[msg_enc_bi] = convenc(msg_orig, trel);',
	'numEncPlot = numPlot ./ codeRate; tEnc = [0:numEncPlot-1] * codeRate;',
	'stem(tEnc, msg_enc_bi(1:length(tEnc)),''rx'');',
	'axis([ min(tEnc) max(tEnc) -0.2 1.2]);  xlabel(''Time''); ylabel(''Amplitude''); '
    'title(''Binary Symbols After Convolutional Encoding'' ); '
   };
  %========== Slide 4 ==========

  slide(4).code={
	'randn(''state'', seed(2));              '
	'msg_enc  = bi2de(reshape(msg_enc_bi, size(msg_enc_bi,2)*k,size(msg_enc_bi,1) / k)'');',
	'grayencod = bitxor([0:M-1],floor([0:M-1]/2)); msg_gr_enc = grayencod(msg_enc+1);',
	'msg_tx  = dmodce(msg_gr_enc, Fd, [Fs, pi/4], ''psk'', M);',
	'msg_rx  = awgn(msg_tx, SNR-10*log10(1/codeRate)-10*log10(N));',
	'numModPlot = numEncPlot * Fs ./ k; tMod = [0:numModPlot-1] ./ Fs .* k;          ',
	'plot(tMod, real(msg_tx(1:length(tMod))),''c-'',tMod, imag(msg_tx(1:length(tMod))),''m-'');',
	'axis([ min(tMod) max(tMod) -1.5 1.5]);  xlabel(''Time''); ylabel(''Amplitude''); '
    'title(''Encoded Symbols After QPSK Baseband Modulation'' ); legend(''In-phase'',''Quadrature'',0);'
	};
  slide(4).text={
    'Use BI2DE to convert the coded information to quarternary alphabet.   Then generate an encoding array and use it to Gray-encode the symbols.  Then use DMOD to Quaternary PSK (QPSK) modulate the signal. Then use AWGN to add noise to the transmitted signal and to create the noisy signal at the receiver.  The term, -10*log10(N), is used to scale the noise power with the oversampling.  The term, -10*log10(1/codeRate), is used to scale the noise power to match the coded symbol rate.  The in-phase and quadrature components of the noiseless QPSK signal are plotted above.',
   '',
	'msg_enc  = bi2de(reshape(msg_enc_bi, size(msg_enc_bi,2)*k,size(msg_enc_bi,1) / k)'');',
	'grayencod = bitxor([0:M-1],floor([0:M-1]/2)); msg_gr_enc = grayencod(msg_enc+1);',
	'msg_tx  = dmodce(msg_gr_enc, Fd, [Fs, pi/4], ''psk'', M);',
	'msg_rx  = awgn(msg_tx, SNR-10*log10(1/codeRate)-10*log10(N));',
	'numModPlot = numEncPlot * Fs ./ k; tMod = [0:numModPlot-1] ./ Fs .* k;          ',
	'plot(tMod, real(msg_tx(1:length(tMod))),''c-'',tMod, imag(msg_tx(1:length(tMod))),''m-'');',
	'axis([ min(tMod) max(tMod) -1.5 1.5]);  xlabel(''Time''); ylabel(''Amplitude''); '
    'title(''Encoded Symbols After QPSK Baseband Modulation'' ); legend(''In-phase'',''Quadrature'',0);'
   };

  %========== Slide 5 ==========
%	'stem(tEnc, msg_enc_bi(1:numEncPlot),''rx''); hold on;  '
%	'stem(tEnc, msg_demod_bi(1:numEncPlot),''bo''); hold off; '

  slide(5).code={
	'msg_gr_demod = ddemodce(msg_rx, Fd, [Fs, pi/4], ''psk'', M);',
	'[dummy graydecod] = sort(grayencod); graydecod = graydecod - 1;',
	'msg_demod = graydecod(msg_gr_demod+1)'';',
    'msg_demod_bi = de2bi(msg_demod,k)'' ; msg_demod_bi =  msg_demod_bi(:);',
	'stem(tEnc, msg_enc_bi(1:numEncPlot),''rx''); hold on;  ',
	'stem(tEnc, msg_demod_bi(1:numEncPlot),''bo''); hold off; ',
	'axis([ 0 numPlot -0.2 1.2]);  xlabel(''Time''); ylabel(''Amplitude''); title(''Demodulated Symbols'' ); '
	};
  slide(5).text={
    'Use DDEMOD to demodulate and detect the coded symbols.  Then sort the gray encoding array to generate the gray decoding array and use the gray decoding array to decode the received symbols. Then use DE2BI to convert the data to binary form.  The detected symbols are plotted in blue stems with circles and the original encoded symbols are plotted in red stems with x''s.  The red stems of the transmitted signal are shadowed by the blue stems of the received signal.  Therefore, comparing  the red x''s with the blue circles indicates that the received signal is identical to the transmitted signal except for symbols at time 5, 6.5 and 13.',
   '',
	'msg_gr_demod = ddemodce(msg_rx, Fd, [Fs, pi/4], ''psk'', M);',
	'[dummy graydecod] = sort(graydecod); graydecod = graydecod - 1;',
	'msg_demod = graydecod(msg_gr_demod+1)'';',
    'msg_demod_bi = de2bi(msg_demod,k)'' ; msg_demod_bi =  msg_demod_bi(:);',
	'stem(tEnc, msg_enc_bi(1:numEncPlot),''rx''); hold on;  ',
	'stem(tEnc, msg_demod_bi(1:numEncPlot),''bo''); hold off; ',
	'axis([ 0 numPlot -0.2 1.2]);  xlabel(''Time''); ylabel(''Amplitude''); title(''Demodulated Symbols'' ); '
   };

  %========== Slide 6 ==========

  slide(6).code={
	'msg_dec = vitdec(msg_demod_bi, trel, tblen, ''cont'', ''hard'');',
	'stem([0:numPlot-1], msg_orig(1:numPlot),''rx''); hold on;  '
	'stem([0:numPlot-1], msg_dec(1+tblen:numPlot+tblen),''bo''); hold off; '
	'axis([ 0 numPlot -0.2 1.2]);  xlabel(''Time''); ylabel(''Amplitude'');'
    'title(''Decoded Symbols'' ); '
	};
  slide(6).text={
    'Then use VITDEC to decode the demodulated symbol stream. This example uses hard decision (''hard'') and the continuous decoding option (''cont'') which causes a delay in the decoded stream of 32 symbols (traceback length = 32).  Therefore the decoded data plot is shifted by 32 symbols to compensate for the decoder delay.  The decoded symbols are plotted in blue stems with circles while the original (unencoded) symbols are plotted in red stems with x''s.  The red stems of the original signal are shadowed by the blue stems of the decoded signal.  Therefore, comparing  the red x''s with the blue circles indicates that the decoded signal is identical to the original (unencoded) signal.  The errors shown in the previous slide in the detected symbols have been corrected.',
   '',
	'msg_dec = vitdec(msg_demod_bi, trel, tblen, ''cont'', ''hard'');',
	'stem([0:numPlot-1], msg_orig(1:numPlot),''rx''); hold on;  '
	'stem([0:numPlot-1], msg_dec(1+tblen:numPlot+tblen),''bo''); hold off; '
	'axis([ 0 numPlot -0.2 1.2]);  xlabel(''Time''); ylabel(''Amplitude'');'
    'title(''Decoded Symbols'' ); '
   };

  %========== Slide 7 ==========

  slide(7).code={
	'[errorBitCod ratioBitCod] = biterr(msg_enc, msg_demod);',
	'[errorBitCh ratioBitCh]   = biterr(msg_orig(1:end-tblen), msg_dec(1+tblen:end));',
   ''
	};
  slide(7).text={
    'Finally, use BITERR to compare the original messages to the demodulated messages.  BITERR is used to calculate the bit error rate. The error rates are calculated for both the channel and for the decoded bits stream.',
    '',
	'[errorBitCod ratioBitCod] = biterr(msg_enc, msg_demod);',
	'[errorBitCh ratioBitCh]   = biterr(msg_orig(1:end-tblen), msg_dec(1+tblen:end));',
    ''
   };

  %========== Slide 8 ==========

  slide(8).code={
    'cla;',
	'load(''vitsimresults.mat'');',
	'semilogy(SNRpBit,expVitBER,''g-'',SNRperBit, ratio,''b*-''); xlabel(''Eb/No (dB)''); ylabel(''BER'');',
    'title(''Performance for R=1/2, K=7 Conv. Code and QPSK with Hard Decision'' ); grid on;',
    'axis([4 8 10e-7 10e-3]);  legend(''Union Bound'',''Simulation Results'',0);',
   ''
	};
  slide(8).text={
    'This slide displays results generated by the example file, VITSIMEXAMPLE, which is a complete baseband simulation for QPSK.  It demonstrates how to create a convolutional code simulation driver in MATLAB that plots the simulation results as they are generated.  Since the empirical results will take time to generate, the results are loaded in from a previous simulation.  The results for the lower Eb/No values are quite far from the expected results because the union bound is loose in that region.  However, as the Eb/No is increased, the probability of error decreases and the results approach to within 1/4 dB of the performance estimated by the union bound.'
    '',
	'load(''vitsimresults.mat'');',
	'semilogy(SNRpBit,expVitBER,''g-'',SNRperBit, ratio,''b*-''); xlabel(''Eb/No (dB)''); ylabel(''BER'');',
    'title(''Performance for R=1/2, K=7 Conv. Code and QPSK with Hard Decision'' ); grid on;'
    'axis([4 8 10e-7 10e-3]);  legend(''Union Bound'',''Simulation Results'',0);',
   ''
   };
end
