## Contents

```function modulated = qpsk_mod( msg, varargin )
```

## A function to perform Quadrature Phase Shift Keying

```     Using good form and properly vectorized code, we generate the QPSK
sequence of the msg passed from user land.  Plots are generated to
show the result generated from the original bits.```
```     modulated = QPSK_MOD( msg )  "msg" can be a row vector if you only want to modulate one
message, or you can create a matrix... with the rows comprising the messages.  The
result will be either a vector or a matrix of modulated signal.```
```     modulated = QPSK_MOD( msg, samples_per_symbol ) The user can set the number of samples
per symbol in the final modulated carrier.```
```     modulated = QPSK_MOD( msg, samples_per_symbol, do_plot ) If the user wants to turn off
the plotting, just set the third argument to 1 for on, or 0 for off.```
```     modulated = QPSK_MOD( msg, samples_per_symbol, do_plot, do_complex ) When I wrote this,
the instructor wanted a real-valued QPSK as the result.  I usually work with
complex-valued signals, so I just gave an option to provide a complex result or a
real-valued result.```
```     Example :
>> msg = [1 0 0 0 1 1 1 0 1];
>> qpsk_mod( msg, 100 );
** Poof... magic plots **```
```     Example #2 :
>> msg = [[1 0 0 0 1 1 1 0 1]; [0 1 0 0 1 0 1 0 1]];
>> qpsk_mod( msg );
** Poof... more magic plots **```

## QPSK Modulation

The math for QPSK. Even bits are multiplied by a sine, while odd bits are multiplied by a cosine. ```    narginchk( 1, 4 );

% Some input checking : Only allow 0's and 1's.
if ~isempty(find( msg ~= 0 & msg ~= 1, 1 ))
error( 'Only values between 0 and 1 are supported for modulation in ASK.' );
end

% Check the shape of what the user gave us.  I decided to make this work on matrices of
% bits.  So each row will be a message.
[m,n] = size(msg);

% We're going to oversample a bit so we can see good resolution on the
% sine wave we will be generating for the carrier wave.
samples_per_symbol = 100;
if nargin >= 2
% Allow the user to override the samples per symbol
samples_per_symbol = varargin{1};
end

% Let the user turn off verbose prints/plots
doplot = 1;
if nargin >= 3
doplot = varargin{2};
end

% Allow complex output
docomplex = 0;
if nargin >= 4
docomplex = 1;
end
```
```Error using qpsk_mod (line 42)
Not enough input arguments.
```

## Variable Declarations :

```    % Hz : Frequency of the carrier signal.  To be precise, the actual
% frequency is f/samples_per_symbol.  So 2Hz.
f = 200;

% Generate our time vector for the sine wave generation.  We're
% creating one period, so from 0->2*pi in steps of
% 2*pi/samples_per_symbol.  i.e. 0->2*pi in 100 steps, evenly divided.
t = 0:2*pi/(samples_per_symbol-1):2*pi;

% In case the original message was odd in length, we need to truncate.
len_min = floor(n/2);

% Repeat our time vector for the sines and cosines.
t = repmat( t, 1, len_min );

% Preallocate for speed... because you should.
modulated = zeros(m, len_min*samples_per_symbol );
```

## The actual work is done in the following lines :

```    for k = 1:m
% Grab the even bits for Q
msg_q = msg( k, 2:2:end )*2 - 1;
% Grab the odd bits for I
msg_i = msg( k, 1:2:end )*2 - 1;

% "upsample", so to speak, the message by a factor of samples_per_symbol
% This is another way to replicate a certain bit.  In the other files, I used repmat().
% I also mentioned rectpulse() from the comms toolbox.
msg_i = msg_i(ones(1,samples_per_symbol), 1:len_min);
msg_i = msg_i(:);
msg_q = msg_q(ones(1,samples_per_symbol), 1:len_min);
msg_q = msg_q(:);

% Modulate the signal by the carrier just like BPSK, but on the I and Q
% pair.
%
%   \$m(t) = e*sin(f*t) + o*cos(f*t)\$
if ~docomplex
modulated(k,:) = (msg_i.*(sin(f * t )') + msg_q.*(cos(f * t)'))';
else
modulated(k,:) = (msg_i.*(sin(f * t )') + 1i*msg_q.*(cos(f * t)')).';
end
end
```

## Plot the results in a pretty display... with titles!

```    if doplot == 1
figure;             % Create a new plot figure
for k = 1:m
% Plot the results
subplot( 2,1,1 );   % Create a subplot frame inside the figure with
% 2 horizontal plots
if ~docomplex
plot( modulated(k,:) );  % plot the modulated data
else
plotiq( modulated(k,:) );% plot the modulated data
end

% Set the axes limits for the y axis... cause I HATE how MATLAB does
% this by default.
ylim( [-1.5 1.5] );
str = sprintf( 'QPSK Modulated Message : %d of %d', k, m );
title( str );               % Give it a title.

% Move to the next frame in the subplot
subplot(2,1,2);
plot( msg(k,:) );

% Set the ylimit so you can see the top of the msg bits... otherwise
% they're unviewable.
ylim( [-0.5 1.5] );
str = sprintf( 'Original Message Bits : Message %d of %d', k, m );
title( str );               % Give it a title.

if k ~= m
fprintf( 'Press space bar or enter to move on to the next plot\n' );
pause;
end
end
end
```
```end

function plotiq( t, str )
%PLOTIQ Plots real and imaginary parts of a signal
%   Just saving typing...
narginchk(1,2);

plot(real(t));
hold on;
plot(imag(t), 'r');
hold off;

if (nargin == 2)
title(str);
end

legend('I', 'Q');
end
```