| % | 
 | %  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 |