function [ratio, errors] = simbasebandex(SNRpBit)
% Baseband QPSK simulation example
%
%   [RATIO, ERRORS] = SIMBASEBANDEX(SNRPBIT) is an example that demonstrates how
%   to simulate modulation using a complex baseband equivalent representation of
%   the signal modulated on a carrier.  It also demonstrates demondulation and
%   detection of the signal in the presence of additive white Gaussian noise for
%   quaternary phase shift keying (QPSK).  This simulation technique is more
%   efficient that passband simulations because it requires a lower value for
%   Fs.  SNRPBIT is a vector that contains the Signal to Noise ratios per bit of
%   the channels for the simulation run.  This file runs a simulation at each of
%   the SNRBBITs listed.  Each simulation runs until both the minimum simulation
%   iterations have been completed and the number of errors equals 'expSymErrs'
%   (60 symbols).  SIMBASEBANDEX then plots the theoretical curves for QPSK
%   along with the simulation results as they are generated.
%
%   SIMBASEBANDEX can be changed to simulate binary PSK (BPSK) by changing M
%   from 4 to 2.  Changes to other modulations (i.e. modulation type and
%   alphabet) will require changes to the equations that generate expected
%   results.

%   Copyright 1996-2000 The MathWorks, Inc.
%   $Revision: 1.2 $ $Date: 2000/08/30 22:21:21 $

% Initalize sampling times, oversampling rate, modulation.
Fd = 1; Fs = 1; N = Fs/Fd; modulation = 'psk';

% Define alphabet (quaternary). Signal to Noise ratio (SNR).
% Change M to 2 to get results for BPSK instead of QPSK
M = 4; k = log2(M); SNR = SNRpBit + 10*log10(k);

% Set number of symbols per iteration and number of iterations
% Expected number of symbol error count
symbPerIter = 4096; iters = 3; expSymErrs = 60;
numSymbTot = symbPerIter * iters;

% Set random number seeds for uniform and Gaussian noise
rand('state', 123456789);  randn('state', 987654321);

% Calculate expected results only for QPSK for plotting later on
expBER = 0.5.*erfc(sqrt(10.^(SNRpBit(:).*0.1)) );
expSER = 1 - (1 - expBER) .^ k;

% Plot the theoretical results for SER and BER.
semilogy(SNRpBit(:), expSER, 'g-', ...
         SNRpBit(:), expBER, 'm-');
legend('Theoretical SER','Theoretical BER',0);  grid on;
title('Performance of Baseband QPSK');
xlabel('SNR/bit (dB)');
ylabel('SER and BER');
hold on;

% Create Gray encoding and decoding arrays
grayencod	= bitxor([0:M-1],floor([0:M-1]/2));
[dummy graydecod] = sort(grayencod);  graydecod = graydecod - 1;


% Drive the simulation for each of the SNR values calculated above
for(idx2 = [1:length(SNR)])
    % Exit loop only when minimum number of iterations have completed and the
    % number of errors exceeds 'expSymErrs'
    idx = 1;
    while ((idx <= iters) | (sum(errSym) <= expSymErrs))

        % Generate random numbers from in the range [0,M-1]
        msg_orig = randsrc(symbPerIter,1,[0:M-1]);

        % Gray encode symbols
        msg_gr_orig = grayencod(msg_orig+1)';

        % Digitally modulate and upsample the signal
        msg_tx  = dmodce(msg_gr_orig, Fd, Fs, modulation, M);

        % Add Gaussian noise to the signal.  The noise signal is calibrated using
        % the 'measured' option.  The noise power is scaled for oversampling.
        msg_rx  = awgn(msg_tx, SNR(idx2)-10*log10(1.*N), 'measured', [], 'dB');

        % Demodulate, detect, and downsample the signal
        msg_gr_demod = ddemodce(msg_rx, Fd, Fs, modulation, M);

        % Gray decode message
        msg_demod = graydecod(msg_gr_demod+1)';

        % calculate bit error count, BER, symbol error count and SER, for this iteration.
        [errBit(idx) ratBit(idx)] = biterr(msg_orig, msg_demod, k);
        [errSym(idx) ratSym(idx)] = symerr(msg_orig, msg_demod);

        % Increment for next iteration, pause to allow <ctrl-C> break
        idx = idx + 1;   pause(.1);
    end

    % average the errors and error ratios for the iterations.
    errors(idx2,:) = [sum(errBit),  sum(errSym)];
    ratio(idx2,:)  = [mean(ratBit), mean(ratSym)];

    % Plot the simulated results for SER and BER.
    semilogy(SNRpBit([1:size(ratio(:,2),1)]),ratio(:,2),'bo', ...
             SNRpBit([1:size(ratio(:,1),1)]),ratio(:,1),'ro');
    legend('Theoretical SER','Theoretical BER','Simulated SER','Simulated BER',0);
    pause(.1);
end
hold off;
