113 lines
2.6 KiB
Matlab
113 lines
2.6 KiB
Matlab
function [MOVI, Fmem] = PQeval (xR, xT, Fmem)
|
|
% PEAQ - Process one frame with the FFT model
|
|
|
|
% P. Kabal $Revision: 1.1 $ $Date: 2003/12/07 13:32:58 $
|
|
|
|
NF = 2048;
|
|
Version = 'Basic';
|
|
|
|
% Windowed DFT
|
|
X2(1,:) = PQDFTFrame (xR);
|
|
X2(2,:) = PQDFTFrame (xT);
|
|
|
|
% Critical band grouping and frequency spreading
|
|
[EbN, Es] = PQ_excitCB (X2);
|
|
|
|
% Time domain smoothing => "Excitation patterns"
|
|
[Ehs(1,:), Fmem.TDS.Ef(1,:)] = PQ_timeSpread (Es(1,:), Fmem.TDS.Ef(1,:));
|
|
[Ehs(2,:), Fmem.TDS.Ef(2,:)] = PQ_timeSpread (Es(2,:), Fmem.TDS.Ef(2,:));
|
|
|
|
% Level and pattern adaptation => "Spectrally adapted patterns"
|
|
[EP, Fmem.Adap] = PQadapt (Ehs, Fmem.Adap, Version, 'FFT');
|
|
|
|
% Modulation patterns
|
|
[M, ERavg, Fmem.Env] = PQmodPatt (Es, Fmem.Env);
|
|
|
|
% Loudness
|
|
MOVI.Loud.NRef = PQloud (Ehs(1,:), Version, 'FFT');
|
|
MOVI.Loud.NTest = PQloud (Ehs(2,:), Version, 'FFT');
|
|
|
|
% Modulation differences
|
|
MOVI.MDiff = PQmovModDiffB (M, ERavg);
|
|
|
|
% Noise Loudness
|
|
MOVI.NLoud.NL = PQmovNLoudB (M, EP);
|
|
|
|
% Bandwidth
|
|
MOVI.BW = PQmovBW (X2);
|
|
|
|
% Noise-to-mask ratios
|
|
MOVI.NMR = PQmovNMRB (EbN, Ehs(1,:));
|
|
|
|
% Probability of detection
|
|
MOVI.PD = PQmovPD (Ehs);
|
|
|
|
% Error harmonic structure
|
|
MOVI.EHS.EHS = PQmovEHS (xR, xT, X2);
|
|
|
|
%--------------------
|
|
function [EbN, Es] = PQ_excitCB (X2)
|
|
|
|
persistent W2 EIN
|
|
|
|
NF = 2048;
|
|
Version = 'Basic';
|
|
if (isempty (W2))
|
|
Fs = 48000;
|
|
f = linspace (0, Fs/2, NF/2+1);
|
|
W2 = PQWOME (f);
|
|
[Nc, fc] = PQCB (Version);
|
|
EIN = PQIntNoise (fc);
|
|
end
|
|
|
|
% Allocate storage
|
|
XwN2 = zeros (1, NF/2+1);
|
|
|
|
% Outer and middle ear filtering
|
|
Xw2(1,:) = W2 .* X2(1,1:NF/2+1);
|
|
Xw2(2,:) = W2 .* X2(2,1:NF/2+1);
|
|
|
|
% Form the difference magnitude signal
|
|
for (k = 0:NF/2)
|
|
XwN2(k+1) = (Xw2(1,k+1) - 2 * sqrt (Xw2(1,k+1) * Xw2(2,k+1)) ...
|
|
+ Xw2(2,k+1));
|
|
end
|
|
|
|
% Group into partial critical bands
|
|
Eb(1,:) = PQgroupCB (Xw2(1,:), Version);
|
|
Eb(2,:) = PQgroupCB (Xw2(2,:), Version);
|
|
EbN = PQgroupCB (XwN2, Version);
|
|
|
|
% Add the internal noise term => "Pitch patterns"
|
|
E(1,:) = Eb(1,:) + EIN;
|
|
E(2,:) = Eb(2,:) + EIN;
|
|
|
|
% Critical band spreading => "Unsmeared excitation patterns"
|
|
Es(1,:) = PQspreadCB (E(1,:), Version);
|
|
Es(2,:) = PQspreadCB (E(2,:), Version);
|
|
|
|
%--------------------
|
|
function [Ehs, Ef] = PQ_timeSpread (Es, Ef)
|
|
|
|
persistent Nc a b
|
|
|
|
if (isempty (Nc))
|
|
[Nc, fc] = PQCB ('Basic');
|
|
Fs = 48000;
|
|
NF = 2048;
|
|
Nadv = NF / 2;
|
|
Fss = Fs / Nadv;
|
|
t100 = 0.030;
|
|
tmin = 0.008;
|
|
[a, b] = PQtConst (t100, tmin, fc, Fss);
|
|
end
|
|
|
|
% Allocate storage
|
|
Ehs = zeros (1, Nc);
|
|
|
|
% Time domain smoothing
|
|
for (m = 0:Nc-1)
|
|
Ef(m+1) = a(m+1) * Ef(m+1) + b(m+1) * Es(m+1);
|
|
Ehs(m+1) = max(Ef(m+1), Es(m+1));
|
|
end
|