Fix licence and restructure, prepare to add AudioWorklet
This commit is contained in:
@@ -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())
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
24
src/pre.js
24
src/pre.js
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user