Use Pulse Shaping on 16-QAM Signal
This example extends the Examine 16-QAM Using MATLAB example to perform pulse shaping and raised cosine filtering by using a pair of square-root raised cosine (RRC) filters. The
rcosdesign function creates the filters. BER performance can be improved by adding forward error correction (FEC) to the communication link. To add FEC to the communications link with pulse shape filtering example, see the Use Forward Error Correction on 16-QAM Signal example.
This example shows how to process a binary data stream by using a communications link that consists of a baseband modulator, channel, demodulator, and pulse shaping and raised cosine filtering. The example displays a portion of the random data in a stem plot, displays the transmitted and received signals in constellation diagrams, and computes the bit error rate (BER).
Establish Simulation Framework
Define simulation parameters for a 16-QAM modulation scheme with raised cosine filtering, and an AWGN channel.
M = 16; % Modulation order k = log2(M); % Number of bits per symbol numBits = 3e5; % Number of bits to process sps = 4; % Number of samples per symbol (oversampling factor)
Create RRC Filter
Set the RRC filter parameters.
filtlen = 10; % Filter length in symbols rolloff = 0.25; % Filter rolloff factor
rcosdesign function to create an RRC filter.
rrcFilter = rcosdesign(rolloff,filtlen,sps);
Use the FVTool to display the RRC filter impulse response.
Compute System BER
rng default; % Use default random number generator dataIn = randi([0 1],numBits,1); % Generate vector of binary data
Reshape the input vector into a matrix of 4-bit binary data. Then, use the
bi2de function to convert the data into integer symbols.
dataInMatrix = reshape(dataIn,length(dataIn)/k,k); % Reshape data into binary 4-tuples dataSymbolsIn = bi2de(dataInMatrix); % Convert to integers
Apply 16-QAM modulation using the
dataMod = qammod(dataSymbolsIn,M);
upfirdn function to upsample the signal by the oversampling factor and apply the RRC filter. The
upfirdn function pads the upsampled signal with zeros at the end to flush the filter. Then, the function applies the filter.
txFiltSignal = upfirdn(dataMod,rrcFilter,sps,1);
Using the number of bits per symbol (
k) and the number of samples per symbol (
sps), convert the ratio of energy per bit to noise power spectral density (
EbNo) to an SNR value for use by the
EbNo = 10; snr = EbNo + 10*log10(k) - 10*log10(sps);
Pass the filtered signal through an AWGN channel.
rxSignal = awgn(txFiltSignal,snr,'measured');
upfirdn function on the received signal to downsample and filter the signal. Downsample by using the same oversampling factor applied for upsampling the transmitted signal. Filter by using the same RRC filter applied to the transmitted signal.
Each filtering operation delays the signal by half of the filter length in symbols,
filtlen/2. So, the total delay from transmit and receive filtering equals the filter length,
filtlen. For the BER computation, the transmitted and received signals must be the same size and you must account for the delay between the transmitted and received signal. Remove the first
filtlen symbols in the decimated signal to account for the cumulative delay of the transmit and receive filtering operations. Remove the last
filtlen symbols in the decimated signal to ensure the number of samples in the demodulator output matches the number of samples in the modulator input.
rxFiltSignal = upfirdn(rxSignal,rrcFilter,1,sps); % Downsample and filter rxFiltSignal = rxFiltSignal(filtlen + 1:end - filtlen); % Account for delay
qamdemod function to demodulate the received filtered signal.
dataSymbolsOut = qamdemod(rxFiltSignal,M);
Convert the recovered integer symbols into binary data by using the
dataOutMatrix = de2bi(dataSymbolsOut,k); dataOut = dataOutMatrix(:); % Return data in column vector
Determine the number of errors and the associated BER by using the
[numErrors,ber] = biterr(dataIn,dataOut); fprintf('\nFor an EbNo setting of %3.1f dB, the bit error rate is %5.2e, based on %d errors.\n', ... EbNo,ber,numErrors)
For an EbNo setting of 10.0 dB, the bit error rate is 1.83e-03, based on 550 errors.
Visualize Filter Effects
To visualize the filter effects in an eye diagram, reduce the setting and regenerate the received data. Visualizing a high SNR signal with no other multipath effects, you can use eye diagrams to highlight the intersymbol interference (ISI) reduction at the output for the pair of pulse shaping RRC filters. The RRC filter does not have zero-ISI until it is paired with the second RRC filter to form in cascade a raised cosine filter.
EbNo = 20; snr = EbNo + 10*log10(k) - 10*log10(sps); rxSignal = awgn(txFiltSignal,snr,'measured'); rxFiltSignal = upfirdn(rxSignal,rrcFilter,1,sps); % Downsample and filter rxFiltSignal = rxFiltSignal(filtlen + 1:end - filtlen); % Account for delay
Create an eye diagram for a portion of the filtered noiseless signal to visualize the effect of the pulse shaping. The transmitted signal has RRC filtering and shows ISI as a narrowing of the eye-opening.
Displaying the eye diagram of the signal after the channel noise shows the signal with RRC filtering and noise. The noise level causes further narrowing of the eye diagram eye-opening.
Displaying the eye diagram of the signal after the receive filtering is applied shows the signal with raised cosine filtering. The wider eye diagram eye-openings, the signal has less ISI with raised cosine filtering as compared to the signal with RRC filtering.
Create a constellation diagram of the received signal before and after filtering. Scale the received signal by the square root of the number of samples per symbol to normalize the transmit and receive power levels.
scatplot = scatterplot(sqrt(sps)*... rxSignal(1:sps*5e3),... sps,0); hold on; scatterplot(rxFiltSignal(1:5e3),1,0,'bx',scatplot); title('Received Signal, Before and After Filtering'); legend('Before Filtering','After Filtering'); axis([-5 5 -5 5]); % Set axis ranges hold off;