| % | |
| % Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | |
| % | |
| % Use of this source code is governed by a BSD-style license | |
| % that can be found in the LICENSE file in the root of the source | |
| % tree. An additional intellectual property rights grant can be found | |
| % in the file PATENTS. All contributing project authors may | |
| % be found in the AUTHORS file in the root of the source tree. | |
| % | |
| function apmtest(task, testname, filepath, casenumber, legacy) | |
| %APMTEST is a tool to process APM file sets and easily display the output. | |
| % APMTEST(TASK, TESTNAME, CASENUMBER) performs one of several TASKs: | |
| % 'test' Processes the files to produce test output. | |
| % 'list' Prints a list of cases in the test set, preceded by their | |
| % CASENUMBERs. | |
| % 'show' Uses spclab to show the test case specified by the | |
| % CASENUMBER parameter. | |
| % | |
| % using a set of test files determined by TESTNAME: | |
| % 'all' All tests. | |
| % 'apm' The standard APM test set (default). | |
| % 'apmm' The mobile APM test set. | |
| % 'aec' The AEC test set. | |
| % 'aecm' The AECM test set. | |
| % 'agc' The AGC test set. | |
| % 'ns' The NS test set. | |
| % 'vad' The VAD test set. | |
| % | |
| % FILEPATH specifies the path to the test data files. | |
| % | |
| % CASENUMBER can be used to select a single test case. Omit CASENUMBER, | |
| % or set to zero, to use all test cases. | |
| % | |
| if nargin < 5 || isempty(legacy) | |
| % Set to true to run old VQE recordings. | |
| legacy = false; | |
| end | |
| if nargin < 4 || isempty(casenumber) | |
| casenumber = 0; | |
| end | |
| if nargin < 3 || isempty(filepath) | |
| filepath = 'data/'; | |
| end | |
| if nargin < 2 || isempty(testname) | |
| testname = 'all'; | |
| end | |
| if nargin < 1 || isempty(task) | |
| task = 'test'; | |
| end | |
| if ~strcmp(task, 'test') && ~strcmp(task, 'list') && ~strcmp(task, 'show') | |
| error(['TASK ' task ' is not recognized']); | |
| end | |
| if casenumber == 0 && strcmp(task, 'show') | |
| error(['CASENUMBER must be specified for TASK ' task]); | |
| end | |
| inpath = [filepath 'input/']; | |
| outpath = [filepath 'output/']; | |
| refpath = [filepath 'reference/']; | |
| if strcmp(testname, 'all') | |
| tests = {'apm','apmm','aec','aecm','agc','ns','vad'}; | |
| else | |
| tests = {testname}; | |
| end | |
| if legacy | |
| progname = './test'; | |
| else | |
| progname = './process_test'; | |
| end | |
| global farFile; | |
| global nearFile; | |
| global eventFile; | |
| global delayFile; | |
| global driftFile; | |
| if legacy | |
| farFile = 'vqeFar.pcm'; | |
| nearFile = 'vqeNear.pcm'; | |
| eventFile = 'vqeEvent.dat'; | |
| delayFile = 'vqeBuf.dat'; | |
| driftFile = 'vqeDrift.dat'; | |
| else | |
| farFile = 'apm_far.pcm'; | |
| nearFile = 'apm_near.pcm'; | |
| eventFile = 'apm_event.dat'; | |
| delayFile = 'apm_delay.dat'; | |
| driftFile = 'apm_drift.dat'; | |
| end | |
| simulateMode = false; | |
| nErr = 0; | |
| nCases = 0; | |
| for i=1:length(tests) | |
| simulateMode = false; | |
| if strcmp(tests{i}, 'apm') | |
| testdir = ['apm/']; | |
| outfile = ['out']; | |
| if legacy | |
| opt = ['-ec 1 -agc 2 -nc 2 -vad 3']; | |
| else | |
| opt = ['--no_progress -hpf' ... | |
| ' -aec --drift_compensation -agc --fixed_digital' ... | |
| ' -ns --ns_moderate -vad']; | |
| end | |
| elseif strcmp(tests{i}, 'apm-swb') | |
| simulateMode = true; | |
| testdir = ['apm-swb/']; | |
| outfile = ['out']; | |
| if legacy | |
| opt = ['-fs 32000 -ec 1 -agc 2 -nc 2']; | |
| else | |
| opt = ['--no_progress -fs 32000 -hpf' ... | |
| ' -aec --drift_compensation -agc --adaptive_digital' ... | |
| ' -ns --ns_moderate -vad']; | |
| end | |
| elseif strcmp(tests{i}, 'apmm') | |
| testdir = ['apmm/']; | |
| outfile = ['out']; | |
| opt = ['-aec --drift_compensation -agc --fixed_digital -hpf -ns ' ... | |
| '--ns_moderate']; | |
| else | |
| error(['TESTNAME ' tests{i} ' is not recognized']); | |
| end | |
| inpathtest = [inpath testdir]; | |
| outpathtest = [outpath testdir]; | |
| refpathtest = [refpath testdir]; | |
| if ~exist(inpathtest,'dir') | |
| error(['Input directory ' inpathtest ' does not exist']); | |
| end | |
| if ~exist(refpathtest,'dir') | |
| warning(['Reference directory ' refpathtest ' does not exist']); | |
| end | |
| [status, errMsg] = mkdir(outpathtest); | |
| if (status == 0) | |
| error(errMsg); | |
| end | |
| [nErr, nCases] = recurseDir(inpathtest, outpathtest, refpathtest, outfile, ... | |
| progname, opt, simulateMode, nErr, nCases, task, casenumber, legacy); | |
| if strcmp(task, 'test') || strcmp(task, 'show') | |
| system(['rm ' farFile]); | |
| system(['rm ' nearFile]); | |
| if simulateMode == false | |
| system(['rm ' eventFile]); | |
| system(['rm ' delayFile]); | |
| system(['rm ' driftFile]); | |
| end | |
| end | |
| end | |
| if ~strcmp(task, 'list') | |
| if nErr == 0 | |
| fprintf(1, '\nAll files are bit-exact to reference\n', nErr); | |
| else | |
| fprintf(1, '\n%d files are NOT bit-exact to reference\n', nErr); | |
| end | |
| end | |
| function [nErrOut, nCases] = recurseDir(inpath, outpath, refpath, ... | |
| outfile, progname, opt, simulateMode, nErr, nCases, task, casenumber, ... | |
| legacy) | |
| global farFile; | |
| global nearFile; | |
| global eventFile; | |
| global delayFile; | |
| global driftFile; | |
| dirs = dir(inpath); | |
| nDirs = 0; | |
| nErrOut = nErr; | |
| for i=3:length(dirs) % skip . and .. | |
| nDirs = nDirs + dirs(i).isdir; | |
| end | |
| if nDirs == 0 | |
| nCases = nCases + 1; | |
| if casenumber == nCases || casenumber == 0 | |
| if strcmp(task, 'list') | |
| fprintf([num2str(nCases) '. ' outfile '\n']) | |
| else | |
| vadoutfile = ['vad_' outfile '.dat']; | |
| outfile = [outfile '.pcm']; | |
| % Check for VAD test | |
| vadTest = 0; | |
| if ~isempty(findstr(opt, '-vad')) | |
| vadTest = 1; | |
| if legacy | |
| opt = [opt ' ' outpath vadoutfile]; | |
| else | |
| opt = [opt ' --vad_out_file ' outpath vadoutfile]; | |
| end | |
| end | |
| if exist([inpath 'vqeFar.pcm']) | |
| system(['ln -s -f ' inpath 'vqeFar.pcm ' farFile]); | |
| elseif exist([inpath 'apm_far.pcm']) | |
| system(['ln -s -f ' inpath 'apm_far.pcm ' farFile]); | |
| end | |
| if exist([inpath 'vqeNear.pcm']) | |
| system(['ln -s -f ' inpath 'vqeNear.pcm ' nearFile]); | |
| elseif exist([inpath 'apm_near.pcm']) | |
| system(['ln -s -f ' inpath 'apm_near.pcm ' nearFile]); | |
| end | |
| if exist([inpath 'vqeEvent.dat']) | |
| system(['ln -s -f ' inpath 'vqeEvent.dat ' eventFile]); | |
| elseif exist([inpath 'apm_event.dat']) | |
| system(['ln -s -f ' inpath 'apm_event.dat ' eventFile]); | |
| end | |
| if exist([inpath 'vqeBuf.dat']) | |
| system(['ln -s -f ' inpath 'vqeBuf.dat ' delayFile]); | |
| elseif exist([inpath 'apm_delay.dat']) | |
| system(['ln -s -f ' inpath 'apm_delay.dat ' delayFile]); | |
| end | |
| if exist([inpath 'vqeSkew.dat']) | |
| system(['ln -s -f ' inpath 'vqeSkew.dat ' driftFile]); | |
| elseif exist([inpath 'vqeDrift.dat']) | |
| system(['ln -s -f ' inpath 'vqeDrift.dat ' driftFile]); | |
| elseif exist([inpath 'apm_drift.dat']) | |
| system(['ln -s -f ' inpath 'apm_drift.dat ' driftFile]); | |
| end | |
| if simulateMode == false | |
| command = [progname ' -o ' outpath outfile ' ' opt]; | |
| else | |
| if legacy | |
| inputCmd = [' -in ' nearFile]; | |
| else | |
| inputCmd = [' -i ' nearFile]; | |
| end | |
| if exist([farFile]) | |
| if legacy | |
| inputCmd = [' -if ' farFile inputCmd]; | |
| else | |
| inputCmd = [' -ir ' farFile inputCmd]; | |
| end | |
| end | |
| command = [progname inputCmd ' -o ' outpath outfile ' ' opt]; | |
| end | |
| % This prevents MATLAB from using its own C libraries. | |
| shellcmd = ['bash -c "unset LD_LIBRARY_PATH;']; | |
| fprintf([command '\n']); | |
| [status, result] = system([shellcmd command '"']); | |
| fprintf(result); | |
| fprintf(['Reference file: ' refpath outfile '\n']); | |
| if vadTest == 1 | |
| equal_to_ref = are_files_equal([outpath vadoutfile], ... | |
| [refpath vadoutfile], ... | |
| 'int8'); | |
| if ~equal_to_ref | |
| nErr = nErr + 1; | |
| end | |
| end | |
| [equal_to_ref, diffvector] = are_files_equal([outpath outfile], ... | |
| [refpath outfile], ... | |
| 'int16'); | |
| if ~equal_to_ref | |
| nErr = nErr + 1; | |
| end | |
| if strcmp(task, 'show') | |
| % Assume the last init gives the sample rate of interest. | |
| str_idx = strfind(result, 'Sample rate:'); | |
| fs = str2num(result(str_idx(end) + 13:str_idx(end) + 17)); | |
| fprintf('Using %d Hz\n', fs); | |
| if exist([farFile]) | |
| spclab(fs, farFile, nearFile, [refpath outfile], ... | |
| [outpath outfile], diffvector); | |
| %spclab(fs, diffvector); | |
| else | |
| spclab(fs, nearFile, [refpath outfile], [outpath outfile], ... | |
| diffvector); | |
| %spclab(fs, diffvector); | |
| end | |
| end | |
| end | |
| end | |
| else | |
| for i=3:length(dirs) | |
| if dirs(i).isdir | |
| [nErr, nCases] = recurseDir([inpath dirs(i).name '/'], outpath, ... | |
| refpath,[outfile '_' dirs(i).name], progname, opt, ... | |
| simulateMode, nErr, nCases, task, casenumber, legacy); | |
| end | |
| end | |
| end | |
| nErrOut = nErr; | |
| function [are_equal, diffvector] = ... | |
| are_files_equal(newfile, reffile, precision, diffvector) | |
| are_equal = false; | |
| diffvector = 0; | |
| if ~exist(newfile,'file') | |
| warning(['Output file ' newfile ' does not exist']); | |
| return | |
| end | |
| if ~exist(reffile,'file') | |
| warning(['Reference file ' reffile ' does not exist']); | |
| return | |
| end | |
| fid = fopen(newfile,'rb'); | |
| new = fread(fid,inf,precision); | |
| fclose(fid); | |
| fid = fopen(reffile,'rb'); | |
| ref = fread(fid,inf,precision); | |
| fclose(fid); | |
| if length(new) ~= length(ref) | |
| warning('Reference is not the same length as output'); | |
| minlength = min(length(new), length(ref)); | |
| new = new(1:minlength); | |
| ref = ref(1:minlength); | |
| end | |
| diffvector = new - ref; | |
| if isequal(new, ref) | |
| fprintf([newfile ' is bit-exact to reference\n']); | |
| are_equal = true; | |
| else | |
| if isempty(new) | |
| warning([newfile ' is empty']); | |
| return | |
| end | |
| snr = snrseg(new,ref,80); | |
| fprintf('\n'); | |
| are_equal = false; | |
| end |