function [txObj] = WIFI_upconverter(txObj, wifi_params, agOut, agParams, useGPU)
% Function implementing upconversion and filtration in LTE
% Author:   Jiri Milos
% Date:     2014/07/03
% Brno University of Technology, DREL
%
% Inputs:   BS_output ... structure of outputs from base station
%           LTE_params ... structure of simulator parameters
% Outputs:  BS_output

% fs = agParams.Fs; % zkontrolovat pocet bitu vygenerovanych, nosnou frekvenci, korektni spektra
fs = wifi_params.Fs;
fc = wifi_params.coexistence.fc;
delay = 30;
% delay = 10;
rolloff = 0.05; %0.22;

B_wifi = wifi_params.mapping.bw_sys;
fInterfOffset = 0;
% oversampling factor
oversamp = 2*ceil((fc+(B_wifi/2)+fInterfOffset)/fs);

% hpulse = rcosine(fs,oversamp*fs,'normal',rolloff,delay);
hpulse = rcosine(fs,oversamp*fs,'sqrt',rolloff,delay);

% Signal = [txObj.output.x_s, zeros(1,wifi_params.coexistence.n_rem_bits)]; % neni potreba
Signal = txObj.output.x_s; % 
% kompenzace zpozdeni filtru
InphaseSignal = [real(Signal), zeros(1,delay*2)];
QuadratureSignal = [imag(Signal), zeros(1,delay*2)];
clear Signal % ------------------------------------------------------------
% % rectangular window
% InphaseSignalRect = rectpulse(InphaseSignal,oversamp);
% QuadratureSignalRect = rectpulse(QuadratureSignal,oversamp);
% upsample
InphaseSignal = upsample(InphaseSignal,oversamp);
QuadratureSignal = upsample(QuadratureSignal,oversamp);
% filtrace
if useGPU
    % Inphase
    CUDA_real = gpuArray(InphaseSignal);                % uložení do GPU
    InphaseSignalFiltCUDA=filter(hpulse,1,CUDA_real);    % výpočet
    InphaseSignalFilt = gather(InphaseSignalFiltCUDA);          % uložení do workspace
    % vymazání proměných GPU pro uvlonění paměti
    clear CUDA_real InphaseSignalFiltCUDA
    % Quadrature
    CUDA_imag = gpuArray(QuadratureSignal);                % uložení do GPU
    QuadratureSignalFiltCUDA=filter(hpulse,1,CUDA_imag);    % výpočet
    QuadratureSignalFilt = gather(QuadratureSignalFiltCUDA);          % uložení do workspace
    % vymazání proměných GPU pro uvlonění paměti
    clear CUDA_imag QuadratureSignalFiltCUDA
else
    InphaseSignalFilt = filter(hpulse,1,InphaseSignal);
    QuadratureSignalFilt = filter(hpulse,1,QuadratureSignal);
end

% upkonverze
clear InphaseSignal QuadratureSignal
tt = (0:length(InphaseSignalFilt)-1)*((1/fs)/oversamp);
% InphaseNosna = sqrt(2)*cos(2*pi*fc*tt);
% QuadratureNosna = sqrt(2)*sin(2*pi*fc*tt);
InphaseNosna = cos(2*pi*fc*tt);
QuadratureNosna = sin(2*pi*fc*tt);

% InphaseNosna2 = sqrt(2)*cos(2*pi*(fc/2)*tt);
% QuadratureNosna2 = sqrt(2)*sin(2*pi*(fc/2)*tt);

txInphase = InphaseSignalFilt.*InphaseNosna;
% txInphase2 = InphaseSignalRect.*InphaseNosna2;
clear InphaseSignalFilt InphaseNosna
txQuadrature = QuadratureSignalFilt.*QuadratureNosna;
% txQuadrature2 = QuadratureSignalRect.*QuadratureNosna2;
clear QuadratureSignalFilt QuadratureNosna

txObj.output.txUpSignal = txInphase+txQuadrature;

% rusivy = InterferenceGenerator(LTE_params,BS_output);
% rusivy = rusivy(1:length(BS_output.txSignal));


txObj.output.genie.fs = fs*oversamp;
txObj.output.genie.oversamp = oversamp;
% pxx = (1/((fs*oversamp)/2))*pwelch(BS_output.txSignal);
% f = (fs*oversamp)*(linspace(0,1,length(pxx)));
% plot(f,10*log10(pxx*1000))

% rusivy = txInphase2+txQuadrature2;
% pwelch(BS_output.txSignal+rusivy)
% tt = toc
end
