Change base structure to use errors instead

This commit is contained in:
msqr1
2024-01-20 00:41:38 -08:00
parent 91a21271d5
commit 2a426b983c
19 changed files with 147 additions and 198 deletions

View File

@@ -11,20 +11,19 @@ int main() {
}
EMSCRIPTEN_BINDINGS() {
function("setLogLevel", &vosk_set_log_level, allow_raw_pointers());
class_<model>("__model__")
class_<model>("model")
.constructor<std::string, std::string, std::string, int>(allow_raw_pointers());
class_<spkModel>("__spkModel__")
.constructor<std::string, std::string, std::string, const int>(allow_raw_pointers());
class_<spkModel>("spkModel")
.constructor<std::string, std::string, std::string, int>(allow_raw_pointers());
class_<recognizer>("__recognizer__")
class_<recognizer>("recognizer")
.constructor<model*, int, int>(allow_raw_pointers())
.function("start", &recognizer::start, allow_raw_pointers())
.function("stop", &recognizer::stop, allow_raw_pointers())
.function("setWords", &recognizer::setWords, allow_raw_pointers())
.function("setPartialWords", &recognizer::setPartialWords, allow_raw_pointers())
.function("setGrm", &recognizer::setGrm, allow_raw_pointers())
.function("setNLSML", &recognizer::setNLSML, allow_raw_pointers())
.function("setSpkModel", &recognizer::setSpkModel, allow_raw_pointers())
.function("setMaxAlternatives", &recognizer::setMaxAlternatives, allow_raw_pointers());
.function("setMaxAlternatives", &recognizer::setMaxAlternatives, allow_raw_pointers())
.function("acceptWaveForm", &recognizer::acceptWaveForm, allow_raw_pointers());
};

View File

