|
|
@ -21,6 +21,9 @@ function SMR = psycho(frameT, frameType, frameTprev1, frameTprev2) |
|
|
|
% Declares constant numbers of bands for long and short windows |
|
|
|
LONG_WINDOW_NUMBER_OF_BANDS = 69; |
|
|
|
SHORT_WINDOW_NUMBER_OF_BANDS = 42; |
|
|
|
% Declares constant noise masking tone and tone masking noise decibels |
|
|
|
NOISE_MASKING_TONE = 6; |
|
|
|
TONE_MASKING_NOISE = 18; |
|
|
|
|
|
|
|
% Declares persistent variable holding the TNS tables and initializes if empty |
|
|
|
persistent TNSTables spreadingLong spreadingShort hannLong hannShort; |
|
|
@ -63,6 +66,8 @@ function SMR = psycho(frameT, frameType, frameTprev1, frameTprev2) |
|
|
|
|
|
|
|
hannLong = 0.5 - 0.5 * cos((pi * (0:2047 + 0.5)) / 1024); |
|
|
|
hannShort = 0.5 - 0.5 * cos((pi * (0:255 + 0.5)) / 128); |
|
|
|
|
|
|
|
clearvars tmpx tmpz tmpy |
|
|
|
end |
|
|
|
|
|
|
|
if ~strcmp(frameType, 'ESH') |
|
|
@ -73,15 +78,15 @@ function SMR = psycho(frameT, frameType, frameTprev1, frameTprev2) |
|
|
|
|
|
|
|
% Calculates the FFT of each frame |
|
|
|
frameF = fft(windowedFrameT); |
|
|
|
frameFMag = 2 * abs(frameF(1:1024)); |
|
|
|
frameFMag = abs(frameF(1:1024)); |
|
|
|
frameFPhase = angle(frameF(1:1024)); |
|
|
|
|
|
|
|
frameFrameFprev1 = fft(windowedFrameTprev1); |
|
|
|
frameFrameFprev1Mag = 2 * abs(frameFrameFprev1(1:1024)); |
|
|
|
frameFrameFprev1Mag = abs(frameFrameFprev1(1:1024)); |
|
|
|
frameFrameFprev1Phase = angle(frameFrameFprev1(1:1024)); |
|
|
|
|
|
|
|
frameFrameFprev2 = fft(windowedFrameTprev2); |
|
|
|
frameFrameFprev2Mag = 2 * abs(frameFrameFprev2(1:1024)); |
|
|
|
frameFrameFprev2Mag = abs(frameFrameFprev2(1:1024)); |
|
|
|
frameFrameFprev2Phase = angle(frameFrameFprev2(1:1024)); |
|
|
|
|
|
|
|
% Calculates the predicted magnitude and phase compontents of each |
|
|
@ -103,22 +108,38 @@ function SMR = psycho(frameT, frameType, frameTprev1, frameTprev2) |
|
|
|
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) .* ... |
|
|
|
bandPredictability(band) = sum(frameFMag( ... |
|
|
|
TNSTables.B219a(band, 2) + 1:TNSTables.B219a(band, 3) + 1) .^ 2 .* ... |
|
|
|
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); |
|
|
|
bandEnergyConv = sum(bandEnergy .* spreadingLong', 2); |
|
|
|
bandPredictabilityConv = sum(bandPredictability .* spreadingLong', 2); |
|
|
|
|
|
|
|
% Renormalizes values |
|
|
|
cb = ct ./ ecb; |
|
|
|
en = ecb ./ sum(spreadingLong, 1); |
|
|
|
bandPredictabilityConv = bandPredictabilityConv ./ bandEnergyConv; |
|
|
|
bandEnergyConv = bandEnergyConv ./ sum(spreadingLong, 1)'; |
|
|
|
|
|
|
|
% Calculates the tonality index |
|
|
|
tb = -0.299 - 0.43 .* log(cb); |
|
|
|
tonalIndex = -0.299 - 0.43 .* log(bandPredictabilityConv); |
|
|
|
tonalIndex(tonalIndex < 0) = 0; |
|
|
|
tonalIndex(tonalIndex > 1) = 1; |
|
|
|
|
|
|
|
% Calculates SNR and converts from dB to power ratio |
|
|
|
signalToNoiseRatio = tonalIndex .* TONE_MASKING_NOISE + ... |
|
|
|
(1 - tonalIndex) .* NOISE_MASKING_TONE; |
|
|
|
powerRatio = 10 .^ (-signalToNoiseRatio ./ 10); |
|
|
|
|
|
|
|
% Calculates the energy threshold |
|
|
|
energyThreshold = bandEnergyConv .* powerRatio; |
|
|
|
|
|
|
|
% Calculates the noise level |
|
|
|
qThrN = eps() * 1024 .* 10 .^ (TNSTables.B219a(:, 6) ./ 10); |
|
|
|
noiseLevel = max(energyThreshold, qThrN); |
|
|
|
|
|
|
|
SMR = bandEnergy ./ noiseLevel'; |
|
|
|
end |
|
|
|
end |
|
|
|