Fix licence and restructure, prepare to add AudioWorklet

This commit is contained in:
msqr1
2024-01-20 17:37:47 -08:00
parent 6bc5f4061d
commit 6da9a662a1
14 changed files with 94 additions and 104 deletions

View File

@@ -1,7 +1,17 @@
#include "spkModel.h"
#include "model.h"
#include "recognizer.h"
#include <emscripten/bind.h>
using namespace emscripten;
void throwJS(const char* msg, bool err = false) {
EM_ASM({
if($1) {
throw Error(UTF8ToString)
return
}
throw UTF8ToString($0)
},msg, err);
}
int main() {
//vosk_set_log_level(-1);
std::thread t{[](){
@@ -12,13 +22,13 @@ int main() {
EMSCRIPTEN_BINDINGS() {
function("setLogLevel", &vosk_set_log_level, allow_raw_pointers());
class_<model>("model")
.constructor<std::string, std::string, std::string, int>(allow_raw_pointers());
.constructor<std::string, std::string, std::string>(allow_raw_pointers());
class_<spkModel>("spkModel")
.constructor<std::string, std::string, std::string, int>(allow_raw_pointers());
.constructor<std::string, std::string, std::string>(allow_raw_pointers());
class_<recognizer>("recognizer")
.constructor<model*, int, int>(allow_raw_pointers())
.constructor<model*, float, int>(allow_raw_pointers())
.function("setWords", &recognizer::setWords, allow_raw_pointers())
.function("setPartialWords", &recognizer::setPartialWords, allow_raw_pointers())
.function("setGrm", &recognizer::setGrm, allow_raw_pointers())

View File

@@ -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) {
throwErr("Unable to fetch model");
throwJS("Unable to fetch model");
return false;
}
if(!extractModel(filename)) {
throwErr("Unable to extract model");
throwJS("Unable to extract model");
return false;
}
fs::remove(filename);
if(!checkModel()) {
throwErr("Model URL contains invalid model files");
throwJS("Model URL contains invalid model files");
fs::current_path("/opfs");
fs::remove_all(storepath);
return false;
}
std::ofstream idFile("id");
if(!idFile.is_open()) {
throwErr("Unable to write new id");
throwJS("Unable to write new id");
fs::remove_all(storepath);
return false;
}

View File

@@ -1,6 +1,4 @@
#pragma once
#include "genericObj.h"
#include <string>
#include <filesystem>
#include <fstream>
@@ -11,8 +9,8 @@
#include <archive.h>
#include <archive_entry.h>
#include <emscripten/wasmfs.h>
#include <emscripten/bind.h>
#include <emscripten.h>
extern void throwJS(const char* msg, bool err = false);
namespace fs = std::filesystem;
struct genericModel {

View File

@@ -1,12 +0,0 @@
#pragma once
#include <emscripten.h>
#include <emscripten/console.h>
void throwErr(const char* msg) {
EM_ASM({
throw Error(UTF8ToString($0))
},msg);
}

View File

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

View File

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

View File

@@ -5,6 +5,11 @@ class recognizer extends EventTarget {
this.obj = rec
objs.push(this)
}
processAudio(buffer) {
if(buffer.numberOfChannels < 1) throw Error("Buffer has ",buffer.numberOfChannels, " channel")
let data = buffer.getChannelData(0);
if(!(data instanceof Float32Array)) throw Error("Channel data isn't a Float32Array");
}
delete() {
this.obj.delete()
}
@@ -32,31 +37,34 @@ 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)
mdl.delete()
return Promise.reject(e)
}
objs.push(mdl)
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)
mdl.delete()
return Promise.reject(e)
}
objs.push(mdl)
return mdl
}
Module.makeRecognizer = async (model, sampleRate) => {
Module.makeRecognizer = async (model, sampleRate, ctx) => {
let rec
try {
rec = recognizer(new Module.recognizer(model,sampleRate, objs.length))
rec = new Module.recognizer(model,sampleRate, objs.length)
}
catch(e) {
return Promise.reject(e.message)
rec.delete()
return Promise.reject(e)
}
return rec
return new recognizer(rec)
}

View File

@@ -1,19 +1,18 @@
#include "./recognizer.h"
#include "recognizer.h"
recognizer::recognizer(model* mdl, float sampleRate, int index) : index(index) {
rec = vosk_recognizer_new(mdl->mdl,sampleRate);
if(rec == nullptr) {
throwErr("Unable to initialize recognizer");
return;
throwJS("Unable to initialize recognizer");
}
}
recognizer::~recognizer() {
vosk_recognizer_free(rec);
}
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() {
vosk_recognizer_free(rec);
}
void recognizer::acceptWaveForm(float* data, int len) {
switch(vosk_recognizer_accept_waveform_f(rec, data, len)) {
case 0:
@@ -23,7 +22,7 @@ void recognizer::acceptWaveForm(float* data, int len) {
fireEv("partialResult", vosk_recognizer_partial_result(rec));
break;
default:
fireEv("_error", "Recognition error, unable to recognize");
throwJS("acceptWaveForm error (from C++)", true);
}
}
void recognizer::setGrm(const std::string& grm) {

View File

@@ -1,27 +1,26 @@
#pragma once
#include "model.h"
#include "spkModel.h"
#include "genericObj.h"
#include <filesystem>
#include <atomic>
#include <thread>
#include <emscripten/bind.h>
#include <emscripten/wasmfs.h>
#include <emscripten/console.h>
#include <emscripten/webaudio.h>
#include <AL/al.h>
#include <AL/alc.h>
#include <archive.h>
#include <archive_entry.h>
extern void throwJS(const char* msg, bool err = false);
namespace fs = std::filesystem;
struct recognizer {
int index{};
VoskRecognizer* rec{};
void acceptWaveForm(float* data, int len);
recognizer(model* model, float sampleRate, int index);
~recognizer();
void acceptWaveForm(float* data, int len);
void fireEv(const char* type, const char* content);
void setSpkModel(spkModel* model);
void setGrm(const std::string& grm);

View File

@@ -3,8 +3,7 @@ spkModel::spkModel(const std::string &url, const std::string& storepath, const s
if(!loadModel(storepath)) return;
mdl = vosk_spk_model_new(".");
if(mdl == nullptr) {
throwErr("Unable to initialize speaker model");
return;
throwJS("Unable to initialize speaker model");
}
};
spkModel::~spkModel() {