add test for file analysis. hotlist output bugfix
This commit is contained in:
parent
2889e7de11
commit
783c1e8a6a
|
@ -2,6 +2,7 @@ log/
|
|||
model/
|
||||
node_modules/
|
||||
records/
|
||||
test/file.mp3.json
|
||||
.vscode/
|
||||
podcasts/
|
||||
webradio-metadata.js
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,7 @@
|
|||
"description": "Distinguish ads, talk and music in radios",
|
||||
"main": "post-processing.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "mocha --delay"
|
||||
},
|
||||
"keywords": [
|
||||
"adblock",
|
||||
|
@ -31,6 +31,7 @@
|
|||
"aws-sdk": "^2.408.0",
|
||||
"electron-builder": "^20.38.5",
|
||||
"electron-prebuilt": "^1.4.13",
|
||||
"electron-rebuild": "^1.8.4"
|
||||
"electron-rebuild": "^1.8.4",
|
||||
"mocha": "^6.0.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@ const consts = {
|
|||
}
|
||||
}
|
||||
|
||||
const toFixed = function(num, digits) {
|
||||
return Math.round(num * Math.pow(10, digits)) / Math.pow(10, digits);
|
||||
}
|
||||
|
||||
class Hotlist extends Writable {
|
||||
constructor(options) {
|
||||
super({ objectMode: true });
|
||||
|
@ -262,11 +266,11 @@ class Hotlist extends Writable {
|
|||
fingersCountMeasurements: tcodes.length, // amount of fingerprints generated by measurements
|
||||
|
||||
// confidence factors
|
||||
ratioFingersReference: ratioFingersReference.toFixed(5),
|
||||
ratioFingersMeasurements: ratioFingersMeasurements.toFixed(5),
|
||||
matchingFocus: matchingFocus.toFixed(5),
|
||||
confidence1: confidence1.toFixed(5),
|
||||
confidence2: confidence2.toFixed(5),
|
||||
ratioFingersReference: toFixed(ratioFingersReference, 5),
|
||||
ratioFingersMeasurements: toFixed(ratioFingersMeasurements, 5),
|
||||
matchingFocus: toFixed(matchingFocus, 5),
|
||||
confidence1: toFixed(confidence1, 5),
|
||||
confidence2: toFixed(confidence2, 5),
|
||||
softmaxraw: softmax,
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ class MlPredictor extends Writable {
|
|||
_final() {
|
||||
if (this.child) {
|
||||
this.child.kill();
|
||||
log.info(this.canonical + " killed child process.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
const { log } = require("abr-log")("test-file");
|
||||
const { Analyser } = require("../post-processing.js");
|
||||
const fs = require("fs-extra");
|
||||
const assert = require("assert");
|
||||
const cluster = require("cluster");
|
||||
|
||||
const FILE = __dirname + '/file.mp3';
|
||||
const TEST_ML = true;
|
||||
const TEST_HOTLIST = true;
|
||||
const PRED_INTERVAL = 1; // in seconds
|
||||
|
||||
if (cluster.isMaster) {
|
||||
|
||||
const TIMEOUT = 30000; // this must be at least the length of the audio tested
|
||||
|
||||
let cp = null;
|
||||
let gotData = false;
|
||||
let finished = false;
|
||||
let hasErrors = false;
|
||||
let exited = false;
|
||||
let exitCode = null;
|
||||
let timedOut = false;
|
||||
let fileOutput = {};
|
||||
let fileOutputIsSane = false;
|
||||
|
||||
const timer = setTimeout(function() {
|
||||
log.error('analysis timed out or was too slow. kill it.');
|
||||
timedOut = true;
|
||||
console.log(getEventListeners(node));
|
||||
|
||||
cp.kill();
|
||||
run();
|
||||
}, TIMEOUT);
|
||||
|
||||
fs.unlink(FILE + '.json', function(err) {
|
||||
// we ignore err here.
|
||||
cp = cluster.fork();
|
||||
cp.on('message', function(msg) {
|
||||
if (msg.type === 'data') {
|
||||
if (msg.data) {
|
||||
gotData = true;
|
||||
}
|
||||
} else if (msg.type === 'end') {
|
||||
finished = true;
|
||||
}
|
||||
});
|
||||
|
||||
cp.on('error', function(err) {
|
||||
log.error('child process had an error: ' + err);
|
||||
hasErrors = true;
|
||||
});
|
||||
|
||||
cp.on('exit', function(code) {
|
||||
exited = true;
|
||||
exitCode = code;
|
||||
clearTimeout(timer);
|
||||
|
||||
fs.readFile(FILE + '.json', function(err, data) {
|
||||
try {
|
||||
fileOutput = JSON.parse(data);
|
||||
fileOutputIsSane = true;
|
||||
} catch (e) {
|
||||
fileOutputIsSane = false;
|
||||
}
|
||||
run();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// for debug purposes. test the previous results directly, without redoing the computations
|
||||
// if you want to do so, comment out the code above
|
||||
/*fs.readFile(FILE + '.json', function(err, data) {
|
||||
fileOutputIsSane = true;
|
||||
fileOutput = JSON.parse(data);
|
||||
run();
|
||||
});*/
|
||||
|
||||
describe('File analysis', function() {
|
||||
|
||||
it("should have emitted data", function() {
|
||||
assert(gotData);
|
||||
});
|
||||
|
||||
it("should have reached the end of the file", function() {
|
||||
assert(finished);
|
||||
});
|
||||
|
||||
it("should not have thrown errors", function() {
|
||||
assert(!hasErrors);
|
||||
});
|
||||
|
||||
it("should have exited properly", function() {
|
||||
assert(exited);
|
||||
assert.equal(exitCode, 0);
|
||||
assert(!timedOut);
|
||||
});
|
||||
|
||||
it("should write results in JSON format", function() {
|
||||
assert(fileOutputIsSane);
|
||||
assert(fileOutput.country);
|
||||
assert(fileOutput.name);
|
||||
|
||||
const blocks = [fileOutput.blocksRaw, fileOutput.blocksCoarse, fileOutput.blocksCleaned];
|
||||
for (let ib = 0; ib<blocks.length; ib++) {
|
||||
const block = blocks[ib];
|
||||
assert(block.length);
|
||||
for (let i=0; i<block.length; i++) {
|
||||
assert(!isNaN(block[i].tStart));
|
||||
assert(!isNaN(block[i].tEnd));
|
||||
assert(['0-ads', '1-speech', '2-music', '3-jingles', 'unsure'].includes(block[i].class));
|
||||
}
|
||||
}
|
||||
|
||||
assert(fileOutput.predictions);
|
||||
for (let i=0; i<fileOutput.predictions.length; i++) {
|
||||
const p = fileOutput.predictions[i];
|
||||
assert(p);
|
||||
|
||||
if (TEST_ML) {
|
||||
assert(p.gain > 60 && p.gain < 85);
|
||||
assert(p.ml);
|
||||
assert(['0-ads', '1-speech', '2-music'].includes(p.ml.class));
|
||||
assert(p.ml.softmaxraw);
|
||||
assert.equal(p.ml.softmaxraw.length, 4);
|
||||
assert(p.ml.softmax);
|
||||
assert.equal(p.ml.softmax.length, 4);
|
||||
assert(!isNaN(p.ml.slotsFuture));
|
||||
assert(!isNaN(p.ml.slotsPast));
|
||||
} else {
|
||||
assert.equal(p.ml, null);
|
||||
}
|
||||
|
||||
if (TEST_HOTLIST) {
|
||||
assert(p.hotlist);
|
||||
assert(['0-ads', '1-speech', '2-music', '3-jingles', 'unsure'].includes(p.hotlist.class));
|
||||
assert(p.hotlist.softmaxraw);
|
||||
assert.equal(p.hotlist.softmaxraw.length, 4);
|
||||
assert(p.hotlist.softmax);
|
||||
assert.equal(p.hotlist.softmax.length, 4);
|
||||
assert(!isNaN(p.hotlist.matchesSync));
|
||||
assert(!isNaN(p.hotlist.matchesTotal));
|
||||
assert(!isNaN(p.hotlist.confidence1));
|
||||
assert(0 <= p.hotlist.confidence1);
|
||||
assert(p.hotlist.confidence1 <= 1);
|
||||
assert(!isNaN(p.hotlist.confidence2));
|
||||
assert(0 <= p.hotlist.confidence2);
|
||||
assert(p.hotlist.confidence2 <= 1);
|
||||
} else {
|
||||
assert.equal(p.hotlist, null);
|
||||
}
|
||||
|
||||
assert(['0-ads', '1-speech', '2-music', '3-jingles', 'unsure'].includes(p.class));
|
||||
assert(!isNaN(p.tStart));
|
||||
assert(!isNaN(p.tEnd));
|
||||
assert(p.tEnd > p.tStart);
|
||||
assert(p.tEnd <= p.tStart + PRED_INTERVAL * 1000);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
const t1 = new Date();
|
||||
|
||||
const abr = new Analyser({
|
||||
country: "France",
|
||||
name: "RTL",
|
||||
config: {
|
||||
file: FILE,
|
||||
predInterval: PRED_INTERVAL,
|
||||
enablePredictorHotlist: TEST_HOTLIST,
|
||||
enablePredictorMl: TEST_ML,
|
||||
saveMetadata: true,
|
||||
verbose: false,
|
||||
}
|
||||
});
|
||||
|
||||
abr.on("data", function(obj) {
|
||||
//log.info(JSON.stringify(obj, null, "\t"));
|
||||
process.send({ type: 'data', data: obj });
|
||||
});
|
||||
|
||||
abr.on("end", function() {
|
||||
const t2 = new Date();
|
||||
log.info("finished analysing file " + FILE + " in " + (+t2-t1)/1000 + " seconds");
|
||||
process.send({ type: 'end' });
|
||||
process.disconnect(); // otherwise the IPC prevents the subprocess from gracefully exiting
|
||||
});
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue