ivan@138: function [SNRx, PSM, PSMt, PESQ_MOS, EAQUAL_ODG, EAQUAL_DIX] = ... ivan@138: audioQualityMeasures(xRef,xTest,fs,options) ivan@138: % ivan@138: % ivan@138: % Usage: ivan@138: % ivan@138: % ivan@138: % Inputs: ivan@138: % - ivan@138: % - ivan@138: % - ivan@138: % - ivan@138: % - ivan@138: % - ivan@138: % - ivan@138: % - ivan@138: % ivan@138: % Outputs: ivan@138: % - ivan@138: % - ivan@138: % - ivan@138: % - ivan@138: % ivan@138: % Note that the CVX library is needed. ivan@138: % ivan@138: % ------------------- ivan@138: % ivan@138: % Audio Inpainting toolbox ivan@138: % Date: June 28, 2011 ivan@138: % By Valentin Emiya, Amir Adler, Maria Jafari ivan@138: % This code is distributed under the terms of the GNU Public License version 3 (http://www.gnu.org/licenses/gpl.txt). ivan@138: % Computes a series of audio quality measures ivan@138: % ivan@138: % Usage: ivan@138: % [PSM,PSMt] = ... ivan@138: % audioQualityMeasures(xRef,xTest,fs,options) ivan@138: % ivan@138: % Inputs: ivan@138: % - xRef: reference signal ivan@138: % - xTest: test signal (to be compared to xRef) ivan@138: % - fs: sampling frequency ivan@138: % - optional parameters [default]: ivan@138: % - options.ENABLE_PEMOQ: flag to use PEMO-Q or not [true] ivan@138: % - options.pemoQExec: name of PEMO-Q executable ['"./PEMO-Q v1.1.2 demo/audioqual_demo.exe"'] ivan@138: % - options.PESQExec: name of PESQ executable [''./PESQ/pesq''] ivan@138: % - options.EAQUALExec: name of EAQUAL (PEAQ) executable ['./EAQUAL/eaqual.exe'] ivan@138: % ivan@138: % Note that PEMO-Q and EAQUAL programs are Windows executable and that ivan@138: % under unix, they can be used by means of wine (Windows Emulator). One ivan@138: % just have to have wine installed. ivan@138: % ivan@138: % Valentin Emiya, INRIA, 2010. ivan@138: ivan@138: ivan@138: %% default options ivan@138: defaultOptions.pemoQExec = '"C:/Program Files/PEMO-Q v1.2/audioqual.exe"'; % Full licensed version ivan@138: if isempty(dir(defaultOptions.pemoQExec)) ivan@138: defaultOptions.pemoQExec = '"./PEMO-Q v1.1.2 demo/audioqual_demo.exe"'; % Demo version ivan@138: end ivan@138: defaultOptions.ENABLE_PEMOQ = true; ivan@138: defaultOptions.PESQExec = './PESQ/pesq'; ivan@138: ivan@138: if ispc ivan@138: defaultOptions.EAQUALExec = './EAQUAL/eaqual.exe'; ivan@138: else % if unix, use wine ivan@138: defaultOptions.EAQUALExec = 'wine ./EAQUAL/eaqual.exe'; ivan@138: defaultOptions.pemoQExec = ['wine ' defaultOptions.pemoQExec]; ivan@138: end ivan@138: ivan@138: if nargin<4 ivan@138: options = defaultOptions; ivan@138: else ivan@138: names = fieldnames(defaultOptions); ivan@138: for k=1:length(names) ivan@138: if ~isfield(options,names{k}) || isempty(options.(names{k})) ivan@138: options.(names{k}) = defaultOptions.(names{k}); ivan@138: end ivan@138: end ivan@138: end ivan@138: ivan@138: if ~ischar(xRef) && ~ischar(xTest) && length(xRef)~=length(xTest) ivan@138: warning('EVAL:LENGTH','Different lengths'); ivan@138: L = min(length(xRef),length(xTest)); ivan@138: xRef = xRef(1:L); ivan@138: xTest = xTest(1:L); ivan@138: end ivan@138: ivan@138: if ischar(xRef) ivan@138: refFile = xRef; ivan@138: sRef = wavread(refFile); ivan@138: else ivan@138: refFile = [tempname '.wav']; ivan@138: sRef = xRef; ivan@138: wavwrite(xRef,fs,refFile); ivan@138: end ivan@138: if ischar(xTest) ivan@138: testFile = xTest; ivan@138: sTest = wavread(testFile); ivan@138: else ivan@138: testFile = [tempname '.wav']; ivan@138: sTest = xTest; ivan@138: wavwrite(xTest,fs,testFile); ivan@138: end ivan@138: ivan@138: ivan@138: SNRx = SNR(sRef,sTest); ivan@138: ivan@138: try ivan@138: % if ispc && options.ENABLE_PEMOQ ivan@138: if options.ENABLE_PEMOQ ivan@138: %% PEMO-Q ivan@138: [PSM,PSMt] = aux_pemoq(refFile,testFile,options); ivan@138: else ivan@138: warning('audioQualityMeasures:noPQ','PEMO-Q is not available (requires Windows plateform)') ivan@138: PSM = NaN; ivan@138: PSMt = NaN; ivan@138: end ivan@138: ivan@138: %% PESQ ivan@138: PESQ_MOS = aux_pesq(refFile,testFile,options); ivan@138: ivan@138: %% EAQUAL (PEAQ) ivan@138: [EAQUAL_ODG, EAQUAL_DIX] = aux_eaqual(refFile,testFile,options); ivan@138: ivan@138: if ~ischar(xRef) ivan@138: %% Delete temporary files ivan@138: delete(refFile); ivan@138: end ivan@138: if ~ischar(xTest) ivan@138: delete(testFile); ivan@138: end ivan@138: ivan@138: catch ivan@138: if ~ischar(xRef) ivan@138: %% In case of error, delete the temporary files ivan@138: delete(refFile); ivan@138: end ivan@138: if ~ischar(xTest) ivan@138: delete(testFile); ivan@138: end ivan@138: rethrow; ivan@138: end ivan@138: ivan@138: ivan@138: return ivan@138: ivan@138: function [PSM,PSMt] = aux_pemoq(refFile,testFile,options) ivan@138: if ~isempty(findstr(options.pemoQExec, 'demo')) ivan@138: fprintf('To unlock PEMO-Q demo, please enter the PIN shown in the new window\n'); ivan@138: end ivan@138: [dum, pemo] = system(sprintf('%s %s %s [] [] 0 0 0', options.pemoQExec, refFile, testFile)); ivan@138: pemo = regexp(pemo, 'PSM.? = \d*.\d*', 'match'); ivan@138: PSM = str2double(cell2mat(regexp(pemo{1},'\d+.?\d*', 'match'))); ivan@138: PSMt = str2double(cell2mat(regexp(pemo{2},'\d+.?\d*', 'match'))); ivan@138: ivan@138: return ivan@138: ivan@138: function PESQ_MOS = aux_pesq(refFile,testFile,options) ivan@138: [dum fs] = wavread(refFile,'size'); ivan@138: if ~ismember(fs,[8000 16000]) ivan@138: error('audioQualityMeasures:badFs',... ivan@138: '8kHz or 16 kHz sampling frequency required for PESQ'); ivan@138: end ivan@138: [dum,s] = system(sprintf('%s +%d %s %s',options.PESQExec,fs,refFile,testFile)); ivan@138: PESQ_MOS = regexp(s, 'Prediction : PESQ_MOS = \d*.\d*', 'match'); ivan@138: PESQ_MOS = str2double(PESQ_MOS{end}(length('Prediction : PESQ_MOS = ')+1:end)); ivan@138: return ivan@138: ivan@138: function [EAQUAL_ODG, EAQUAL_DIX] = aux_eaqual(refFile,testFile,options) ivan@138: [dum fs] = wavread(refFile,'size'); ivan@138: DELETE_FLAG = false; ivan@138: if fs<44100 ivan@138: warning('EAQUAL:BAD_FS',... ivan@138: 'Sampling frequency is too low for Eaqual (<44.1kHz).\nResampling first (result not relevant)'); ivan@138: DELETE_FLAG = true; ivan@138: ivan@138: x = wavread(refFile); ivan@138: fsEaqual = 48000; ivan@138: x = resample(x,fsEaqual,fs); ivan@138: refFile = [tempname '.wav']; ivan@138: wavwrite(x,fsEaqual,refFile); ivan@138: ivan@138: x = wavread(testFile); ivan@138: fsEaqual = 48000; ivan@138: x = resample(x,fsEaqual,fs); ivan@138: testFile = [tempname '.wav']; ivan@138: wavwrite(x,fsEaqual,testFile); ivan@138: ivan@138: fs = fsEaqual; ivan@138: end ivan@138: ivan@138: [dum,s] = system(sprintf('%s -fref %s -ftest %s -srate %d',options.EAQUALExec,refFile,testFile,fs)); ivan@138: ivan@138: EAQUAL_ODG = regexp(s, 'Resulting ODG:\t.?\d*(\.\d*)?', 'match'); ivan@138: EAQUAL_ODG = str2double(EAQUAL_ODG{end}(length('Resulting ODG: ')+1:end)); ivan@138: EAQUAL_DIX = regexp(s, 'Resulting DIX:\t.?\d*(\.\d*)?', 'match'); ivan@138: EAQUAL_DIX = str2double(EAQUAL_DIX{end}(length('Resulting DIX: ')+1:end)); ivan@138: ivan@138: if DELETE_FLAG ivan@138: delete(refFile); ivan@138: delete(testFile); ivan@138: end ivan@138: return