%
% signal power and adjacent channel interference computation
%

% Kalle Ruttik
% 20.11.2012

clear all
close all

% generate random BPSK modulated data
nData=20000;                           % number of input data bits
in_data=randi([0 1],20000,1);          % addresses of random data, used in modulation
hMod=comm.RectangularQAMModulator(2);  % modulator
mod_data=step(hMod,in_data);           % modulation          

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% shaping the data with rectangular shaping filter
%
nSamplesPerSymbol=16;
tx_rect_shaped_mod_data=rectpulse(mod_data,nSamplesPerSymbol);%/sqrt(nSamplesPerSymbol);
SamplingRate=5e6*nSamplesPerSymbol;
rectACPR = comm.ACPR('SampleRate', SamplingRate);   % create function that computes signal powers 
rectACPR.MainChannelFrequency = 0;
rectACPR.MainMeasurementBandwidth = 5e6;            
rectACPR.AdjacentChannelOffset = [-10 -5 5 10]*1e6; % center frequencies of the adjacent channels
rectACPR.AdjacentMeasurementBandwidth = 5e6;
rectACPR.MainChannelPowerOutputPort = true;
rectACPR.AdjacentChannelPowerOutputPort = true;


%ACPR - adjacent channel power ratio (leakage to adjacent channel)
[ACPR_rect_fitered_dB, mainChannelPower_rect, adjChannelPower_rect] = ...
    step(rectACPR,tx_rect_shaped_mod_data)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% shaping the data with rectangular shaping filter
%
% filter generation
nSym=6;                                 % how many symbols the filter spans in both sides
                                        % of the center symbol
loc=-nSym:1/nSamplesPerSymbol:nSym;     % positions where the filter coefficient are computed    
gt_sinc=sin(pi*loc)./(pi*loc);           % generation of the sinc
gt_sinc(nSym*nSamplesPerSymbol+1)=1;
%gt_sinc=(gt_sinc./sqrt(sum(gt_sinc.^2)));  % power of the filter is normalized to 1

mod_data_upsampled=zeros(1,nData*nSamplesPerSymbol);
mod_data_upsampled(1:nSamplesPerSymbol:end)=mod_data;

tx_sinc_shaped_mod_data=(filter(gt_sinc,1,mod_data_upsampled))';
sincACPR = comm.ACPR('SampleRate', SamplingRate);   % create function that computes signal powers 
sincACPR.MainChannelFrequency = 0;
sincACPR.MainMeasurementBandwidth = 5e6;            
sincACPR.AdjacentChannelOffset = [-10 -5 5 10]*1e6; % center frequencies of the adjacent channels
sincACPR.AdjacentMeasurementBandwidth = 5e6;
sincACPR.MainChannelPowerOutputPort = true;
sincACPR.AdjacentChannelPowerOutputPort = true;


%ACPR - adjacent channel power ratio (leakage to adjacent channel)
[ACPR_sinc_fitered_dB, mainChannelPower_sinc, adjChannelPower_sinc] = ...
    step(sincACPR,tx_sinc_shaped_mod_data)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OFDM modulated data
%

% OFDM signal generation
% Generates multiple OFDM symbols and set them into one long data vector
% FFT is 1024 but data is only in 600 carriers
% the bandwidth of the 601 carriers is 5e6 (center carrier is zero)

nFFT=1024;                          % size of the FFT
nData=600;                          % amount of data to be transmitted
% plotting the power spectrum
F_ofdm=5e6/601*1024;                              % data rate frequncy
SamplingRate=F_ofdm*nSamplesPerSymbol;

% mapping data to the frequency vector
% center frequency is zero 
% Data is allocated to be around zero frequency
% half data is in negative side, half in positive side.
data_OFDM=zeros(1,nFFT);             % data vector in frequency domain
nSamplesPerSymbol=16;               % in current code has to be even number
nOFDMsymbols=16;                    % how long is the signal in terms of OFDM symbols 
                                    % only one of the symbols has data,
                                    % rest are set to zero
nPaddedZeros=(nOFDMsymbols-1)*nFFT*nSamplesPerSymbol;    % how many zeros are added to the end of the OFDM symbol vector

% Extends the spectrum to correspond to oversampling rate
data_OFDM_oversampled=zeros(1,nSamplesPerSymbol*nFFT); % allocates the vector
locData=((nSamplesPerSymbol/2*nFFT+1):(nSamplesPerSymbol/2+1)*nFFT)-1/2*nFFT; % computes the locations of the data in the oversampling vector

for i1=1:nOFDMsymbols
in_data=(2*randi([0 1],nData,1)-1)*nData;   % BPSK modulated data
data_OFDM((512+2):(512+nData/2+1))=in_data(nData/2+1:nData);
data_OFDM((512-nData/2+1):(512))=in_data(1:nData/2);

data_OFDM_oversampled(locData)=data_OFDM; % allocates the data

tx_OFDM_in_time_mod_data(((i1-1)*nFFT*nSamplesPerSymbol+1):(i1*nFFT*nSamplesPerSymbol))=ifft(fftshift(data_OFDM_oversampled));
end
tx_OFDM_in_time_mod_data=conj(tx_OFDM_in_time_mod_data)';

ofdmACPR = comm.ACPR('SampleRate', SamplingRate);   % create function that computes signal powers 
ofdmACPR.MainChannelFrequency = 0;
ofdmACPR.MainMeasurementBandwidth = 5e6;            
ofdmACPR.AdjacentChannelOffset = [-10 -5 5 10]*1e6; % center frequencies of the adjacent channels
ofdmACPR.AdjacentMeasurementBandwidth = 5e6;
ofdmACPR.MainChannelPowerOutputPort = true;
ofdmACPR.AdjacentChannelPowerOutputPort = true;


%ACPR - adjacent channel power ratio (leakage to adjacent channel)
[ACPR_ofdm_fitered_dB, mainChannelPower_ofdm, adjChannelPower_ofdm] = ...
    step(ofdmACPR,tx_OFDM_in_time_mod_data)





