|
|
@ -18,6 +18,107 @@ function SMR = psycho(frameT, frameType, frameTprev1, frameTprev2) |
|
|
|
% - SMR is the signal to mask ratio array of dimensions 42X8 for |
|
|
|
% EIGHT_SHORT_SEQUENCE frames and 69X1 otherwise |
|
|
|
|
|
|
|
% Declares constant numbers of bands for long and short windows |
|
|
|
LONG_WINDOW_NUMBER_OF_BANDS = 69; |
|
|
|
SHORT_WINDOW_NUMBER_OF_BANDS = 42; |
|
|
|
|
|
|
|
end |
|
|
|
% Declares persistent variable holding the TNS tables and initializes if empty |
|
|
|
persistent TNSTables spreadingLong spreadingShort hannLong hannShort; |
|
|
|
if isempty(TNSTables) || isempty(spreadingLong) || ... |
|
|
|
isempty(spreadingShort) || isempty(hannLong) || isempty(hannShort) |
|
|
|
TNSTables = load('TableB219.mat'); |
|
|
|
|
|
|
|
spreadingLong = zeros(LONG_WINDOW_NUMBER_OF_BANDS); |
|
|
|
spreadingShort = zeros(SHORT_WINDOW_NUMBER_OF_BANDS); |
|
|
|
|
|
|
|
% Calculates all possible spreading function results for long |
|
|
|
% windows |
|
|
|
tmpx = repmat(TNSTables.B219a(:, 5)', LONG_WINDOW_NUMBER_OF_BANDS, 1); |
|
|
|
tmpx = tmpx - repmat(TNSTables.B219a(:, 5), 1, LONG_WINDOW_NUMBER_OF_BANDS); |
|
|
|
indeces = logical(tril(ones(LONG_WINDOW_NUMBER_OF_BANDS))); |
|
|
|
tmpx(indeces) = tmpx(indeces) .* 3; |
|
|
|
indeces = ~indeces; |
|
|
|
tmpx(indeces) = tmpx(indeces) .* 1.5; |
|
|
|
|
|
|
|
tmpz = 8 * min((tmpx - 0.5) .^ 2 - 2 * (tmpx - 0.5), 0); |
|
|
|
tmpy = 15.811389 + 7.5 * (tmpx + 0.474) - 17.5 * sqrt(1 + (tmpx + 0.474) .^ 2); |
|
|
|
|
|
|
|
tmpSum = tmpz + tmpy; |
|
|
|
spreadingLong(tmpy >= -100) = 10 .^ (tmpSum(tmpy >= -100) ./ 10); |
|
|
|
|
|
|
|
% Calculates all possible spreading function results for short |
|
|
|
% windows |
|
|
|
tmpx = repmat(TNSTables.B219b(:, 5)', SHORT_WINDOW_NUMBER_OF_BANDS, 1); |
|
|
|
tmpx = tmpx - repmat(TNSTables.B219b(:, 5), 1, SHORT_WINDOW_NUMBER_OF_BANDS); |
|
|
|
indeces = logical(tril(ones(SHORT_WINDOW_NUMBER_OF_BANDS))); |
|
|
|
tmpx(indeces) = tmpx(indeces) .* 3; |
|
|
|
indeces = ~indeces; |
|
|
|
tmpx(indeces) = tmpx(indeces) .* 1.5; |
|
|
|
|
|
|
|
tmpz = 8 * min((tmpx - 0.5) .^ 2 - 2 * (tmpx - 0.5), 0); |
|
|
|
tmpy = 15.811389 + 7.5 * (tmpx + 0.474) - 17.5 * sqrt(1 + (tmpx + 0.474) .^ 2); |
|
|
|
|
|
|
|
tmpSum = tmpz + tmpy; |
|
|
|
spreadingShort(tmpy >= -100) = 10 .^ (tmpSum(tmpy >= -100) ./ 10); |
|
|
|
|
|
|
|
hannLong = 0.5 - 0.5 * cos((pi * (0:2047 + 0.5)) / 1024); |
|
|
|
hannShort = 0.5 - 0.5 * cos((pi * (0:255 + 0.5)) / 128); |
|
|
|
end |
|
|
|
|
|
|
|
if ~strcmp(frameType, 'ESH') |
|
|
|
% Applies window to the frames |
|
|
|
windowedFrameT = frameT .* hannLong'; |
|
|
|
windowedFrameTprev1 = frameTprev1 .* hannLong'; |
|
|
|
windowedFrameTprev2 = frameTprev2 .* hannLong'; |
|
|
|
|
|
|
|
% Calculates the FFT of each frame |
|
|
|
frameF = fft(windowedFrameT); |
|
|
|
frameFMag = 2 * abs(frameF(1:1024)); |
|
|
|
frameFPhase = angle(frameF(1:1024)); |
|
|
|
|
|
|
|
frameFrameFprev1 = fft(windowedFrameTprev1); |
|
|
|
frameFrameFprev1Mag = 2 * abs(frameFrameFprev1(1:1024)); |
|
|
|
frameFrameFprev1Phase = angle(frameFrameFprev1(1:1024)); |
|
|
|
|
|
|
|
frameFrameFprev2 = fft(windowedFrameTprev2); |
|
|
|
frameFrameFprev2Mag = 2 * abs(frameFrameFprev2(1:1024)); |
|
|
|
frameFrameFprev2Phase = angle(frameFrameFprev2(1:1024)); |
|
|
|
|
|
|
|
% Calculates the predicted magnitude and phase compontents of each |
|
|
|
% frequency |
|
|
|
magPred = 2 .* frameFrameFprev1Mag - frameFrameFprev2Mag; |
|
|
|
phasePred = 2 .* frameFrameFprev1Phase - frameFrameFprev2Phase; |
|
|
|
|
|
|
|
% Calculates this frame's predictability |
|
|
|
framePredictability = sqrt((frameFMag .* cos(frameFPhase) - ... |
|
|
|
magPred .* cos(phasePred)) .^ 2 + ... |
|
|
|
(frameFMag .* sin(frameFPhase) - ... |
|
|
|
magPred .* sin(phasePred)) .^ 2) ./ ... |
|
|
|
(frameFMag + abs(magPred)); |
|
|
|
|
|
|
|
% Calculates the energy and weighted predictability in the |
|
|
|
% threshold calculation partitions |
|
|
|
bandEnergy(LONG_WINDOW_NUMBER_OF_BANDS) = 0; |
|
|
|
bandPredictability(LONG_WINDOW_NUMBER_OF_BANDS) = 0; |
|
|
|
for band = 1:LONG_WINDOW_NUMBER_OF_BANDS |
|
|
|
bandEnergy(band) = sumsqr(frameFMag(TNSTables.B219a(band, 2) + 1: ... |
|
|
|
TNSTables.B219a(band, 3) + 1)); |
|
|
|
bandPredictability(band) = sumsqr(frameFMag( ... |
|
|
|
TNSTables.B219a(band, 2) + 1:TNSTables.B219a(band, 3) + 1) .* ... |
|
|
|
framePredictability(TNSTables.B219a(band, 2) + 1: ... |
|
|
|
TNSTables.B219a(band, 3) + 1)); |
|
|
|
end |
|
|
|
|
|
|
|
% Convolves the partitioned energy and predictability with the |
|
|
|
% spreading function |
|
|
|
ecb = sum(bandEnergy .* spreadingLong', 2); |
|
|
|
ct = sum(bandPredictability .* spreadingLong', 2); |
|
|
|
|
|
|
|
% Renormalizes values |
|
|
|
cb = ct ./ ecb; |
|
|
|
en = ecb ./ sum(spreadingLong, 1); |
|
|
|
|
|
|
|
% Calculates the tonality index |
|
|
|
tb = -0.299 - 0.43 .* log(cb); |
|
|
|
end |
|
|
|
end |
|
|
|