function frameFout = iTNS(frameFin, frameType, TNScoeffs)
%Implementation of the reverse TNS step
%   Usage frameFout = iTNS(frameFin, frameType, TNScoeffs), where:
%       Inputs
%       - frameFin is the frame in the frequency domain, in MDCT coefficients
%       representation containing both channels of the audio stored in an
%       array of dimensions 1024X2
%       - frameType is the type of the current frame in string
%       representation, can be one of "OLS" (ONLY_LONG_SEQUENCE), "LSS"
%       (LONG_START_SEQUENCE), "ESH" (EIGHT_SHORT_SEQUENCE), "LPS"
%       (LONG_STOP_SEQUENCE)
%       - TNScoeffs is the quantized TNS coefficients array of dimensions
%       4X8 for EIGHT_SHORT_SEQUENCE frames and 4X1 otherwise
%
%       Output
%       - frameFout is the frame in the frequency domain after Temporal Noise
%       Shaping, in MDCT coefficients representation containing both channels
%       of the audio stored in an array of dimensions 1024X2

    % Declares persistent variable holding the TNS tables and initializes if empty
    persistent TNSTables;
    if isempty(TNSTables)
        TNSTables = load('TableB219.mat');
    end

    if ~strcmp(frameType, 'ESH')
        % Inverses MDCT coefficients filtering
        frameFout = filter(1, [1 TNScoeffs], frameFin);
    else
        for subFrameIndex = 1:8
            subFrame = frameFin((subFrameIndex - 1) * 128 + 1:subFrameIndex * 128);

            % Inverses MDCT coefficients filtering
            frameFout((subFrameIndex - 1) * 128 + 1:subFrameIndex * 128) = ...
                filter(1, [1 TNScoeffs((subFrameIndex - 1) * 4 + 1:subFrameIndex * 4)], subFrame);
        end
    end
end