clear all;
close all;

%........................................................................
% Initiation
%........................................................................

%.......... PARAMETERS..........................


Number_of_subcarriers = 256; 
cp_len = Number_of_subcarriers*0.25;
modulation = 4;
symbol_size = 200;
bitspersymbol = log2(modulation);
Data_bits = Number_of_subcarriers*symbol_size*bitspersymbol; %Data_bits 102400

%Generate Random bits
InputPort1 = randi([0 1],Data_bits,1); %Generates bits in parallel
OutputPort1 = InputPort1
reshape_data = reshape(InputPort1,bitspersymbol,length(InputPort1)/2); %Generates data into 2x51200
decidata = bi2de(reshape_data'); %Generates data between 0 and 3
%Mapping
%pi/4 set to default and BitInput set to false and BitInput set to false
%because of column Vector between 0 and 3
hModulator = comm.QPSKModulator('BitInput', false,'PhaseOffset', pi/4); 

hmod = step(hModulator,decidata); %hmod Modulated
% scatterplot(hmod)
%serial to parallel of modulated data 
S2P = reshape(hmod.',Number_of_subcarriers,symbol_size);

cp_start = Number_of_subcarriers - cp_len;

for i=1:symbol_size    
ifft_Subcarrier(:,i) = ifft((S2P(:,i)),Number_of_subcarriers);%IFFT of 256
for j = 1:cp_len
cyclic_prefix(j,i) = ifft_Subcarrier(cp_start+j,i);%cyclic prefix of 64
end
Append_prefix(:,i) = vertcat( cyclic_prefix(:,i), ifft_Subcarrier(:,i));%Append Prefix of 256+64
%Appends prefix to each subcarriers
end

%convert to serial stream for transmission of signal
[rows_Append_prefix, cols_Append_prefix]=size(Append_prefix);
len_ofdm_data = rows_Append_prefix*cols_Append_prefix;% ofdm data 320x200

%Signal transmitted OFDM
ofdm_signal = reshape(Append_prefix, 1, len_ofdm_data);
%figure(2),plot(real(ofdm_signal)); xlabel('Time'); ylabel('Amplitude');
%title('OFDM Signal');grid on;

%..............................................................................

%..............................................................................
%...................AWGN........................

channelOutput = awgn(ofdm_signal.', 10, 'measured');

%hPO = comm.PhaseFrequencyOffset('PhaseOffset',45,'FrequencyOffset',0);
%channelOutput = step(hPO,channelOutput1.');
%......Series to parallel......................
recvd_signal_paralleled = reshape(channelOutput,rows_Append_prefix, cols_Append_prefix);
%......................................................................

%.......................................................................
%....... Remove cyclic prefix...........................................
recvd_signal_paralleled(1:cp_len,:)=[];

%..........................................................................
%FFT for received signal
for i=1:symbol_size
fft_data(:,i) = fft(recvd_signal_paralleled(:,i),Number_of_subcarriers);
end

%.... Zero Forcing Equalization...........
Tx_signal = S2P;
A = fft_data(:,1)./Tx_signal(:,1);
A1 = fft_data(:,2)./Tx_signal(:,2);
A2 = fft_data(:,199)./Tx_signal(:,199);
A3 = fft_data(:,200)./Tx_signal(:,200);
scatterplot(fft_data(:,1));
A_average = (A+A1+A2+A3)/4;

for a = 1:symbol_size
Division(:,a) = ((fft_data(:,a))./(A_average));
end


%Reconstructed signal ...................................................
recvd_serial_data = reshape(Division,(symbol_size*Number_of_subcarriers),1);
scatterplot(recvd_serial_data);

%DeMapping...................................................
hDemod = comm.QPSKDemodulator('PhaseOffset',pi/4);
demodulatedData = step(hDemod,recvd_serial_data);
demodulate2bi = de2bi(demodulatedData);
demodulatereshap = reshape(demodulate2bi',length(InputPort1),1);
[No_of_error,BER] = biterr(InputPort1,demodulatereshap);



