function [ChanMod_output, txObj] = WIFI_downconverter(ChanMod_output, txObj, wifi_params, useGPU)
% Function implementing downconversion and filtration in WIFI
% 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 ... here for transparency (UE_input)

fs = wifi_params.Fs;
fc = wifi_params.coexistence.fc;
delay = 30;
rolloff = 0.05;

fInterfOffset = 0;
% oversampling factor
% oversamp = 2*ceil((fc+(B/2)+fInterfOffset)/fs);
oversamp = txObj.output.genie.oversamp;

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

Signal = ChanMod_output; % POTREBA VYTVORIT!!!
% downkonverze
tt = (0:length(Signal)-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);

rxInphase = Signal.*InphaseNosna;
rxQuadrature = Signal.*QuadratureNosna;

clear Signal
% inverzni filtrace
% filtrace
if useGPU
    % Inphase
    CUDA_real = gpuArray(rxInphase);                % uložení do GPU
    %     InphaseSignalFiltCUDA=filter(hpulse,0.5,CUDA_real)/oversamp;    % výpočet
    InphaseSignalFiltCUDA=filter(hpulse,0.5,CUDA_real);    % výpočet
    rxInphaseSignalFiltered = 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(rxQuadrature);                % uložení do GPU
    %     QuadratureSignalFiltCUDA=filter(hpulse,0.5,CUDA_imag)/oversamp;    % výpočet
    QuadratureSignalFiltCUDA=filter(hpulse,0.5,CUDA_imag);    % výpočet
    rxQuadratureSignalFiltered = gather(QuadratureSignalFiltCUDA);          % uložení do workspace
    % vymazání proměných GPU pro uvlonění paměti
    clear CUDA_imag QuadratureSignalFiltCUDA
else
    %     rxInphaseSignalFiltered = filter(hpulse,0.5,rxInphase)/oversamp;
    %     rxQuadratureSignalFiltered = filter(hpulse,0.5,rxQuadrature)/oversamp;
    rxInphaseSignalFiltered = filter(hpulse,0.5,rxInphase);
    rxQuadratureSignalFiltered = filter(hpulse,0.5,rxQuadrature);
end

% downsampling
rxInphaseDownsampled = downsample(rxInphaseSignalFiltered,oversamp); % downsampling a prevedeni na korektni amplitudu signalu
rxQuadratureDownsampled = downsample(rxQuadratureSignalFiltered,oversamp);

% kompenzace zpozdeni filtru
rxInphaseDownsampled = rxInphaseDownsampled(2*delay+1:end);
rxQuadratureDownsampled = rxQuadratureDownsampled(2*delay+1:end);

% prevedeni zpet na komplexni signal
ChanMod_output = rxInphaseDownsampled+1j*rxQuadratureDownsampled;

end
