ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 1 | function apmtest(task, testname, filepath, casenumber, legacy) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 2 | %APMTEST is a tool to process APM file sets and easily display the output. |
| 3 | % APMTEST(TASK, TESTNAME, CASENUMBER) performs one of several TASKs: |
| 4 | % 'test' Processes the files to produce test output. |
| 5 | % 'list' Prints a list of cases in the test set, preceded by their |
| 6 | % CASENUMBERs. |
| 7 | % 'show' Uses spclab to show the test case specified by the |
| 8 | % CASENUMBER parameter. |
| 9 | % |
| 10 | % using a set of test files determined by TESTNAME: |
| 11 | % 'all' All tests. |
| 12 | % 'apm' The standard APM test set (default). |
| 13 | % 'apmm' The mobile APM test set. |
| 14 | % 'aec' The AEC test set. |
| 15 | % 'aecm' The AECM test set. |
| 16 | % 'agc' The AGC test set. |
| 17 | % 'ns' The NS test set. |
| 18 | % 'vad' The VAD test set. |
| 19 | % |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 20 | % FILEPATH specifies the path to the test data files. |
| 21 | % |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 22 | % CASENUMBER can be used to select a single test case. Omit CASENUMBER, |
| 23 | % or set to zero, to use all test cases. |
| 24 | % |
| 25 | |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 26 | if nargin < 5 || isempty(legacy) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 27 | % Set to true to run old VQE recordings. |
| 28 | legacy = false; |
| 29 | end |
| 30 | |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 31 | if nargin < 4 || isempty(casenumber) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 32 | casenumber = 0; |
| 33 | end |
| 34 | |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 35 | if nargin < 3 || isempty(filepath) |
| 36 | filepath = 'data/'; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 37 | end |
| 38 | |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 39 | if nargin < 2 || isempty(testname) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 40 | testname = 'all'; |
| 41 | end |
| 42 | |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 43 | if nargin < 1 || isempty(task) |
| 44 | task = 'test'; |
| 45 | end |
| 46 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 47 | if ~strcmp(task, 'test') && ~strcmp(task, 'list') && ~strcmp(task, 'show') |
| 48 | error(['TASK ' task ' is not recognized']); |
| 49 | end |
| 50 | |
| 51 | if casenumber == 0 && strcmp(task, 'show') |
| 52 | error(['CASENUMBER must be specified for TASK ' task]); |
| 53 | end |
| 54 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 55 | inpath = [filepath 'input/']; |
| 56 | outpath = [filepath 'output/']; |
| 57 | refpath = [filepath 'reference/']; |
| 58 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 59 | if strcmp(testname, 'all') |
| 60 | tests = {'apm','apmm','aec','aecm','agc','ns','vad'}; |
| 61 | else |
| 62 | tests = {testname}; |
| 63 | end |
| 64 | |
| 65 | if legacy |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 66 | progname = './test'; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 67 | else |
| 68 | progname = './process_test'; |
| 69 | end |
| 70 | |
| 71 | global farFile; |
| 72 | global nearFile; |
| 73 | global eventFile; |
| 74 | global delayFile; |
| 75 | global driftFile; |
| 76 | |
| 77 | if legacy |
| 78 | farFile = 'vqeFar.pcm'; |
| 79 | nearFile = 'vqeNear.pcm'; |
| 80 | eventFile = 'vqeEvent.dat'; |
| 81 | delayFile = 'vqeBuf.dat'; |
| 82 | driftFile = 'vqeDrift.dat'; |
| 83 | else |
| 84 | farFile = 'apm_far.pcm'; |
| 85 | nearFile = 'apm_near.pcm'; |
| 86 | eventFile = 'apm_event.dat'; |
| 87 | delayFile = 'apm_delay.dat'; |
| 88 | driftFile = 'apm_drift.dat'; |
| 89 | end |
| 90 | |
| 91 | simulateMode = false; |
| 92 | nErr = 0; |
| 93 | nCases = 0; |
| 94 | for i=1:length(tests) |
| 95 | simulateMode = false; |
| 96 | |
| 97 | if strcmp(tests{i}, 'apm') |
| 98 | testdir = ['apm/']; |
| 99 | outfile = ['out']; |
| 100 | if legacy |
| 101 | opt = ['-ec 1 -agc 2 -nc 2 -vad 3']; |
| 102 | else |
| 103 | opt = ['--no_progress -hpf' ... |
| 104 | ' -aec --drift_compensation -agc --fixed_digital' ... |
| 105 | ' -ns --ns_moderate -vad']; |
| 106 | end |
| 107 | |
| 108 | elseif strcmp(tests{i}, 'apm-swb') |
| 109 | simulateMode = true; |
| 110 | testdir = ['apm-swb/']; |
| 111 | outfile = ['out']; |
| 112 | if legacy |
| 113 | opt = ['-fs 32000 -ec 1 -agc 2 -nc 2']; |
| 114 | else |
| 115 | opt = ['--no_progress -fs 32000 -hpf' ... |
| 116 | ' -aec --drift_compensation -agc --adaptive_digital' ... |
| 117 | ' -ns --ns_moderate -vad']; |
| 118 | end |
| 119 | elseif strcmp(tests{i}, 'apmm') |
| 120 | testdir = ['apmm/']; |
| 121 | outfile = ['out']; |
| 122 | opt = ['-aec --drift_compensation -agc --fixed_digital -hpf -ns ' ... |
| 123 | '--ns_moderate']; |
| 124 | |
| 125 | else |
| 126 | error(['TESTNAME ' tests{i} ' is not recognized']); |
| 127 | end |
| 128 | |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 129 | inpathtest = [inpath testdir]; |
| 130 | outpathtest = [outpath testdir]; |
| 131 | refpathtest = [refpath testdir]; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 132 | |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 133 | if ~exist(inpathtest,'dir') |
| 134 | error(['Input directory ' inpathtest ' does not exist']); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 135 | end |
| 136 | |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 137 | if ~exist(refpathtest,'dir') |
| 138 | warning(['Reference directory ' refpathtest ' does not exist']); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 139 | end |
| 140 | |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 141 | [status, errMsg] = mkdir(outpathtest); |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 142 | if (status == 0) |
| 143 | error(errMsg); |
| 144 | end |
| 145 | |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 146 | [nErr, nCases] = recurseDir(inpathtest, outpathtest, refpathtest, outfile, ... |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 147 | progname, opt, simulateMode, nErr, nCases, task, casenumber, legacy); |
| 148 | |
| 149 | if strcmp(task, 'test') || strcmp(task, 'show') |
| 150 | system(['rm ' farFile]); |
| 151 | system(['rm ' nearFile]); |
| 152 | if simulateMode == false |
| 153 | system(['rm ' eventFile]); |
| 154 | system(['rm ' delayFile]); |
| 155 | system(['rm ' driftFile]); |
| 156 | end |
| 157 | end |
| 158 | end |
| 159 | |
| 160 | if ~strcmp(task, 'list') |
| 161 | if nErr == 0 |
| 162 | fprintf(1, '\nAll files are bit-exact to reference\n', nErr); |
| 163 | else |
| 164 | fprintf(1, '\n%d files are NOT bit-exact to reference\n', nErr); |
| 165 | end |
| 166 | end |
| 167 | |
| 168 | |
| 169 | function [nErrOut, nCases] = recurseDir(inpath, outpath, refpath, ... |
| 170 | outfile, progname, opt, simulateMode, nErr, nCases, task, casenumber, ... |
| 171 | legacy) |
| 172 | |
| 173 | global farFile; |
| 174 | global nearFile; |
| 175 | global eventFile; |
| 176 | global delayFile; |
| 177 | global driftFile; |
| 178 | |
| 179 | dirs = dir(inpath); |
| 180 | nDirs = 0; |
| 181 | nErrOut = nErr; |
| 182 | for i=3:length(dirs) % skip . and .. |
| 183 | nDirs = nDirs + dirs(i).isdir; |
| 184 | end |
| 185 | |
| 186 | |
| 187 | if nDirs == 0 |
| 188 | nCases = nCases + 1; |
| 189 | |
| 190 | if casenumber == nCases || casenumber == 0 |
| 191 | |
| 192 | if strcmp(task, 'list') |
| 193 | fprintf([num2str(nCases) '. ' outfile '\n']) |
| 194 | else |
| 195 | vadoutfile = ['vad_' outfile '.dat']; |
| 196 | outfile = [outfile '.pcm']; |
| 197 | |
| 198 | % Check for VAD test |
| 199 | vadTest = 0; |
| 200 | if ~isempty(findstr(opt, '-vad')) |
| 201 | vadTest = 1; |
| 202 | if legacy |
| 203 | opt = [opt ' ' outpath vadoutfile]; |
| 204 | else |
| 205 | opt = [opt ' --vad_out_file ' outpath vadoutfile]; |
| 206 | end |
| 207 | end |
| 208 | |
| 209 | if exist([inpath 'vqeFar.pcm']) |
| 210 | system(['ln -s -f ' inpath 'vqeFar.pcm ' farFile]); |
| 211 | elseif exist([inpath 'apm_far.pcm']) |
| 212 | system(['ln -s -f ' inpath 'apm_far.pcm ' farFile]); |
| 213 | end |
| 214 | |
| 215 | if exist([inpath 'vqeNear.pcm']) |
| 216 | system(['ln -s -f ' inpath 'vqeNear.pcm ' nearFile]); |
| 217 | elseif exist([inpath 'apm_near.pcm']) |
| 218 | system(['ln -s -f ' inpath 'apm_near.pcm ' nearFile]); |
| 219 | end |
| 220 | |
| 221 | if exist([inpath 'vqeEvent.dat']) |
| 222 | system(['ln -s -f ' inpath 'vqeEvent.dat ' eventFile]); |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 223 | elseif exist([inpath 'apm_event.dat']) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 224 | system(['ln -s -f ' inpath 'apm_event.dat ' eventFile]); |
| 225 | end |
| 226 | |
| 227 | if exist([inpath 'vqeBuf.dat']) |
| 228 | system(['ln -s -f ' inpath 'vqeBuf.dat ' delayFile]); |
ajm@google.com | aace5b6 | 2011-07-26 21:02:24 +0000 | [diff] [blame] | 229 | elseif exist([inpath 'apm_delay.dat']) |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 230 | system(['ln -s -f ' inpath 'apm_delay.dat ' delayFile]); |
| 231 | end |
| 232 | |
| 233 | if exist([inpath 'vqeSkew.dat']) |
| 234 | system(['ln -s -f ' inpath 'vqeSkew.dat ' driftFile]); |
| 235 | elseif exist([inpath 'vqeDrift.dat']) |
| 236 | system(['ln -s -f ' inpath 'vqeDrift.dat ' driftFile]); |
| 237 | elseif exist([inpath 'apm_drift.dat']) |
| 238 | system(['ln -s -f ' inpath 'apm_drift.dat ' driftFile]); |
| 239 | end |
| 240 | |
| 241 | if simulateMode == false |
| 242 | command = [progname ' -o ' outpath outfile ' ' opt]; |
| 243 | else |
| 244 | if legacy |
| 245 | inputCmd = [' -in ' nearFile]; |
| 246 | else |
| 247 | inputCmd = [' -i ' nearFile]; |
| 248 | end |
| 249 | |
| 250 | if exist([farFile]) |
| 251 | if legacy |
| 252 | inputCmd = [' -if ' farFile inputCmd]; |
| 253 | else |
| 254 | inputCmd = [' -ir ' farFile inputCmd]; |
| 255 | end |
| 256 | end |
| 257 | command = [progname inputCmd ' -o ' outpath outfile ' ' opt]; |
| 258 | end |
| 259 | % This prevents MATLAB from using its own C libraries. |
| 260 | shellcmd = ['bash -c "unset LD_LIBRARY_PATH;']; |
| 261 | fprintf([command '\n']); |
| 262 | [status, result] = system([shellcmd command '"']); |
| 263 | fprintf(result); |
| 264 | |
| 265 | fprintf(['Reference file: ' refpath outfile '\n']); |
| 266 | |
| 267 | if vadTest == 1 |
| 268 | equal_to_ref = are_files_equal([outpath vadoutfile], ... |
| 269 | [refpath vadoutfile], ... |
| 270 | 'int8'); |
| 271 | if ~equal_to_ref |
| 272 | nErr = nErr + 1; |
| 273 | end |
| 274 | end |
| 275 | |
| 276 | [equal_to_ref, diffvector] = are_files_equal([outpath outfile], ... |
| 277 | [refpath outfile], ... |
| 278 | 'int16'); |
| 279 | if ~equal_to_ref |
| 280 | nErr = nErr + 1; |
| 281 | end |
| 282 | |
| 283 | if strcmp(task, 'show') |
| 284 | % Assume the last init gives the sample rate of interest. |
| 285 | str_idx = strfind(result, 'Sample rate:'); |
| 286 | fs = str2num(result(str_idx(end) + 13:str_idx(end) + 17)); |
| 287 | fprintf('Using %d Hz\n', fs); |
| 288 | |
| 289 | if exist([farFile]) |
| 290 | spclab(fs, farFile, nearFile, [refpath outfile], ... |
| 291 | [outpath outfile], diffvector); |
| 292 | %spclab(fs, diffvector); |
| 293 | else |
| 294 | spclab(fs, nearFile, [refpath outfile], [outpath outfile], ... |
| 295 | diffvector); |
| 296 | %spclab(fs, diffvector); |
| 297 | end |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 298 | end |
| 299 | end |
| 300 | end |
| 301 | else |
| 302 | |
| 303 | for i=3:length(dirs) |
| 304 | if dirs(i).isdir |
| 305 | [nErr, nCases] = recurseDir([inpath dirs(i).name '/'], outpath, ... |
| 306 | refpath,[outfile '_' dirs(i).name], progname, opt, ... |
| 307 | simulateMode, nErr, nCases, task, casenumber, legacy); |
| 308 | end |
| 309 | end |
| 310 | end |
| 311 | nErrOut = nErr; |
| 312 | |
| 313 | function [are_equal, diffvector] = ... |
| 314 | are_files_equal(newfile, reffile, precision, diffvector) |
| 315 | |
| 316 | are_equal = false; |
| 317 | diffvector = 0; |
| 318 | if ~exist(newfile,'file') |
| 319 | warning(['Output file ' newfile ' does not exist']); |
| 320 | return |
| 321 | end |
| 322 | |
| 323 | if ~exist(reffile,'file') |
| 324 | warning(['Reference file ' reffile ' does not exist']); |
| 325 | return |
| 326 | end |
| 327 | |
| 328 | fid = fopen(newfile,'rb'); |
| 329 | new = fread(fid,inf,precision); |
| 330 | fclose(fid); |
| 331 | |
| 332 | fid = fopen(reffile,'rb'); |
| 333 | ref = fread(fid,inf,precision); |
| 334 | fclose(fid); |
| 335 | |
| 336 | if length(new) ~= length(ref) |
| 337 | warning('Reference is not the same length as output'); |
| 338 | minlength = min(length(new), length(ref)); |
| 339 | new = new(1:minlength); |
| 340 | ref = ref(1:minlength); |
| 341 | end |
| 342 | diffvector = new - ref; |
| 343 | |
| 344 | if isequal(new, ref) |
| 345 | fprintf([newfile ' is bit-exact to reference\n']); |
| 346 | are_equal = true; |
| 347 | else |
| 348 | if isempty(new) |
| 349 | warning([newfile ' is empty']); |
| 350 | return |
| 351 | end |
| 352 | snr = snrseg(new,ref,80); |
| 353 | fprintf('\n'); |
| 354 | are_equal = false; |
| 355 | end |