You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
8.3 KiB
173 lines
8.3 KiB
6 years ago
|
function [frameFout, TNScoeffs] = TNS(frameFin, frameType)
|
||
|
%Implementation of the TNS step
|
||
|
% Usage [frameFout, TNScoeffs] = TNS(frameFin, frameType), 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)
|
||
|
%
|
||
|
% 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
|
||
|
% - TNScoeffs is the quantized TNS coefficients array of dimensions
|
||
|
% 4X8 for EIGHT_SHORT_SEQUENCE frames and 4X1 otherwise
|
||
|
|
||
|
% Declares constant numbers of bands for long and short windows
|
||
|
LONG_WINDOW_NUMBER_OF_BANDS = 69;
|
||
|
SHORT_WINDOW_NUMBER_OF_BANDS = 42;
|
||
|
% Declares constant order of the linear prediction filter
|
||
|
LPF_ORDER = 4;
|
||
|
% Declares constant coefficients' resolution
|
||
|
COEF_RES = 4;
|
||
|
|
||
|
% 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')
|
||
|
% Calculates the energy per band
|
||
|
bandEnergy(LONG_WINDOW_NUMBER_OF_BANDS) = 0;
|
||
|
for band = 1:LONG_WINDOW_NUMBER_OF_BANDS - 1
|
||
|
bandEnergy(band) = sumsqr(frameFin(TNSTables.B219a(band, 2) + 1:TNSTables.B219a(band + 1, 2)));
|
||
|
end
|
||
|
bandEnergy(LONG_WINDOW_NUMBER_OF_BANDS) = sumsqr( ...
|
||
|
frameFin(TNSTables.B219a(LONG_WINDOW_NUMBER_OF_BANDS, 2) + 1:...
|
||
|
TNSTables.B219a(LONG_WINDOW_NUMBER_OF_BANDS, 3) + 1));
|
||
|
|
||
|
% Calculates the normalization factors
|
||
|
|
||
|
% PROBABLY WRONG, THE ONE BELLOW SHOULD BE RIGHT AND BETTER
|
||
|
% normalizationFactor(1024) = 0;
|
||
|
% for normIndex = 1:1024
|
||
|
% bandIndices = find(TNSTables.B219a(:, 2) >= (normIndex - 1), 1);
|
||
|
% if ~isempty(bandIndices)
|
||
|
% normalizationFactor(normIndex) = sqrt(bandEnergy(bandIndices));
|
||
|
% else
|
||
|
% normalizationFactor(normIndex) = sqrt(bandEnergy(find(TNSTables.B219a(:, 3) >= normIndex - 1, 1)));
|
||
|
% end
|
||
|
% end
|
||
|
|
||
|
bandIndices = quantiz(0:1023, TNSTables.B219a(:, 2) - 1);
|
||
|
normalizationFactor = sqrt(bandEnergy(bandIndices));
|
||
|
|
||
|
% Smooths normalization factors
|
||
|
for normIndex = 1023:-1:1
|
||
|
normalizationFactor(normIndex) = (normalizationFactor(normIndex) + normalizationFactor(normIndex + 1)) / 2;
|
||
|
end
|
||
|
for normIndex = 2:1024
|
||
|
normalizationFactor(normIndex) = (normalizationFactor(normIndex) + normalizationFactor(normIndex - 1)) / 2;
|
||
|
end
|
||
|
|
||
|
% Normalizes MDCT coefficients according to each band energy
|
||
|
normalizedFrameFin = frameFin ./ normalizationFactor';
|
||
|
|
||
|
% Calculates the linear prediction coefficients
|
||
|
[linPredCoeff, ~] = lpc(normalizedFrameFin, LPF_ORDER);
|
||
|
|
||
|
% Quantizes these coefficients
|
||
|
quantizedLinPredCoeff(LPF_ORDER) = 0;
|
||
|
for coeffIndex = 2:length(linPredCoeff)
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = asin(linPredCoeff(coeffIndex));
|
||
|
if linPredCoeff(coeffIndex) >= 0
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = round(quantizedLinPredCoeff(coeffIndex - 1) * ...
|
||
|
(bitshift(1, COEF_RES - 1) - 0.5) / (pi / 2));
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = quantizedLinPredCoeff(coeffIndex - 1) / ...
|
||
|
(bitshift(1, COEF_RES - 1) - 0.5) / (pi / 2);
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = sin (quantizedLinPredCoeff(coeffIndex - 1));
|
||
|
else
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = round(quantizedLinPredCoeff(coeffIndex - 1) * ...
|
||
|
(bitshift(1, COEF_RES - 1) + 0.5) / (pi / 2));
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = quantizedLinPredCoeff(coeffIndex - 1) / ...
|
||
|
(bitshift(1, COEF_RES - 1) + 0.5) / (pi / 2);
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = sin (quantizedLinPredCoeff(coeffIndex - 1));
|
||
|
end
|
||
|
end
|
||
|
|
||
|
% Filters MDCT coefficients
|
||
|
if ~isstable(1, [1 (quantizedLinPredCoeff * (-1))])
|
||
|
error('TNS, l[79]: Inverse filter not stable!');
|
||
|
else
|
||
|
TNScoeffs = quantizedLinPredCoeff;
|
||
|
frameFout = filter([1 (quantizedLinPredCoeff * (-1))], 1, frameFin);
|
||
|
end
|
||
|
else
|
||
|
% Initializes output vectors
|
||
|
TNScoeffs(LPF_ORDER * 8) = 0;
|
||
|
frameFout(1024) = 0;
|
||
|
|
||
|
bandEnergy(SHORT_WINDOW_NUMBER_OF_BANDS) = 0;
|
||
|
for subFrameIndex = 1:8
|
||
|
subFrame = frameFin((subFrameIndex - 1) * 128 + 1:subFrameIndex * 128);
|
||
|
|
||
|
% Calculates the energy per band
|
||
|
for band = 1:SHORT_WINDOW_NUMBER_OF_BANDS - 1
|
||
|
bandEnergy(band) = sumsqr(subFrame(TNSTables.B219b(band, 2) + 1:TNSTables.B219b(band + 1, 2)));
|
||
|
end
|
||
|
bandEnergy(SHORT_WINDOW_NUMBER_OF_BANDS) = sumsqr( ...
|
||
|
subFrame(TNSTables.B219b(SHORT_WINDOW_NUMBER_OF_BANDS, 2) + 1:...
|
||
|
TNSTables.B219b(SHORT_WINDOW_NUMBER_OF_BANDS, 3) + 1));
|
||
|
|
||
|
% Calculates the normalization factors
|
||
|
normalizationFactor(128) = 0;
|
||
|
for normIndex = 1:128
|
||
|
bandIndices = find(TNSTables.B219b(:, 2) >= normIndex - 1, 1);
|
||
|
if ~isempty(bandIndices)
|
||
|
normalizationFactor(normIndex) = sqrt(bandEnergy(bandIndices));
|
||
|
else
|
||
|
normalizationFactor(normIndex) = sqrt(bandEnergy(find(TNSTables.B219b(:, 3) <= normIndex - 1, 1)));
|
||
|
end
|
||
|
end
|
||
|
|
||
|
% Smooths normalization factors
|
||
|
for normIndex = 127:-1:1
|
||
|
normalizationFactor(normIndex) = (normalizationFactor(normIndex) + normalizationFactor(normIndex + 1)) / 2;
|
||
|
end
|
||
|
for normIndex = 2:128
|
||
|
normalizationFactor(normIndex) = (normalizationFactor(normIndex) + normalizationFactor(normIndex - 1)) / 2;
|
||
|
end
|
||
|
|
||
|
% Normalizes MDCT coefficients according to each band energy
|
||
|
normalizedFrameFin = subFrame ./ normalizationFactor';
|
||
|
|
||
|
% Calculates the linear prediction coefficients
|
||
|
[linPredCoeff, ~] = lpc(normalizedFrameFin, LPF_ORDER);
|
||
|
|
||
|
% Quantizes these coefficients
|
||
|
quantizedLinPredCoeff(LPF_ORDER) = 0;
|
||
|
for coeffIndex = 1:length(linPredCoeff)
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = asin(linPredCoeff(coeffIndex));
|
||
|
if linPredCoeff(coeffIndex) >= 0
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = round(quantizedLinPredCoeff(coeffIndex - 1) * ...
|
||
|
(bitshift(1, COEF_RES - 1) - 0.5) / (pi / 2));
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = quantizedLinPredCoeff(coeffIndex - 1) / ...
|
||
|
(bitshift(1, COEF_RES - 1) - 0.5) / (pi / 2);
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = sin (quantizedLinPredCoeff(coeffIndex - 1));
|
||
|
else
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = round(quantizedLinPredCoeff(coeffIndex - 1) * ...
|
||
|
(bitshift(1, COEF_RES - 1) + 0.5) / (pi / 2));
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = quantizedLinPredCoeff(coeffIndex - 1) / ...
|
||
|
(bitshift(1, COEF_RES - 1) + 0.5) / (pi / 2);
|
||
|
quantizedLinPredCoeff(coeffIndex - 1) = sin (quantizedLinPredCoeff(coeffIndex - 1));
|
||
|
end
|
||
|
end
|
||
|
|
||
|
% Filters MDCT coefficients
|
||
|
if ~isstable(1, [1 (quantizedLinPredCoeff * (-1))])
|
||
|
error('TNS, l[79]: Inverse filter not stable!');
|
||
|
else
|
||
|
TNScoeffs((subFrameIndex - 1) * 4 + 1:subFrameIndex * 4) = quantizedLinPredCoeff;
|
||
|
frameFout((subFrameIndex - 1) * 128 + 1:subFrameIndex * 128) = ...
|
||
|
filter([1 (quantizedLinPredCoeff * (-1))], 1, subFrame);
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|