49 lines
1.8 KiB
JavaScript
49 lines
1.8 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import { test } from "node:test";
|
|
import vm from "node:vm";
|
|
|
|
function processor() {
|
|
let Processor;
|
|
class Base {
|
|
constructor() {
|
|
this.port = { sent: [], postMessage(data) { this.sent.push(data); } };
|
|
}
|
|
}
|
|
vm.runInNewContext(readFileSync(new URL("../../src/voice_assistant/audio_gateway/web/pcm-worklet.js", import.meta.url), "utf8"), {
|
|
AudioWorkletProcessor: Base, sampleRate: 16000,
|
|
registerProcessor(name, constructor) { assert.equal(name, "pcm-input"); Processor = constructor; },
|
|
});
|
|
return new Processor();
|
|
}
|
|
|
|
test("negotiated capture emits complete little-endian PCM16 frames", () => {
|
|
const input = processor();
|
|
input.port.onmessage({ data: { type: "start", chunkSamples: 2 } });
|
|
input.process([[new Float32Array([-1, 0, 1])]]);
|
|
const chunk = input.port.sent[0];
|
|
assert.equal(chunk.type, "pcm");
|
|
assert.equal(chunk.buffer.byteLength, 4);
|
|
const samples = new DataView(chunk.buffer);
|
|
assert.equal(samples.getInt16(0, true), -32768);
|
|
assert.equal(samples.getInt16(2, true), 0);
|
|
});
|
|
|
|
test("capture continues across process callbacks until stop", () => {
|
|
const input = processor();
|
|
input.port.onmessage({ data: { type: "start", chunkSamples: 2 } });
|
|
input.process([[new Float32Array([0, 0, 0])]]);
|
|
input.process([[new Float32Array([0, 0])]]);
|
|
assert.equal(input.port.sent.filter((event) => event.type === "pcm").length, 2);
|
|
input.port.onmessage({ data: { type: "stop" } });
|
|
input.process([[new Float32Array([0, 0, 0])]]);
|
|
assert.equal(input.port.sent.length, 2);
|
|
});
|
|
|
|
test("invalid capture window reports an error", () => {
|
|
const input = processor();
|
|
input.port.onmessage({ data: { type: "start", chunkSamples: 0 } });
|
|
assert.equal(input.port.sent[0].type, "error");
|
|
assert.equal(input.capturing, false);
|
|
});
|