Fix regression in recognizer delete()

This commit is contained in:
msqr1
2024-09-28 12:23:33 -07:00
parent 479f611d00
commit 3290a321f2
6 changed files with 29 additions and 30 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
Binary file not shown.
+1 -1
View File
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.
+22 -23
View File
@@ -4,17 +4,18 @@
*/ */
let objs = []; let objs = [];
let events = ["status", "partialResult", "result"]; let events = ['status', 'partialResult', 'result'];
let storageWorkerURL = URL.createObjectURL(new Blob(['(', (() => { let storageWorkerURL = URL.createObjectURL(new Blob(['(', (async () => {
let txtDecoder = new TextDecoder(); let txtDecoder = new TextDecoder();
let txtEncoder = new TextEncoder(); let txtEncoder = new TextEncoder();
let OPFSRoot = await navigator.storage.getDirectory();
onmessage = async msg => { onmessage = async msg => {
msg = msg.data; msg = msg.data;
let components = msg.storepath.split("/"); let components = msg.storepath.split('/');
let prevDir = await navigator.storage.getDirectory(); let prevDir = OPFSRoot;
for(let component of components) prevDir = await prevDir.getDirectoryHandle(component, { create: true }); for(let component of components) prevDir = await prevDir.getDirectoryHandle(component, { create: true });
let idHandle = await prevDir.getFileHandle("id", { create: true }); let idHandle = await prevDir.getFileHandle('id', { create: true });
let mdlHandle = await prevDir.getFileHandle("model.tgz", { create: true }); let mdlHandle = await prevDir.getFileHandle('model.tgz', { create: true });
let idFile = await idHandle.createSyncAccessHandle(); let idFile = await idHandle.createSyncAccessHandle();
let mdlFile = await mdlHandle.createSyncAccessHandle(); let mdlFile = await mdlHandle.createSyncAccessHandle();
let oldIdBuf = new ArrayBuffer(idFile.getSize()); let oldIdBuf = new ArrayBuffer(idFile.getSize());
@@ -23,16 +24,16 @@ let storageWorkerURL = URL.createObjectURL(new Blob(['(', (() => {
if(txtDecoder.decode(oldIdBuf) == msg.id) { if(txtDecoder.decode(oldIdBuf) == msg.id) {
tgz = new ArrayBuffer(mdlFile.getSize()); tgz = new ArrayBuffer(mdlFile.getSize());
mdlFile.read(tgz); mdlFile.read(tgz);
tar = await new Response(new Response(tgz).body.pipeThrough(new DecompressionStream("gzip"))).arrayBuffer(); tar = await new Response(new Response(tgz).body.pipeThrough(new DecompressionStream('gzip'))).arrayBuffer();
} }
else { else {
let res = await fetch(msg.url); let res = await fetch(msg.url);
if(!res.ok) { if(!res.ok) {
postMessage("Unable to download model"); postMessage('Unable to download model');
return; return;
} }
let teed = res.body.tee(); let teed = res.body.tee();
tgz = await new Response(teed[0].pipeThrough(new CompressionStream("gzip"))).arrayBuffer(); tgz = await new Response(teed[0].pipeThrough(new CompressionStream('gzip'))).arrayBuffer();
mdlFile.write(tgz, { at: 0 }); mdlFile.write(tgz, { at: 0 });
mdlFile.truncate(tgz.byteLength); mdlFile.truncate(tgz.byteLength);
let newId = txtEncoder.encode(msg.id); let newId = txtEncoder.encode(msg.id);
@@ -44,10 +45,10 @@ let storageWorkerURL = URL.createObjectURL(new Blob(['(', (() => {
mdlFile.close(); mdlFile.close();
self.postMessage(tar, [tar]); self.postMessage(tar, [tar]);
} }
}).toString(), ')()'], { type: "text/javascript" })) }).toString(), ')()'], { type: 'text/javascript' }))
let storageWorker = new Worker(storageWorkerURL); let storageWorker = new Worker(storageWorkerURL);
let processorURL = URL.createObjectURL(new Blob(['(', (() => { let processorURL = URL.createObjectURL(new Blob(['(', (() => {
registerProcessor("VoskletTransferer", class extends AudioWorkletProcessor { registerProcessor('VoskletTransferer', class extends AudioWorkletProcessor {
constructor(opts) { constructor(opts) {
super(); super();
this.count = 0; this.count = 0;
@@ -65,7 +66,7 @@ let processorURL = URL.createObjectURL(new Blob(['(', (() => {
return true; return true;
} }
}) })
}).toString(), ')()'], { type: "text/javascript" })); }).toString(), ')()'], { type: 'text/javascript' }));
Module['cleanUp'] = async () => { Module['cleanUp'] = async () => {
for(let obj of objs) await obj.delete(); for(let obj of objs) await obj.delete();
@@ -76,8 +77,8 @@ Module['cleanUp'] = async () => {
Module['createTransferer'] = async (ctx, bufferSize) => { Module['createTransferer'] = async (ctx, bufferSize) => {
await ctx.audioWorklet.addModule(processorURL); await ctx.audioWorklet.addModule(processorURL);
return new AudioWorkletNode(ctx, "VoskletTransferer", { return new AudioWorkletNode(ctx, 'VoskletTransferer', {
channelCountMode: "explicit", channelCountMode: 'explicit',
numberOfInputs: 1, numberOfInputs: 1,
numberOfOutputs: 0, numberOfOutputs: 0,
channelCount: 1, channelCount: 1,
@@ -96,7 +97,7 @@ class CommonModel extends EventTarget {
static async mk(url, storepath, id, normalMdl) { static async mk(url, storepath, id, normalMdl) {
let mdl = new CommonModel(); let mdl = new CommonModel();
let result = new Promise((resolve, reject) => { let result = new Promise((resolve, reject) => {
mdl.addEventListener("status", ev => { mdl.addEventListener('status', ev => {
if(!ev.detail) { if(!ev.detail) {
if(normalMdl) mdl['findWord'] = word => mdl.obj['findWord'](word) if(normalMdl) mdl['findWord'] = word => mdl.obj['findWord'](word)
resolve(mdl) resolve(mdl)
@@ -104,11 +105,11 @@ class CommonModel extends EventTarget {
else reject(ev.detail) else reject(ev.detail)
}, { once: true }) }, { once: true })
}); });
storageWorker.addEventListener("message", tar => { storageWorker.addEventListener('message', tar => {
tar = tar.data; tar = tar.data;
let tarStart = _malloc(tar.byteLength); let tarStart = _malloc(tar.byteLength);
HEAPU8.set(new Uint8Array(tar), tarStart); HEAPU8.set(new Uint8Array(tar), tarStart);
mdl.obj = new Module['CommonModel'](objs.length - 1, normalMdl, "/" + storepath, id, tarStart, tar.byteLength); mdl.obj = new Module['CommonModel'](objs.length - 1, normalMdl, '/' + storepath, id, tarStart, tar.byteLength);
}, { once: true }); }, { once: true });
storageWorker.postMessage({ storageWorker.postMessage({
url: url, url: url,
@@ -128,7 +129,7 @@ Module['createSpkModel'] = async (url, storepath, id) =>
class Recognizer extends EventTarget { class Recognizer extends EventTarget {
constructor() { constructor() {
super(); super();
// Closure workaround, this is removed if I put it as a regular class function. For some reason delete() doesn't // Closure workaround to prevent acceptWaveform from getting removed
this['acceptWaveform'] = audioData => { this['acceptWaveform'] = audioData => {
let start = _malloc(audioData.length * 4); let start = _malloc(audioData.length * 4);
HEAPF32.set(audioData, start / 4); HEAPF32.set(audioData, start / 4);
@@ -146,17 +147,17 @@ class Recognizer extends EventTarget {
}) })
} }
async delete(processCurrent = false) { async delete(processCurrent = false) {
let result = new Promise((resolve, _) => this.addEventListener("status", _ => { let result = new Promise((resolve, _) => this.addEventListener('status', _ => {
this.obj.delete(); this.obj.delete();
resolve(); resolve();
}, { once: true })); }, { once: true }));
this.obj.safeDelete(processCurrent); this.obj['safeDelete'](processCurrent);
return result; return result;
} }
static async mk(model, sampleRate, mode, grammar, spkModel) { static async mk(model, sampleRate, mode, grammar, spkModel) {
let rec = new Recognizer(); let rec = new Recognizer();
let result = new Promise((resolve, reject) => { let result = new Promise((resolve, reject) => {
rec.addEventListener("status", ev => { rec.addEventListener('status', ev => {
if(!ev.detail) resolve(rec); if(!ev.detail) resolve(rec);
else reject(ev.detail); else reject(ev.detail);
}, { once: true }); }, { once: true });
@@ -183,5 +184,3 @@ Module['createRecognizerWithSpkModel'] = (model, sampleRate, spkModel) =>
Module['createRecognizerWithGrm'] = (model, sampleRate, grammar) => Module['createRecognizerWithGrm'] = (model, sampleRate, grammar) =>
Recognizer.mk(model.obj, sampleRate, 3, grammar, null); Recognizer.mk(model.obj, sampleRate, 3, grammar, null);
+3 -3
View File
@@ -36,12 +36,12 @@ OPENFST=$(realpath openfst)
CLAPACK_WASM=$(realpath clapack-wasm) CLAPACK_WASM=$(realpath clapack-wasm)
cd src && cd src &&
MODE=1 && # 0: Debug, 1: Optimized release MODE=0 && # 0: Debug, 1: Optimized release
echo "Mode = $MODE" && echo "Mode = $MODE" &&
if [ "$MODE" = 0 ]; then if [ "$MODE" = 0 ]; then
em++ Util.cc CommonModel.cc Recognizer.cc Bindings.cc -O0 -std=c++23 -g3 -Wall -Wextra -Wpedantic -DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0 -fno-rtti -DMAX_WORKERS="$MAX_THREADS" -sWASMFS -sWASM_BIGINT -sMODULARIZE -sWASM_EXNREF -sTEXTDECODER=2 -sWASM_WORKERS=2 -sEVAL_CTORS=2 -sSTACK_OVERFLOW_CHECK=2 -sASSERTIONS=2 -sINITIAL_MEMORY="$INITIAL_MEMORY" -sALLOW_MEMORY_GROWTH -sRUNTIME_DEBUG -sPOLYFILL=0 -sEXIT_RUNTIME=0 -sINVOKE_RUN=0 -sDISABLE_EXCEPTION_CATCHING=0 -sINCOMING_MODULE_JS_API=wasmMemory,instantiateWasm,wasm -sEXPORT_NAME=loadVosklet -sMALLOC=emmalloc -sENVIRONMENT=web,worker -I. -I"$VOSK"/src -L"$KALDI"/src -l:online2/kaldi-online2.a -l:decoder/kaldi-decoder.a -l:ivector/kaldi-ivector.a -l:gmm/kaldi-gmm.a -l:tree/kaldi-tree.a -l:feat/kaldi-feat.a -l:cudamatrix/kaldi-cudamatrix.a -l:lat/kaldi-lat.a -l:lm/kaldi-lm.a -l:rnnlm/kaldi-rnnlm.a -l:hmm/kaldi-hmm.a -l:nnet3/kaldi-nnet3.a -l:transform/kaldi-transform.a -l:matrix/kaldi-matrix.a -l:fstext/kaldi-fstext.a -l:util/kaldi-util.a -l:base/kaldi-base.a -L"$OPENFST"/lib -l:libfst.a -l:libfstngram.a -L"$CLAPACK_WASM" -l:CBLAS/lib/cblas.a -l:CLAPACK-3.2.1/lapack.a -l:CLAPACK-3.2.1/libcblaswr.a -l:f2c_BLAS-3.8.0/blas.a -l:libf2c/libf2c.a -L"$VOSK"/src -l:vosk.a -lembind -msimd128 -matomics -mbulk-memory -mreference-types -mnontrapping-fptoint -mextended-const -msign-ext -mmutable-globals --pre-js Wrapper.js -o ../test.js em++ Util.cc CommonModel.cc Recognizer.cc Bindings.cc -O0 -std=c++23 -g3 -Wall -Wextra -Wpedantic -fno-rtti -DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0 -DMAX_WORKERS="$MAX_THREADS" -sWASMFS -sWASM_BIGINT -sMODULARIZE -sWASM_EXNREF -sTEXTDECODER=2 -sWASM_WORKERS=2 -sEVAL_CTORS=2 -sSTACK_OVERFLOW_CHECK=2 -sASSERTIONS=2 -sINITIAL_MEMORY="$INITIAL_MEMORY" -sALLOW_MEMORY_GROWTH -sRUNTIME_DEBUG -sPOLYFILL=0 -sEXIT_RUNTIME=0 -sINVOKE_RUN=0 -sDISABLE_EXCEPTION_CATCHING=0 -sINCOMING_MODULE_JS_API=wasmMemory,instantiateWasm,wasm -sEXPORT_NAME=loadVosklet -sMALLOC=emmalloc -sENVIRONMENT=web,worker -I. -I"$VOSK"/src -L"$KALDI"/src -l:online2/kaldi-online2.a -l:decoder/kaldi-decoder.a -l:ivector/kaldi-ivector.a -l:gmm/kaldi-gmm.a -l:tree/kaldi-tree.a -l:feat/kaldi-feat.a -l:cudamatrix/kaldi-cudamatrix.a -l:lat/kaldi-lat.a -l:lm/kaldi-lm.a -l:rnnlm/kaldi-rnnlm.a -l:hmm/kaldi-hmm.a -l:nnet3/kaldi-nnet3.a -l:transform/kaldi-transform.a -l:matrix/kaldi-matrix.a -l:fstext/kaldi-fstext.a -l:util/kaldi-util.a -l:base/kaldi-base.a -L"$OPENFST"/lib -l:libfst.a -l:libfstngram.a -L"$CLAPACK_WASM" -l:CBLAS/lib/cblas.a -l:CLAPACK-3.2.1/lapack.a -l:CLAPACK-3.2.1/libcblaswr.a -l:f2c_BLAS-3.8.0/blas.a -l:libf2c/libf2c.a -L"$VOSK"/src -l:vosk.a -lembind -msimd128 -matomics -mbulk-memory -mreference-types -mnontrapping-fptoint -mextended-const -msign-ext -mmutable-globals --pre-js Wrapper.js -o ../test.js
elif [ "$MODE" = 1 ]; then elif [ "$MODE" = 1 ]; then
em++ Util.cc CommonModel.cc Recognizer.cc Bindings.cc -std=c++23 -O3 -Wall -Wextra -Wpedantic -DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0 -fno-rtti -DMAX_WORKERS="$MAX_THREADS" -sWASMFS -sWASM_BIGINT -sMODULARIZE -sWASM_EXNREF -sTEXTDECODER=2 -sWASM_WORKERS=2 -sEVAL_CTORS=2 -sINITIAL_MEMORY="$INITIAL_MEMORY" -sALLOW_MEMORY_GROWTH -sPOLYFILL=0 -sEXIT_RUNTIME=0 -sINVOKE_RUN=0 -sSUPPORT_LONGJMP=0 -sINCOMING_MODULE_JS_API=wasmMemory,instantiateWasm,wasm -sEXPORT_NAME=loadVosklet -sMALLOC=emmalloc -sENVIRONMENT=web,worker -I. -I"$VOSK"/src -L"$KALDI"/src -l:online2/kaldi-online2.a -l:decoder/kaldi-decoder.a -l:ivector/kaldi-ivector.a -l:gmm/kaldi-gmm.a -l:tree/kaldi-tree.a -l:feat/kaldi-feat.a -l:cudamatrix/kaldi-cudamatrix.a -l:lat/kaldi-lat.a -l:lm/kaldi-lm.a -l:rnnlm/kaldi-rnnlm.a -l:hmm/kaldi-hmm.a -l:nnet3/kaldi-nnet3.a -l:transform/kaldi-transform.a -l:matrix/kaldi-matrix.a -l:fstext/kaldi-fstext.a -l:util/kaldi-util.a -l:base/kaldi-base.a -L"$OPENFST"/lib -l:libfst.a -l:libfstngram.a -L"$CLAPACK_WASM" -l:CBLAS/lib/cblas.a -l:CLAPACK-3.2.1/lapack.a -l:CLAPACK-3.2.1/libcblaswr.a -l:f2c_BLAS-3.8.0/blas.a -l:libf2c/libf2c.a -L"$VOSK"/src -l:vosk.a -lembind -flto -msimd128 -matomics -mbulk-memory -mreference-types -mnontrapping-fptoint -mextended-const -msign-ext -mmutable-globals --pre-js Wrapper.js --closure 1 -o ../test.js && em++ Util.cc CommonModel.cc Recognizer.cc Bindings.cc -std=c++23 -O3 -Wall -Wextra -Wpedantic -fno-rtti -DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0 -DMAX_WORKERS="$MAX_THREADS" -sWASMFS -sWASM_BIGINT -sMODULARIZE -sWASM_EXNREF -sTEXTDECODER=2 -sWASM_WORKERS=2 -sEVAL_CTORS=2 -sINITIAL_MEMORY="$INITIAL_MEMORY" -sALLOW_MEMORY_GROWTH -sPOLYFILL=0 -sEXIT_RUNTIME=0 -sINVOKE_RUN=0 -sSUPPORT_LONGJMP=0 -sINCOMING_MODULE_JS_API=wasmMemory,instantiateWasm,wasm -sEXPORT_NAME=loadVosklet -sMALLOC=emmalloc -sENVIRONMENT=web,worker -I. -I"$VOSK"/src -L"$KALDI"/src -l:online2/kaldi-online2.a -l:decoder/kaldi-decoder.a -l:ivector/kaldi-ivector.a -l:gmm/kaldi-gmm.a -l:tree/kaldi-tree.a -l:feat/kaldi-feat.a -l:cudamatrix/kaldi-cudamatrix.a -l:lat/kaldi-lat.a -l:lm/kaldi-lm.a -l:rnnlm/kaldi-rnnlm.a -l:hmm/kaldi-hmm.a -l:nnet3/kaldi-nnet3.a -l:transform/kaldi-transform.a -l:matrix/kaldi-matrix.a -l:fstext/kaldi-fstext.a -l:util/kaldi-util.a -l:base/kaldi-base.a -L"$OPENFST"/lib -l:libfst.a -l:libfstngram.a -L"$CLAPACK_WASM" -l:CBLAS/lib/cblas.a -l:CLAPACK-3.2.1/lapack.a -l:CLAPACK-3.2.1/libcblaswr.a -l:f2c_BLAS-3.8.0/blas.a -l:libf2c/libf2c.a -L"$VOSK"/src -l:vosk.a -lembind -flto -msimd128 -matomics -mbulk-memory -mreference-types -mnontrapping-fptoint -mextended-const -msign-ext -mmutable-globals --pre-js Wrapper.js --closure 1 -o ../test.js &&
tr -d '\n' < ../test.js | tr -s ' ' > /tmp/hehe && mv /tmp/hehe ../test.js tr -d '\n' < ../test.js | tr -s ' ' > /tmp/hehe && mv /tmp/hehe ../test.js
fi fi
cd .. && cd .. &&