Change base structure to use errors instead
This commit is contained in:
@@ -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());
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
class __genericObj__ {static objects = []}
|
||||
|
||||
@@ -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);
|
||||
|
||||
12
src/model.js
12
src/model.js
@@ -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
1
src/post.js
Normal file
@@ -0,0 +1 @@
|
||||
window.loadBR = loadBR
|
||||
62
src/pre.js
Normal file
62
src/pre.js
Normal 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
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user