Code covered by the BSD License

# A Few Modulations

by

### Jared (view profile)

ASK, BPSK, FSK and QPSK modulations done by hand.

bpsk_mod

## Contents

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

## A function to perform Binary Phase Shift Keying

```     Using good form and properly vectorized code, we generate the BPSK
sequence of the msg passed from user land.  Plots are generated to
show the result generated from the original bits.```
```     modulated = BPSK_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 = BPSK_MOD( msg, samples_per_symbol ) The user can set the number of samples
per symbol in the final modulated carrier.```
```     modulated = BPSK_MOD( msg, samples_per_symbol, do_plot ) If the user wants to turn off
the plotting, just set the third argument to anything.```
```     Example :
>> msg = [1 0 0 0 1 1 1 0 1];
>> bpsk_mod( msg );
** Poof... magic plots **```
```     Example #2 :
>> msg = [[1 0 0 0 1 1 1 0 1]; [0 1 0 0 1 0 1 0 1]];
>> bpsk_mod( msg );
** Poof... more magic plots **```

```    % 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 = 0;
end
```
```Error using bpsk_mod (line 31)
Not enough input arguments.
```

## Variable Declarations

```    % Hz   Frequency of the carrier signal
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_bit.  i.e. 0->2*pi in 100 steps, evenly divided.
t=0:2*pi/(samples_per_symbol-1):2*pi;

modulated = zeros( m, samples_per_symbol*n );
```

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

This is a little bit of MATLAB magic. 'repmat' stands for replicate matrix. So, now 't' consists of cycles of 0->2*pi. There are as many cycles from 0->2*pi as we have bits in the original msg.

Alternatively, you could do this the n00b way and make a for loop like this...

temp( = []; % Make a matrix with scope outside the for loop. for n = 1:length(msg) temp = [temp t]; <---- This is matrix concatenation... end t = temp;

But one piece of advice : You should avoid for loops like the plague in MATLAB. There is always a "vectorized" way to accomplish the same task in MATLAB, and for loops are slow in m-code, while vectorization is blazing fast. Also, the for loop grows an array dynamically which also incurs memory penalties and is slow and not good practice. In fact, MATLAB's lint tool has now started warning about that. n00bish. But repmat is pro.

```    t = repmat( t, 1, n );

% Now we need to oversample our msg.  This is for convenience in the
% multiply later.  i.e. we want our 10011101 to look like...
% 1111111 0000000 000000 1111111 11... etc.  We want as many
% replications of the bits as we're oversampling... so samples_per_bit.
% However, we've replicated the vector as follows...
% 1 0 0 1 1 1 0 1
% 1 0 0 1 1 1 0 1
% . . . . . . . .
% <samples_per_bit times>
% . . . . . . . .
% 1 0 0 1 1 1 0 1
%
% This is mainly because there's (amazingly) not a good/easy way to do
% it in MATLAB.  (Without the communications toolbox's 'rectpulse'.)
for k = 1:m
temp = repmat( msg(k,:), samples_per_symbol, 1);

% So it takes two steps to perform our oversample of the data.
% This function reshapes that matrix of data by running
% down the columns and placing the data into a single long vector, thus
% accomplishing the goal of replicating the bits samples_per_bit times.
%
% The -1 at the end is to map the signal from 0,1 (which would create
% OOK) to -1, 1 which creates BPSK.  Take it out to see the difference.
msg_bits = reshape( temp, samples_per_symbol*n, 1)*2 - 1;

% The following would also have worked, but it's even harder to explain
% how it's doing the same thing...
%
% msg = msg(ones(1,samples_per_bit), :);
% msg = msg(:)*2 - 1;
%
% Alternatively, if you have the comms toolbox :
%
% msg = rectpulse( msg, samples_per_bit );

% Now we generate our carrier sine wave.  Frequency * 0->2*pi over and
% over again.  It makes a sin wave.  :)  The ' at the end transposes
% the result from a row vector to a column vector so we can easily
% multiply in the next step.
carrier = sin(f * t )';

% This is the actual modulation step.  Here we do a point by point
% multiply ".*"  This multiplies modulated(1) = msg(1) * carrier(1) and
% modulated(2) = msg(2) * carrier(2) ... modulated(n) = msg(n) * carrier(n).
% The "*" operator does dot products and matrix multiplies, and in this
% case, we want the point by point multiply instead.
%
% Regarding the normal * operator, you'll end up having endless
% headaches with it as it strictly adheres to the rules of linear
% algebra.  So, for example, strictly speaking, if we were to try to
% dot product (*) the following vectors, it would fail since they're
% both column vectors.  For dot product to work, one would have to be a
% column vector, and one a row vector... and they'd also have to be the
% same length.  You can also use the * operator on matrices, but again,
% you must strictly adhere to linear algebra rules.  For example, a 3x2
% matrix may be multiplied by a 2x3 matrix only.  For example...
%
% >> a = ones(2,3)
% a =
%      1     1     1
%      1     1     1
% >> b = ones(3,2)
% b =
%      1     1
%      1     1
%      1     1
% >> a*b
% ans =
%      3     3
%      3     3
%
modulated(k,:) = msg_bits .* carrier;
end
```

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

```    if doplot == 1
% Plot the results
figure;                     % Create a new plot figure
for k = 1:m
subplot( 2,1,1 );           % Create a subplot frame inside the figure with
% 2 horizontal plots
plot( modulated(k,:) );     % plot the modulated data
% Set the axes limits for the y axis... cause I HATE how MATLAB does
% this by default.
ylim( [(min(modulated(k,:)) - 0.5) (max(modulated(k,:) + 0.5))] );
str = sprintf( 'BPSK Modulated Message : %d of %d', k, m );
title( str );               % Give it a title.
subplot(2,1,2);             % Move to the next frame in the subplot
msg(k,:) = msg(k,:) - 1;
plot( msg(k,:) );           % Plot our msg, remembering to subtract 1 to make
% it 0->1 bits instead of 1->2

% Set the ylimit so you can see the top of the msg bits... otherwise
% they're unviewable.
ylim( [(min(msg(k,:)) - 0.5) (max(msg(k,:)) + 0.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
```