178 lines
4.2 KiB
Matlab
178 lines
4.2 KiB
Matlab
function [ODG, MOVB]= PQevalAudio (Fref, Ftest, StartS, EndS)
|
|
% Perceptual evaluation of audio quality.
|
|
|
|
% - StartS shifts the frames, so that the first frame starts at that sample.
|
|
% This is a two element array, one element for each input file. If StartS is
|
|
% a scalar, it applies to both files.
|
|
% - EndS marks the end of data. The processing stops with the last frame that
|
|
% contains that sample. This is a two element array, one element for each
|
|
% input file. If EndS is as scalar, it applies to both files.
|
|
|
|
% P. Kabal $Revision: 1.2 $ $Date: 2004/02/05 04:25:24 $
|
|
|
|
% Globals (to save on copying in/out of functions)
|
|
global MOVC PQopt
|
|
|
|
% Analysis parameters
|
|
NF = 2048;
|
|
Nadv = NF / 2;
|
|
Version = 'Basic';
|
|
|
|
% Options
|
|
PQopt.ClipMOV = 0;
|
|
PQopt.PCinit = 0;
|
|
PQopt.PDfactor = 1;
|
|
PQopt.Ni = 1;
|
|
PQopt.DelayOverlap = 1;
|
|
PQopt.DataBounds = 1;
|
|
PQopt.EndMin = NF / 2;
|
|
|
|
%addpath ('CB', 'MOV', 'Misc', 'Patt');
|
|
|
|
if (nargin < 3)
|
|
StartS = [0, 0];
|
|
end
|
|
if (nargin < 4)
|
|
EndS = [];
|
|
end
|
|
|
|
% Get the number of samples and channels for each file
|
|
WAV(1) = PQwavFilePar (Fref);
|
|
WAV(2) = PQwavFilePar (Ftest);
|
|
|
|
% Reconcile file differences
|
|
PQ_CheckWAV (WAV);
|
|
if (WAV(1).Nframe ~= WAV(2).Nframe)
|
|
disp ('>>> Number of samples differ: using the minimum');
|
|
end
|
|
|
|
% Data boundaries
|
|
Nchan = WAV(1).Nchan;
|
|
[StartS, Fstart, Fend] = PQ_Bounds (WAV, Nchan, StartS, EndS, PQopt);
|
|
|
|
% Number of PEAQ frames
|
|
Np = Fend - Fstart + 1;
|
|
if (PQopt.Ni < 0)
|
|
PQopt.Ni = ceil (Np / abs(PQopt.Ni));
|
|
end
|
|
|
|
% Initialize the MOV structure
|
|
MOVC = PQ_InitMOVC (Nchan, Np);
|
|
|
|
% Initialize the filter memory
|
|
Nc = PQCB (Version);
|
|
for (j = 0:Nchan-1)
|
|
Fmem(j+1) = PQinitFMem (Nc, PQopt.PCinit);
|
|
end
|
|
|
|
is = 0;
|
|
for (i = -Fstart:Np-1)
|
|
|
|
% Read a frame of data
|
|
xR = PQgetData (WAV(1), StartS(1) + is, NF); % Reference file
|
|
xT = PQgetData (WAV(2), StartS(2) + is, NF); % Test file
|
|
is = is + Nadv;
|
|
|
|
% Process a frame
|
|
for (j = 0:Nchan-1)
|
|
[MOVI(j+1), Fmem(j+1)] = PQeval (xR(j+1,:), xT(j+1,:), Fmem(j+1));
|
|
end
|
|
|
|
if (i >= 0)
|
|
% Move the MOV precursors into a new structure
|
|
PQframeMOV (i, MOVI); % Output is in global MOVC
|
|
|
|
% Print the MOV precursors
|
|
%if (PQopt.Ni ~= 0 & mod (i, PQopt.Ni) == 0)
|
|
% PQprtMOVCi (Nchan, i, MOVC);
|
|
%nd
|
|
end
|
|
end
|
|
|
|
% Time average of the MOV values
|
|
if (PQopt.DelayOverlap)
|
|
Nwup = Fstart;
|
|
else
|
|
Nwup = 0;
|
|
end
|
|
MOVB = PQavgMOVB (MOVC, Nchan, Nwup);
|
|
|
|
% Neural net
|
|
ODG = PQnNet (MOVB);
|
|
|
|
% Summary printout
|
|
%PQprtMOV (MOVB, ODG);
|
|
|
|
%----------
|
|
function PQ_CheckWAV (WAV)
|
|
% Check the file parameters
|
|
|
|
Fs = 48000;
|
|
|
|
if (WAV(1).Nchan ~= WAV(2).Nchan)
|
|
error ('>>> Number of channels differ');
|
|
end
|
|
if (WAV(1).Nchan > 2)
|
|
error ('>>> Too many input channels');
|
|
end
|
|
if (WAV(1).Nframe ~= WAV(2).Nframe)
|
|
disp ('>>> Number of samples differ');
|
|
end
|
|
if (WAV(1).Fs ~= WAV(2).Fs)
|
|
error ('>>> Sampling frequencies differ');
|
|
end
|
|
if (WAV(1).Fs ~= Fs)
|
|
error ('>>> Invalid Sampling frequency: only 48 kHz supported');
|
|
end
|
|
|
|
%----------
|
|
function [StartS, Fstart, Fend] = PQ_Bounds (WAV, Nchan, StartS, EndS, PQopt)
|
|
|
|
PQ_NF = 2048;
|
|
PQ_NADV = (PQ_NF / 2);
|
|
|
|
if (isempty (StartS))
|
|
StartS(1) = 0;
|
|
StartS(2) = 0;
|
|
elseif (length (StartS) == 1)
|
|
StartS(2) = StartS(1);
|
|
end
|
|
Ns = WAV(1).Nframe;
|
|
|
|
% Data boundaries (determined from the reference file)
|
|
if (PQopt.DataBounds)
|
|
Lim = PQdataBoundary (WAV(1), Nchan, StartS(1), Ns);
|
|
%fprintf ('PEAQ Data Boundaries: %ld (%.3f s) - %ld (%.3f s)\n', ...
|
|
% Lim(1), Lim(1)/WAV(1).Fs, Lim(2), Lim(2)/WAV(1).Fs);
|
|
else
|
|
Lim = [Starts(1), StartS(1) + Ns - 1];
|
|
end
|
|
|
|
% Start frame number
|
|
Fstart = floor ((Lim(1) - StartS(1)) / PQ_NADV);
|
|
|
|
% End frame number
|
|
Fend = floor ((Lim(2) - StartS(1) + 1 - PQopt.EndMin) / PQ_NADV);
|
|
|
|
%----------
|
|
function MOVC = PQ_InitMOVC (Nchan, Np)
|
|
MOVC.MDiff.Mt1B = zeros (Nchan, Np);
|
|
MOVC.MDiff.Mt2B = zeros (Nchan, Np);
|
|
MOVC.MDiff.Wt = zeros (Nchan, Np);
|
|
|
|
MOVC.NLoud.NL = zeros (Nchan, Np);
|
|
|
|
MOVC.Loud.NRef = zeros (Nchan, Np);
|
|
MOVC.Loud.NTest = zeros (Nchan, Np);
|
|
|
|
MOVC.BW.BWRef = zeros (Nchan, Np);
|
|
MOVC.BW.BWTest = zeros (Nchan, Np);
|
|
|
|
MOVC.NMR.NMRavg = zeros (Nchan, Np);
|
|
MOVC.NMR.NMRmax = zeros (Nchan, Np);
|
|
|
|
MOVC.PD.Pc = zeros (1, Np);
|
|
MOVC.PD.Qc = zeros (1, Np);
|
|
|
|
MOVC.EHS.EHS = zeros (Nchan, Np);
|