@@ -1,6 +1,6 @@
#include "genericModel.h"
genericModel::genericModel(const std::string &url, const std::string& storepath, const std::string &id, int index) : url(url), id(id), genericObj(index) {
genericModel::genericModel(const std::string &url, const std::string& storepath, const std::string &id) : url(url), id(id) {
fs::current_path("/opfs");
fs::create_directories(storepath);
fs::current_path(storepath);
@@ -21,23 +21,23 @@ bool genericModel::loadModel(const std::string& storepath) {
char filename[] {"/opfs/XXXXXX.tzst"};
close(mkostemps(filename, 5, O_PATH));
if(emscripten_wget(url.c_str(),filename) == 1) {
fireEv("error", "Unable to fetch model");
throwErr("Unable to fetch model");
return false;
}
if(!extractModel(filename)) {
fireEv("error", "Unable to extract model");
throwErr("Unable to extract model");
return false;
}
fs::remove(filename);
if(!checkModel()) {
fireEv("error", "Model URL contains invalid model files");
throwErr("Model URL contains invalid model files");
fs::current_path("/opfs");
fs::remove_all(storepath);
return false;
}
std::ofstream idFile("id");
if(!idFile.is_open()) {
fireEv("error", "Unable to write new id");
throwErr("Unable to write new id");
fs::remove_all(storepath);
return false;
}

View File

@@ -15,12 +15,12 @@
namespace fs = std::filesystem;
struct genericModel : genericObj {
struct genericModel {
const std::string url{};
const std::string id{};
static bool extractModel(char *name);
static bool checkId(const std::string& id);
virtual bool checkModel() = 0;
bool loadModel(const std::string& storepath);
genericModel(const std::string &url, const std::string &storepath, const std::string &id, int index);
genericModel(const std::string &url, const std::string &storepath, const std::string &id);
};

View File

@@ -1,11 +0,0 @@
#include "genericObj.h"
void genericObj::fireEv(const char *type, const char *content) {
EM_ASM({
if($0 === 0) {
__genericObj__.objects[$0].dispatchEvent(new Event(UTF8ToString($1)));
return;
}
__genericObj__.objects[$0].dispatchEvent(new CustomEvent(UTF8ToString($1), {"details" : UTF8ToString($2)}));
},this->index, type, content);
}

View File

@@ -2,11 +2,11 @@
#include <emscripten.h>
#include <emscripten/console.h>
struct genericObj {
const int index{};
genericObj(int index) : index(index) {};
void fireEv(const char *type, const char *content = nullptr);
};
void throwErr(const char* msg) {
EM_ASM({
throw Error(UTF8ToString($0))
},msg);
}

View File

@@ -1,2 +0,0 @@
class __genericObj__ {static objects = []}

View File

@@ -1,13 +1,12 @@
#include "model.h"
model::model(const std::string &url, const std::string& storepath, const std::string& id, int index) : genericModel(url, id, storepath, index) {
model::model(const std::string &url, const std::string& storepath, const std::string& id, int index) : genericModel(url, id, storepath) {
if(!loadModel(storepath)) return;
mdl = vosk_model_new(".");
if(mdl == nullptr) {
fireEv("error", "Unable to initialize model");
throwErr("Unable to initialize model");
return;
}
fireEv("ready");
};
model::~model() {
vosk_model_free(mdl);

View File

@@ -1,12 +0,0 @@
class Model extends EventTarget{
constructor() {
super()
}
init(url, storepath, id) {
this.obj = new BrowserRecognizer.__model__(url, storepath, id, __genericObj__.objects.length);
__genericObj__.objects.push(this)
}
delete() {
this.obj.delete()
}
}

1
src/post.js Normal file
View File

@@ -0,0 +1 @@
window.loadBR = loadBR

62
src/pre.js Normal file
View File

@@ -0,0 +1,62 @@
var objs = []
class recognizer extends EventTarget {
constructor(rec) {
super()
this.obj = rec
objs.push(this)
}
delete() {
this.obj.delete()
}
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)
}
}
Module.deleteAll = () => objs.forEach(obj => obj.delete())
Module.makeModel = async (url, path, id) => {
let mdl
try {
mdl = new Module.model(url, path, id)
objs.push(mdl)
}
catch(e) {
return Promise.reject(e.message)
}
return mdl
}
Module.makeSpkModel = async (url, path, id) => {
let mdl
try {
mdl = new Module.spkModel(url, path, id)
objs.push(mdl)
}
catch(e) {
return Promise.reject(e.message)
}
return mdl
}
Module.makeRecognizer = async (model, sampleRate) => {
let rec
try {
rec = recognizer(new Module.recognizer(model,sampleRate, objs.length))
}
catch(e) {
return Promise.reject(e.message)
}
return rec
}

View File

@@ -1,33 +1,30 @@
#include "./recognizer.h"
void recognizer::start() {
controller.test_and_set(std::memory_order_relaxed);
controller.notify_all();
}
void recognizer::stop() {
controller.clear(std::memory_order_relaxed);
controller.notify_all();
}
recognizer::recognizer(model* mdl, int sampleRate, int index) : genericObj(index) {
mic = alcCaptureOpenDevice("Emscripten OpenAL capture",sampleRate, AL_FORMAT_MONO16, 22480);
if(alcGetError(mic) != 0) {
fireEv("error", "Unable to initialize microphone");
return;
}
rec = vosk_recognizer_new(mdl->mdl,static_cast<float>(sampleRate));
recognizer::recognizer(model* mdl, float sampleRate, int index) : index(index) {
rec = vosk_recognizer_new(mdl->mdl,sampleRate);
if(rec == nullptr) {
fireEv("error", "Unable to construct recognizer");
throwErr("Unable to initialize recognizer");
return;
}
main();
}
void recognizer::fireEv(const char *type, const char *content) {
EM_ASM({
recognizers[$0].dispatchEvent(new CustomEvent(UTF8ToString($1), {"details" : UTF8ToString($2)}));
},this->index, type, content);
}
recognizer::~recognizer() {
done.test_and_set(std::memory_order_relaxed);
done.notify_all();
stop();
vosk_recognizer_free(rec);
alcCaptureCloseDevice(mic);
}
void recognizer::acceptWaveForm() {
void recognizer::acceptWaveForm(float* data, int len) {
switch(vosk_recognizer_accept_waveform_f(rec, data, len)) {
case 0:
fireEv("result", vosk_recognizer_result(rec));
break;
case 1:
fireEv("partialResult", vosk_recognizer_partial_result(rec));
break;
default:
fireEv("_error", "Recognition error, unable to recognize");
}
}
void recognizer::setGrm(const std::string& grm) {
vosk_recognizer_set_grm(rec, grm.c_str());

View File

@@ -16,14 +16,13 @@
#include <archive_entry.h>
namespace fs = std::filesystem;
struct recognizer : genericObj {
struct recognizer {
int index{};
VoskRecognizer* rec{};
ALCdevice* mic{};
void acceptWaveForm();
recognizer(model* model, int sampleRate, int index);
void acceptWaveForm(float* data, int len);
recognizer(model* model, float sampleRate, int index);
~recognizer();
void start();
void stop();
void fireEv(const char* type, const char* content);
void setSpkModel(spkModel* model);
void setGrm(const std::string& grm);
void setWords(bool words);

View File

@@ -1,38 +0,0 @@
class Recognizer extends EventTarget {
constructor() {
super()
}
init(model) {
ctx = new (AudioContext || webkitAudioContext)()
new BrowserRecognizer.__recognizer__(model.obj,ctx.sampleRate,__genericObj__.objects.length)
ctx.close()
__genericObj__.objects.push(this)
}
start() {
this.obj.start()
}
stop() {
this.obj.stop()
}
delete() {
this.obj.delete()
}
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)
}
}

View File

@@ -1,11 +1,11 @@
#include "spkModel.h"
spkModel::spkModel(const std::string &url, const std::string& storepath, const std::string& id, int index) : genericModel(url, storepath, id, index) {
spkModel::spkModel(const std::string &url, const std::string& storepath, const std::string& id) : genericModel(url, storepath, id) {
if(!loadModel(storepath)) return;
mdl = vosk_spk_model_new(".");
if(mdl == nullptr) {
fireEv("error", "Unable to initialize speaker model");
throwErr("Unable to initialize speaker model");
return;
}
fireEv("ready");
};
spkModel::~spkModel() {
vosk_spk_model_free(mdl);

View File

@@ -4,7 +4,7 @@
struct spkModel : genericModel {
bool checkModel();
VoskSpkModel* mdl{};
spkModel(const std::string &url, const std::string& storepath, const std::string& id, const int index);
spkModel(const std::string &url, const std::string& storepath, const std::string& id);
~spkModel();
};

View File

@@ -1,12 +0,0 @@
class SpkModel extends EventTarget{
constructor() {
super()
}
init(url, storepath, id) {
this.obj = new BrowserRecognizer.__spkModel__(url, storepath, id, __genericObj__.objects.length)
__genericObj__.objects.push(this)
}
delete() {
this.obj.delete()
}
}