%
% OFDMM signal spectrum
%

% Kalle Ruttik
% 19.11.2012

clear all 
close all

nFFT=1024;                          % size of the FFT
nData=600;                          % amount of data to be transmitted
inData=2*randi([0 1],nData,1)-1;   % BPSK modulated data

% 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
data_OFDM((nFFT/2-nData/2+1):(nFFT/2))=inData(1:nData/2);
data_OFDM((nFFT/2+2):(nFFT/2+nData/2+1))=inData(nData/2+1:nData);

nSamples_per_symbol=8;               % in current code has to be even number
                                    % this corresponds to extension of the
                                    % spectrum in frequency domain
nOFDM_symbols=16;                     % how long is the signal in terms of OFDM symbols
                                    % this corresponds to extension in time
                                    % domain
                                    % only one of the symbols has data,
                                    % rest are set to zero
                                    
nPadded_zeros=(nOFDM_symbols-1)*nFFT*nSamples_per_symbol;    % 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,nSamples_per_symbol*nFFT); % allocates the vector in frequency
locData=((nSamples_per_symbol/2*nFFT+1):(nSamples_per_symbol/2+1)*nFFT)-1/2*nFFT; % computes the locations of the data in the oversampling vector
data_OFDM_oversampled(locData)=data_OFDM; % allocates the data


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% time domain signal 
%

B=5e6;                                            % signal bandwidth
F_ofdm=B/nData*nFFT;                              % symbol frequency 
                                                                                    
sampling_rate=F_ofdm*nSamples_per_symbol;            % frequency of samples
T=1/sampling_rate;                                 % time interval between samples

data_OFDM_in_time=ifft(ifftshift(data_OFDM_oversampled)); % time domain signal
% adding some zeros at the end of the time signal
% this has the effect of creating frequency bins between the OFDM carriers.
% Why?
data_OFDM_in_time_extended=[data_OFDM_in_time zeros(1,nPadded_zeros)]; 


time_moments_of_samples = T*(0:(length(data_OFDM_in_time_extended)-1));
data_spectrum_OFDM_oversampled_extended=fftshift(fft(data_OFDM_in_time_extended));

figure(1)
scale1=(nSamples_per_symbol); % scaling due to oversampling
plot(time_moments_of_samples,real(data_OFDM_in_time_extended)*scale1,'k-s');
hold on
plot(time_moments_of_samples,imag(data_OFDM_in_time_extended)*scale1,'r-s');
grid
xlabel('time samples');
ylabel('magnitude');
legend('real part','imag part');
axis([0 10*nSamples_per_symbol*T -0.1 0.1]);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% frequency domain signal
%

figure(2)
FFT_bins_frequencies=(-(sampling_rate/2-F_ofdm/(nOFDM_symbols*nFFT)):F_ofdm/(nOFDM_symbols*nFFT):sampling_rate/2);
plot(FFT_bins_frequencies/1e6,10*log10(1/sampling_rate*abs(data_spectrum_OFDM_oversampled_extended).^2))
grid
xlabel('frequency [MHz]');
ylabel('magnitude [dB]');
axis([-40 40 -150 -60]);
