50 lines
1.7 KiB
JavaScript
50 lines
1.7 KiB
JavaScript
|
|
// SPDX-License-Identifier: Apache-2.0
|
||
|
|
//
|
||
|
|
// Analysis worker: the browser's AnalysisResultsManager worker thread.
|
||
|
|
//
|
||
|
|
// Holds each loaded track's mono signal (transferred in, never copied) and runs
|
||
|
|
// one metric at a time on request, so a 10-minute spectrogram never blocks the
|
||
|
|
// page. Everything stays in this tab's memory; closing the tab frees it.
|
||
|
|
//
|
||
|
|
// Messages in: {type: 'load', trackId, mono, sampleRate}
|
||
|
|
// {type: 'compute', reqId, trackId, metricId}
|
||
|
|
// {type: 'drop', trackId}
|
||
|
|
// Messages out: {type: 'result', reqId, trackId, metricId, data, ms}
|
||
|
|
// {type: 'error', reqId, trackId, metricId, message}
|
||
|
|
|
||
|
|
import { COMPUTE, transferables } from './dsp.js';
|
||
|
|
|
||
|
|
const tracks = new Map(); // trackId -> {mono, sampleRate, memo}
|
||
|
|
|
||
|
|
self.onmessage = (event) => {
|
||
|
|
const msg = event.data;
|
||
|
|
if (msg.type === 'load') {
|
||
|
|
tracks.set(msg.trackId, { mono: msg.mono, sampleRate: msg.sampleRate, memo: {} });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (msg.type === 'drop') {
|
||
|
|
tracks.delete(msg.trackId);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (msg.type !== 'compute') return;
|
||
|
|
|
||
|
|
const { reqId, trackId, metricId } = msg;
|
||
|
|
const track = tracks.get(trackId);
|
||
|
|
const compute = COMPUTE[metricId];
|
||
|
|
if (!track || !compute) {
|
||
|
|
self.postMessage({
|
||
|
|
type: 'error', reqId, trackId, metricId,
|
||
|
|
message: track ? `unknown metric ${metricId}` : 'track is no longer loaded',
|
||
|
|
});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
try {
|
||
|
|
const t0 = performance.now();
|
||
|
|
const data = compute(track.mono, track.sampleRate, track.memo);
|
||
|
|
const ms = performance.now() - t0;
|
||
|
|
self.postMessage({ type: 'result', reqId, trackId, metricId, data, ms }, transferables(data));
|
||
|
|
} catch (err) {
|
||
|
|
self.postMessage({ type: 'error', reqId, trackId, metricId, message: String((err && err.message) || err) });
|
||
|
|
}
|
||
|
|
};
|