Use fireEv

This commit is contained in:
msqr1
2024-02-07 10:58:41 -08:00
parent 76c5dbb130
commit bf65aebe69
2 changed files with 78 additions and 107 deletions

View File

@@ -8,72 +8,13 @@ Module.cleanUp = () => {
objs.forEach(obj => obj.delete()) objs.forEach(obj => obj.delete())
Module.revokeURLs() Module.revokeURLs()
} }
class Recognizer extends EventTarget { class genericModel extends EventTarget {
constructor() { constructor() {
super() super()
objs.push(this) objs.push(this)
} }
async getNode(ctx, channelIndex = 0) { static async _init(url, storepath, id, normalMdl) {
if(typeof this.node === "undefined") { let mdl = new genericModel()
let msgChannel = new MessageChannel()
await ctx.audioWorklet.addModule(processorUrl)
this.node = new AudioWorkletNode(ctx, 'BRProcessor', { channelCountMode: "max", numberOfInputs: 1, numberOfOutputs: 1 })
this.node.port.postMessage({cmd : "init", ptr: this.ptr, channel: channelIndex}, [msgChannel.port1])
msgChannel.port1.onmessage = (ev) => {
this.obj.acceptWaveForm()
}
}
return this.node
}
recognize(buf, channelIndex = 0) {
Module.HEAPF32.set(buf.getChannelData(channelIndex).subarray(0, 512), this.ptr);
this.obj.acceptWaveForm()
}
delete() {
this.obj.delete()
if(typeof this.node !== "undefined") {
this.node.port.postMessage({cmd : "deinit"})
}
}
setWords(words) {
this.obj.setWords(words)
}
setPartialWords(partialWords) {
this.obj.setPartialWords(partialWords)
}
setGrm(grm) {
this.obj.setGrm(grm)
}
setSpkModel(model) {
this.obj.setSpkModel(model.obj)
}
setNLSML(nlsml) {
this.obj.setNLSML(nlsml)
}
setMaxAlternatives(alts) {
this.obj.setMaxAlternatives(alts)
}
}
class Model extends EventTarget {
constructor(d) {
super()
objs.push(this)
}
delete() {
this.obj.delete()
}
}
class SpkModel extends EventTarget {
constructor() {
super()
objs.push(this)
}
delete() {
this.obj.delete()
}
}
Module.makeModel = async (url, storepath, id) => {
let mdl = new Model()
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
mdl.addEventListener("_continue", (ev) => { mdl.addEventListener("_continue", (ev) => {
if(ev.detail === ".") { if(ev.detail === ".") {
@@ -82,7 +23,12 @@ Module.makeModel = async (url, storepath, id) => {
mdl.delete() mdl.delete()
return reject(ev.detail) return reject(ev.detail)
}, {once : true}) }, {once : true})
if(normalMdl) {
mdl.obj = new Module.model(storepath, id, objs.length) mdl.obj = new Module.model(storepath, id, objs.length)
}
else {
mdl.obj = new Module.spkModel(storepath, id, objs.length)
}
if(mdl.obj.checkModel()) { if(mdl.obj.checkModel()) {
mdl.obj.load(true) mdl.obj.load(true)
return; return;
@@ -104,39 +50,22 @@ Module.makeModel = async (url, storepath, id) => {
})() })()
}) })
} }
delete() {
this.obj.delete()
}
}
Module.makeModel = async (url, storepath, id) => {
return genericModel._init(url, storepath, id,true)
}
Module.makeSpkModel = async (url, storepath, id) => { Module.makeSpkModel = async (url, storepath, id) => {
let mdl = new SpkModel() return genericModel._init(url, storepath, id, false)
return new Promise((resolve, reject) => {
mdl.addEventListener("_continue", (ev) => {
if(ev.detail === ".") {
return resolve(mdl)
} }
mdl.delete() class Recognizer extends EventTarget {
reject(ev.detail) constructor() {
}, {once : true}) super()
mdl.obj = new Module.model(storepath, id, objs.length) objs.push(this)
if(mdl.obj.checkModel()) {
mdl.obj.load(true)
return
} }
(async () => { static async _init(model, sampleRate) {
let res = await fetch(url)
if(!res.ok) {
return reject("Unable to download model")
}
let wStream = await (await (await navigator.storage.getDirectory()).getFileHandle("m0dEl.tar", {create : true})).createWritable()
let tarReader = res.body.pipeThrough(dStream).getReader()
while(true) {
let readRes = await tarReader.read()
if(!readRes.done) await wStream.write(readRes.value)
else break
}
await wStream.close()
mdl.obj.afterFetch()
})()
})
}
Module.makeRecognizer = (model, sampleRate) => {
let rec = new Recognizer() let rec = new Recognizer()
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
rec.addEventListener("_continue", (ev) => { rec.addEventListener("_continue", (ev) => {
@@ -151,20 +80,62 @@ Module.makeRecognizer = (model, sampleRate) => {
rec.ptr = Module._malloc(512) rec.ptr = Module._malloc(512)
}) })
} }
async getNode(ctx, channelIndex = 0) {
if(typeof this.node === "undefined") {
let msgChannel = new MessageChannel()
await ctx.audioWorklet.addModule(processorUrl)
this.node = new AudioWorkletNode(ctx, 'BRProcessor', { channelCountMode: "max", numberOfInputs: 1, numberOfOutputs: 1, processorOptions: { ptr: this.ptr, channel: channelIndex, recognizerPort: msgChannel.port1 } })
msgChannel.port1.onmessage = (ev) => {
this.obj.acceptWaveForm()
}
}
return this.node
}
recognize(buf, channelIndex = 0) {
Module.HEAPF32.set(buf.getChannelData(channelIndex).subarray(0, 512), this.ptr);
this.obj.acceptWaveForm()
}
delete() {
this.obj.delete()
if(typeof this.node !== "undefined") {
this.node.port.postMessage(".")
}
}
setWords(words) {
this.obj.setWords(words)
}
setPartialWords(partialWords) {
this.obj.setPartialWords(partialWords)
}
setGrm(grm) {
this.obj.setGrm(grm)
}
setSpkModel(spkModel) {
this.obj.setSpkModel(spkModel.obj)
}
setNLSML(nlsml) {
this.obj.setNLSML(nlsml)
}
setMaxAlternatives(alts) {
this.obj.setMaxAlternatives(alts)
}
}
Module.makeRecognizer = (model, sampleRate) => {
return Recognizer._init(model.obj, sampleRate)
}
let processorUrl = URL.createObjectURL(new Blob(['(', let processorUrl = URL.createObjectURL(new Blob(['(',
(() => { (() => {
registerProcessor("BRProcessor", class extends AudioWorkletProcessor { registerProcessor("BRProcessor", class extends AudioWorkletProcessor {
constructor(options) { constructor(options) {
super(options)
this.done = false this.done = false
this.port.onmessage = (ev) => { this.port.onmessage = (ev) => this.done = true
if(ev.cmd === "deinit") this.done = false
}
this.ptr = options.processorOptions.ptr this.ptr = options.processorOptions.ptr
this.recognizerPort = options.processorOptions.recognizerPort
this.channelIndex = options.processorOptions.channelIndex
} }
process(inputs, outputs, params) { process(inputs, outputs, params) {
if(this.done) return false; if(this.done) return false;
this.wasmMem.set(inputs[0].getChannelData(this.channel)); this.wasmMem.set(inputs[0].getChannelData(this.channelIndex));
this.recognizerPort.postMessage(".") this.recognizerPort.postMessage(".")
outputs = inputs outputs = inputs
return true return true
@@ -172,6 +143,7 @@ let processorUrl = URL.createObjectURL(new Blob(['(',
}) })
}).toString() }).toString()
, ')()'], {type : "text/javascript"})) , ')()'], {type : "text/javascript"}))
// Taken from the worker.js file // Taken from the worker.js file
let pthreadUrl = URL.createObjectURL(new Blob(['(', let pthreadUrl = URL.createObjectURL(new Blob(['(',
(() => { (() => {
@@ -194,7 +166,6 @@ let pthreadUrl = URL.createObjectURL(new Blob(['(',
function assert(condition, text) { function assert(condition, text) {
if (!condition) abort('Assertion failed: ' + text); if (!condition) abort('Assertion failed: ' + text);
} }
function threadPrintErr() { function threadPrintErr() {
var text = Array.prototype.slice.call(arguments).join(' '); var text = Array.prototype.slice.call(arguments).join(' ');
console.error(text); console.error(text);

View File

@@ -2,7 +2,7 @@
spkModel::spkModel(const std::string& storepath, const std::string& id, int index) : genericModel(storepath, id, index) { spkModel::spkModel(const std::string& storepath, const std::string& id, int index) : genericModel(storepath, id, index) {
mdl = vosk_spk_model_new("."); mdl = vosk_spk_model_new(".");
if(mdl == nullptr) { if(mdl == nullptr) {
throwJS("Unable to initialize speaker model"); fireEv("_continue", "Unable to initialize speaker model", index);
} }
} }
spkModel::~spkModel() { spkModel::~spkModel() {