%% FUNCIÓN TRANSMISIÓN GFDM
%<TX_GFDM>

%PARÁMETROS DE RETORNO:
%sumPxxGFDM: acumulador periodogramas
%fGFDM: vector frecuencia normalizado para GFDM
%bGlat: banda de guarda lateral
%nBloq: número de bloques

%PARÁMETROS DE INGRESO:
%parametros: Estructura con parámetros de simulación

function [sumPxxGFDM,fGFDM,bGlat,nBloq]= TX_GFDM(parametros)

% Inicialización de parámetros
numTotBits =32*2*(parametros.numSub-1);%Número total de bits. Equivale a (32 bloques*2 bitsPorSubportadora*(numSubportadoras-1))
numSubSimb=parametros.numSubSimb;%Número de subsímbolos
numSubP=(parametros.numSub-1)/numSubSimb; %Número de subportadoras
pc=parametros.pc(2);%Longitud prefijo cíclico
totSubEq=floor((numSubP*parametros.tamFFT/parametros.numSub));%Total subportadoras equivalente
longSigMap=numTotBits/2;%numTotBits/bitPorSubportadora
nBloq = longSigMap/(numSubP*numSubSimb);%número de bloques
longBloq = numSubSimb * numSubP;%longitud del bloque
totNumSubSimb= numSubSimb;%número total de subsímbolos
longTotBloq = totSubEq * totNumSubSimb;%longitud total del bloque
sGFDM = zeros((nBloq*longTotBloq)+pc,1);%Inicialización señal GFDM
sumPxxGFDM=0;%Inicialización acumulador periodogramas
bGlat=(totSubEq-numSubP)/2;%Banda de guarda lateral

% Filtro coseno alzado
g=fca(totNumSubSimb,totSubEq,0.3);%equivale a fca(M,K,alpha)

% Generación datos
datosIn = generacionDatos(numTotBits)';

% Modulación QPSK
 datosQPSK=modQPSK(datosIn);

for i = 0:nBloq-1 %Iteración por cada bloque
   
    %Mapeo estructuctura KxM 
    mapSig=mapKxM(datosQPSK,longBloq,i,nBloq, numSubP, numSubSimb);%señal mapeada KxM

    %Cálculo IFFT
    sig_rep = calcIFFT_GFDM(totSubEq,totNumSubSimb,bGlat,numSubP,mapSig);%Cálculo y arreglo con repetición de matriz

    sig_sum = zeros(longTotBloq, 1);%Inicialización acumulador suma de señales
    
    for j = 1:totNumSubSimb %Iteración en subsímbolos de cada bloque
        % Conformación pulso digital 
        sCPD = sig_rep(:,j).*g;
        sCPD = circshift(sCPD, totSubEq*(j-1));
        sig_sum = sig_sum + sCPD;
    end

    % Inserción prefijo cíclico
    sig_pc = [sig_sum(end-pc+1:end); sig_sum];
    sGFDM(i*(longTotBloq+pc) + (1:longTotBloq + pc)) = sig_pc; 
   
    % Cálculo y actualización acumulador PSD
    sig_sum2=sGFDM(i*(longTotBloq+pc) + (1:longTotBloq + pc));
    [PxxGFDM,fGFDM]=periodogram(sig_sum2,[],2*length(sig_sum2),[]);
    sumPxxGFDM=sumPxxGFDM+PxxGFDM;

end


end

