|
|
|
function frameType = SSC(~, nextFrameT, prevFrameType)
|
|
|
|
%Implementation of the Sequence Segmentation Control step
|
|
|
|
% Usage frameType = SSC(frameT, nextFrameT, prevFrameType), where:
|
|
|
|
% Inputs
|
|
|
|
% - frameT is a frame in the time domain, containing both channels of
|
|
|
|
% the audio stored in an array of dimensions 2048X2
|
|
|
|
% - nextFrameT is the next frame in the time domain, containing both
|
|
|
|
% channels of the audio stored in an array of dimensions 2048X2
|
|
|
|
% - prevFrameType is the type of the previous 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
|
|
|
|
% - 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)
|
|
|
|
|
|
|
|
% Examines the cases where the determination of the type of the next
|
|
|
|
% frame isn't needed for
|
|
|
|
if strcmp(prevFrameType, 'LSS')
|
|
|
|
frameType = 'ESH';
|
|
|
|
return;
|
|
|
|
elseif strcmp(prevFrameType, 'LPS')
|
|
|
|
frameType = 'OLS';
|
|
|
|
return;
|
|
|
|
end
|
|
|
|
|
|
|
|
% Determines the type of the next frame
|
|
|
|
% Filters frame
|
|
|
|
nextFrameT = filter([0.7548 -0.7548], [1 -0.5095], nextFrameT, [], 1);
|
|
|
|
channelFrameType = {'nan', 'nan'};
|
|
|
|
for channel = 1:2
|
|
|
|
% Calculates sub-frame energy estimation
|
|
|
|
[subFrames, ~] = buffer(nextFrameT(577:end - 448, channel), 128, 0, 'nodelay');
|
|
|
|
energyEstimations = sum(subFrames .^ 2, 1)';
|
|
|
|
|
|
|
|
% Calculates the ratio of the sub-frame energy to the average energy of
|
|
|
|
% the previous sub-frames
|
|
|
|
energyRatios = movmean(energyEstimations, [8 0]);
|
|
|
|
energyRatios = energyEstimations ./ [energyEstimations(1); energyRatios(1:end-1)];
|
|
|
|
|
|
|
|
if ~isempty(find(energyEstimations > 10^(-3), 1)) && ...
|
|
|
|
~isempty(find(energyRatios(energyEstimations > 10^(-3)) > 10, 1))
|
|
|
|
% Next frame is ESH
|
|
|
|
if strcmp(prevFrameType, 'ESH')
|
|
|
|
% This frame of this channel is an EIGHT_SHORT_SEQUENCE type
|
|
|
|
% frame. This means the frames of both channels will be encoded
|
|
|
|
% as EIGHT_SHORT_SEQUENCE type frames.
|
|
|
|
frameType = 'ESH';
|
|
|
|
return;
|
|
|
|
elseif strcmp(prevFrameType, 'OLS')
|
|
|
|
channelFrameType{channel} = 'LSS';
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if strcmp(prevFrameType, 'ESH')
|
|
|
|
channelFrameType{channel} = 'LPS';
|
|
|
|
elseif strcmp(prevFrameType, 'OLS')
|
|
|
|
channelFrameType{channel} = 'OLS';
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
% Joins decision for both channels
|
|
|
|
if strcmp(channelFrameType{1}, 'nan') || strcmp(channelFrameType{2}, 'nan')
|
|
|
|
error('SSC, l[67]: Internal error occurred!')
|
|
|
|
end
|
|
|
|
if strcmp(channelFrameType{1}, 'OLS')
|
|
|
|
frameType = channelFrameType{2};
|
|
|
|
elseif strcmp(channelFrameType{2}, 'OLS')
|
|
|
|
frameType = channelFrameType{1};
|
|
|
|
elseif strcmp(channelFrameType{1}, channelFrameType{2})
|
|
|
|
frameType = channelFrameType{1};
|
|
|
|
else
|
|
|
|
frameType = 'ESH';
|
|
|
|
end
|
|
|
|
end
|