|
@ -64,8 +64,8 @@ function SMR = psycho(frameT, frameType, frameTprev1, frameTprev2) |
|
|
tmpSum = tmpz + tmpy; |
|
|
tmpSum = tmpz + tmpy; |
|
|
spreadingShort(tmpy >= -100) = 10 .^ (tmpSum(tmpy >= -100) ./ 10); |
|
|
spreadingShort(tmpy >= -100) = 10 .^ (tmpSum(tmpy >= -100) ./ 10); |
|
|
|
|
|
|
|
|
hannLong = 0.5 - 0.5 * cos((pi * (0:2047 + 0.5)) / 1024); |
|
|
hannLong = 0.5 - 0.5 * cos(pi * ((0:2047) + 0.5) / 1024); |
|
|
hannShort = 0.5 - 0.5 * cos((pi * (0:255 + 0.5)) / 128); |
|
|
hannShort = 0.5 - 0.5 * cos(pi * ((0:255) + 0.5) / 128); |
|
|
|
|
|
|
|
|
clearvars tmpx tmpz tmpy |
|
|
clearvars tmpx tmpz tmpy |
|
|
end |
|
|
end |
|
@ -141,5 +141,92 @@ function SMR = psycho(frameT, frameType, frameTprev1, frameTprev2) |
|
|
noiseLevel = max(energyThreshold, qThrN); |
|
|
noiseLevel = max(energyThreshold, qThrN); |
|
|
|
|
|
|
|
|
SMR = bandEnergy ./ noiseLevel'; |
|
|
SMR = bandEnergy ./ noiseLevel'; |
|
|
|
|
|
else |
|
|
|
|
|
% Splits the frame into sub-frames |
|
|
|
|
|
[subFramesT, ~] = buffer(frameT(449:end-448), 256, 128, 'nodelay'); |
|
|
|
|
|
[subFramesTprev1, ~] = buffer(frameTprev1(449:end-448), 256, 128, 'nodelay'); |
|
|
|
|
|
|
|
|
|
|
|
bandEnergy(SHORT_WINDOW_NUMBER_OF_BANDS) = 0; |
|
|
|
|
|
bandPredictability(SHORT_WINDOW_NUMBER_OF_BANDS) = 0; |
|
|
|
|
|
qThrN = eps() * 128 .* 10 .^ (TNSTables.B219b(:, 6) ./ 10); |
|
|
|
|
|
SMR(SHORT_WINDOW_NUMBER_OF_BANDS, 8) = 0; |
|
|
|
|
|
|
|
|
|
|
|
for subFrameIndex = 1:8 |
|
|
|
|
|
% Applies window to the frames |
|
|
|
|
|
windowedFrameT = subFramesT(:, subFrameIndex) .* hannShort'; |
|
|
|
|
|
if subFrameIndex == 1 |
|
|
|
|
|
windowedFrameTprev1 = subFramesTprev1(:, 8) .* hannShort'; |
|
|
|
|
|
windowedFrameTprev2 = subFramesTprev1(:, 7) .* hannShort'; |
|
|
|
|
|
elseif subFrameIndex == 2 |
|
|
|
|
|
windowedFrameTprev1 = subFramesT(:, subFrameIndex - 1) .* hannShort'; |
|
|
|
|
|
windowedFrameTprev2 = subFramesTprev1(:, 8) .* hannShort'; |
|
|
|
|
|
else |
|
|
|
|
|
windowedFrameTprev1 = subFramesT(:, subFrameIndex - 1) .* hannShort'; |
|
|
|
|
|
windowedFrameTprev2 = subFramesT(:, subFrameIndex - 1) .* hannShort'; |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
% Calculates the FFT of each frame |
|
|
|
|
|
frameF = fft(windowedFrameT); |
|
|
|
|
|
frameFMag = abs(frameF(1:128)); |
|
|
|
|
|
frameFPhase = angle(frameF(1:128)); |
|
|
|
|
|
|
|
|
|
|
|
frameFrameFprev1 = fft(windowedFrameTprev1); |
|
|
|
|
|
frameFrameFprev1Mag = abs(frameFrameFprev1(1:128)); |
|
|
|
|
|
frameFrameFprev1Phase = angle(frameFrameFprev1(1:128)); |
|
|
|
|
|
|
|
|
|
|
|
frameFrameFprev2 = fft(windowedFrameTprev2); |
|
|
|
|
|
frameFrameFprev2Mag = abs(frameFrameFprev2(1:128)); |
|
|
|
|
|
frameFrameFprev2Phase = angle(frameFrameFprev2(1:128)); |
|
|
|
|
|
|
|
|
|
|
|
% 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 |
|
|
|
|
|
for band = 1:SHORT_WINDOW_NUMBER_OF_BANDS |
|
|
|
|
|
bandEnergy(band) = sumsqr(frameFMag(TNSTables.B219b(band, 2) + 1: ... |
|
|
|
|
|
TNSTables.B219b(band, 3) + 1)); |
|
|
|
|
|
bandPredictability(band) = sum(frameFMag( ... |
|
|
|
|
|
TNSTables.B219b(band, 2) + 1:TNSTables.B219b(band, 3) + 1) .^ 2 .* ... |
|
|
|
|
|
framePredictability(TNSTables.B219b(band, 2) + 1: ... |
|
|
|
|
|
TNSTables.B219b(band, 3) + 1)); |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
% Convolves the partitioned energy and predictability with the |
|
|
|
|
|
% spreading function |
|
|
|
|
|
bandEnergyConv = sum(bandEnergy .* spreadingShort', 2); |
|
|
|
|
|
bandPredictabilityConv = sum(bandPredictability .* spreadingShort', 2); |
|
|
|
|
|
|
|
|
|
|
|
% Renormalizes values |
|
|
|
|
|
bandPredictabilityConv = bandPredictabilityConv ./ bandEnergyConv; |
|
|
|
|
|
bandEnergyConv = bandEnergyConv ./ sum(spreadingShort, 1)'; |
|
|
|
|
|
|
|
|
|
|
|
% Calculates the tonality index |
|
|
|
|
|
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 |
|
|
|
|
|
noiseLevel = max(energyThreshold, qThrN); |
|
|
|
|
|
|
|
|
|
|
|
SMR(:, subFrameIndex) = bandEnergy ./ noiseLevel'; |
|
|
|
|
|
end |
|
|
end |
|
|
end |
|
|
end |
|
|
end |
|
|