MATLAB Answers

Error in FBMC vs. OFDM Modulation of Mathworks

19 views (last 30 days)
Javier Cáceres
Javier Cáceres on 4 Jan 2018
Commented: Peter Liu on 22 Mar 2019
In this code, having a transmission without noise, the transmitted bits should be the same as the received bits.
The inpData variable is different than the rxBits variable. Example: inpData [1 0 1 1] .... rxBits [0 0 1 0]. Please help
s = rng(211); % Set RNG state for repeatability
%%System Parameters
numFFT = 1024; % Number of FFT points
numGuards = 212; % Guard bands on both sides
K = 4; % Overlapping symbols, one of 2, 3, or 4
numSymbols = 8; % Simulation length in symbols
bitsPerSubCarrier = 4; % 2: 4QAM, 4: 16QAM, 6: 64QAM, 8: 256QAM
snrdB =0; % SNR in dB
% Prototype filter
switch K
case 2
HkOneSided = sqrt(2)/2;
case 3
HkOneSided = [0.911438 0.411438];
case 4
HkOneSided = [0.971960 sqrt(2)/2 0.235147];
otherwise
return
end
% Build symmetric filter
Hk = [fliplr(HkOneSided) 1 HkOneSided];
% QAM symbol mapper
qamMapper = comm.RectangularQAMModulator(...
'ModulationOrder', 2^bitsPerSubCarrier, ...
'BitInput', true, ...
'NormalizationMethod', 'Average power');
% Transmit-end processing
% Initialize arrays
L = numFFT-2*numGuards; % Number of complex symbols per OFDM symbol
KF = K*numFFT;
KL = K*L;
dataSubCar = zeros(L, 1);
dataSubCarUp = zeros(KL, 1);
sumFBMCSpec = zeros(KF*2, 1);
sumOFDMSpec = zeros(numFFT*2, 1);
numBits = bitsPerSubCarrier*L/2; % account for oversampling by 2
inpData = zeros(numBits, numSymbols);
rxBits = zeros(numBits, numSymbols);
txSigAll = complex(zeros(KF, numSymbols));
symBuf = complex(zeros(2*KF, 1));
% Loop over symbols
for symIdx = 1:numSymbols
% Generate mapped symbol data
inpData(:, symIdx) = randi([0 1], numBits, 1);
modData = qamMapper(inpData(:, symIdx));
% OQAM Modulator: alternate real and imaginary parts
if rem(symIdx,2)==1 % Odd symbols
dataSubCar(1:2:L) = real(modData);
dataSubCar(2:2:L) = 1i*imag(modData);
else % Even symbols
dataSubCar(1:2:L) = 1i*imag(modData);
dataSubCar(2:2:L) = real(modData);
end
% Upsample by K, pad with guards, and filter with the prototype filter
dataSubCarUp(1:K:end) = dataSubCar;
dataBitsUpPad = [zeros(numGuards*K,1); dataSubCarUp; zeros(numGuards*K,1)];
X1 = filter(Hk, 1, dataBitsUpPad);
% Remove 1/2 filter length delay
X = [X1(K:end); zeros(K-1,1)];
% Compute IFFT of length KF for the transmitted symbol
txSymb = fftshift(ifft(X));
% Transmitted signal is a sum of the delayed real, imag symbols
symBuf = [symBuf(numFFT/2+1:end); complex(zeros(numFFT/2,1))];
symBuf(KF+(1:KF)) = symBuf(KF+(1:KF)) + txSymb;
% Compute power spectral density (PSD)
currSym = complex(symBuf(1:KF));
[specFBMC, fFBMC] = periodogram(currSym, hann(KF, 'periodic'), KF*2, 1);
sumFBMCSpec = sumFBMCSpec + specFBMC;
% Store transmitted signals for all symbols
txSigAll(:,symIdx) = currSym;
end
% Plot power spectral density
sumFBMCSpec = sumFBMCSpec/mean(sumFBMCSpec(1+K+2*numGuards*K:end-2*numGuards*K-K));
plot(fFBMC-0.5,10*log10(sumFBMCSpec));
grid on
axis([-0.5 0.5 -180 10]);
xlabel('Normalized frequency');
ylabel('PSD (dBW/Hz)')
title(['FBMC, K = ' num2str(K) ' overlapped symbols'])
set(gcf, 'Position', figposition([15 50 30 30]));
for symIdx = 1:numSymbols
inpData2 = randi([0 1], bitsPerSubCarrier*L, 1);
modData = qamMapper(inpData2);
symOFDM = [zeros(numGuards,1); modData; zeros(numGuards,1)];
ifftOut = sqrt(numFFT).*ifft(ifftshift(symOFDM));
[specOFDM,fOFDM] = periodogram(ifftOut, rectwin(length(ifftOut)), ...
numFFT*2, 1, 'centered');
sumOFDMSpec = sumOFDMSpec + specOFDM;
end
% Plot power spectral density (PSD) over all subcarriers
sumOFDMSpec = sumOFDMSpec/mean(sumOFDMSpec(1+2*numGuards:end-2*numGuards));
figure;
plot(fOFDM,10*log10(sumOFDMSpec));
grid on
axis([-0.5 0.5 -180 10]);
xlabel('Normalized frequency');
ylabel('PSD (dBW/Hz)')
title(['OFDM, numFFT = ' num2str(numFFT)])
set(gcf, 'Position', figposition([46 50 30 30]));
% QAM demodulator
qamDemod = comm.RectangularQAMDemodulator(...
'ModulationOrder', 2^bitsPerSubCarrier, ...
'BitOutput', true, ...
'NormalizationMethod', 'Average power');
BER = comm.ErrorRate;
% Process symbol-wise
for symIdx = 1:numSymbols
rxSig = txSigAll(:, symIdx);
% Add WGN
%rxNsig = awgn(rxSig, snrdB, 'measured');
% Perform FFT
rxf = fft(fftshift(rxSig));
% Matched filtering with prototype filter
rxfmf = filter(Hk, 1, rxf);
% Remove K-1 delay elements
rxfmf = [rxfmf(K:end); zeros(K-1,1)];
% Remove guards
rxfmfg = rxfmf(numGuards*K+1:end-numGuards*K);
% OQAM post-processing
% Downsample by 2K, extract real and imaginary parts
if rem(symIdx, 2)
% Imaginary part is K samples after real one
r1 = real(rxfmfg(1:2*K:end));
r2 = imag(rxfmfg(K+1:2*K:end));
rcomb = complex(r1, r2);
else
% Real part is K samples after imaginary one
r1 = imag(rxfmfg(1:2*K:end));
r2 = real(rxfmfg(K+1:2*K:end));
rcomb = complex(r2, r1);
end
% Normalize by the upsampling factor
rcomb = (1/K)*rcomb;
% Demapper: Perform hard decision
rxBits(:, symIdx) = qamDemod(rcomb);
end
% Measure BER with appropriate delay
BER.ReceiveDelay = bitsPerSubCarrier*KL;
ber = BER(inpData(:), rxBits(:));
% Display Bit error
disp(['FBMC Reception for K = ' num2str(K) ', BER = ' num2str(ber(1)) ...
' at SNR = ' num2str(snrdB) ' dB'])
% Restore RNG state
rng(s);

Answers (1)

abdullah qasim
abdullah qasim on 16 Jan 2019
this code calculates BER for one sample, not for all samples so give one value for BER.
so we must do it loop (for loop) to calculate all values of ber and give the full sketch to BER to SNR

  1 Comment

Peter Liu
Peter Liu on 22 Mar 2019
Hi. Do you know why it measures BER with the delay bitsPerSubCarrier*KL ? Does it mean that all the recieved data lags behind the transmitted data by bitsPerSubCarrier*KL samples?

Sign in to comment.

Sign in to answer this question.


Translated by