%% FUNCIÓN BER FBMC
%<BER_FBMC>

%PARÁMETROS DE RETORNO:
%berN: BER estimado para valor particular en EbNo

%PARÁMETROS DE INGRESO:
%EbNoVec: Vector con valores asumidos de la relación EbNo
%parametros: Estructura con parámetros de simulación
%n: Consecutivo control ejecución de bucle

function berN=BER_FBMC(parametros, EbNoVec, n)

snrdB = EbNoVec(n);

%Inicialización de valores
KF=4*parametros.tamFFT;%Equivale a (K*tamaño_FFT)
buf_vTxFBMC=complex(zeros(4*parametros.tamFFT,parametros.numTotSimb));%Equivale a zeros(K*FFT,Número_símbolos)
bufSim=complex(zeros(2*KF,1));%buffer con valores del símbolo 
inDatos=zeros(parametros.numSub-1,parametros.numTotSimb);%Inicialización vector ingreso de datos
salDatos=zeros(parametros.numSub-1,parametros.numTotSimb);%Inicialización vector salida de datos

%*****************************TX*****************************
for ind = 1:parametros.numTotSimb %Bucle iteración parámetros en cadena TX
    
    %Generación Datos
    inDatos(:,ind)=generacionDatos(2*(parametros.numSub-1)/2);%Equivale a bitsPorSubportadora*Subportadoras/2.
    
    %Modulación QPSK
    datosQPSK=modQPSK(inDatos(:,ind));
    
    % Modulación OQAM
    datosOQAM=modOQAM(datosQPSK,ind,parametros);
    
    %Filtro NK. Incluye sobremuestreo de K muestras,inclusión de bandas de guarda y filtrado
    [X,bGIzqFBMC,bGDerFBMC, Hk]=filtroNK(datosOQAM,parametros);
    
    %Cálculo IFFT
    txSimb=fftshift(ifft(X));%Símbolo tras ejecutar IFFT. Se ejecuta de forma diferente a lo hecho en la OFDM
    
    %Sobrelapamiento y suma
    bufSim=[bufSim((parametros.tamFFT/2)+1:end);complex(zeros(parametros.tamFFT/2,1))];%corrimiento de muestras(tamFFT/2) a la izq
    bufSim(KF+(1:KF))=bufSim(KF+(1:KF))+txSimb; % %Actualización mitad final del vector con resultado de iteración actual
    vTxFBMC=complex(bufSim(1:KF));%Símbolo actual a transmitir FBMC
    buf_vTxFBMC(:,ind)=vTxFBMC;%Almacenamiento de señales transmitidas para todos los símbolos
    
end

%*****************************RX*****************************
for ind = 1:parametros.numTotSimb %Bucle iteración parámetros en cadena RX
    
    vRxFBMC = buf_vTxFBMC(:, ind); % Vector recibido
     
    %Paso de la señal a través de un canal AWGN
    vRxNFBMC = awgn(vRxFBMC, snrdB, 'measured');
    
    %Cálculo FFT
    rxSimb = fft(fftshift(vRxNFBMC)); %Símbolo tras ejecutar FFT.
    
    %Filtro NK en Recepción. Incluye filtrado, compensación retardo y
    %remoción de bandas de guarda
    rxrBG=filtroNK_Rx(Hk, rxSimb, bGIzqFBMC,bGDerFBMC);
    
    %Demodulación OQAM. Incluye submuestreo por factor 2K y extracción
    %parte real e imaginaria
    rcomb=demOQAM(ind, rxrBG);
    
    %Demodulación QPSK
    datosOut=demQPSK(rcomb);
    salDatos(:,ind)=datosOut;
    
end

    %**********************CÁLCULO BER********************
    %Equivale a la inclusión de un ReceiveDelay usando el toolbox de
    %comunicaciones para el cálculo del BER

    muRem=2*4*(parametros.numSub-1);%muestras removidas para medición apropiada de BER. Equivale a bitsPorSubportadora*K*numSubportadoras
    inDatos=inDatos(:);salDatos=salDatos(:);
    inDatos=inDatos(1:end-muRem);%Muestras remanentes del vector de datos de entrada
    salDatos=salDatos(muRem+1:end);%Muestras remanentes del vector de datos de salida
    nErrors = biterr(inDatos,salDatos);
    berN=nErrors/length(inDatos);
    
end


