Some bug fixes and change in pattern
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ kaldi
|
||||
libarchive
|
||||
vosk-api
|
||||
zstd
|
||||
test.cc
|
||||
|
||||
File diff suppressed because one or more lines are too long
26
README.md
26
README.md
@@ -1,6 +1,6 @@
|
||||
# Browser-recognizer
|
||||
- A from-microphone speech recognizer built on Vosk that can be run on the browser, inspired by [vosk-browser](https://github.com/ccoreilly/vosk-browser), but built from scratch and no code taken!
|
||||
- Browser-recognizer can run on the main browser thread or worker.
|
||||
- Browser-recognizer can run both in the browser main thread and web workers.
|
||||
## Interface
|
||||
- setLogLevel: set Kaldi's log level (default: -1)
|
||||
- -2: Error
|
||||
@@ -11,11 +11,15 @@
|
||||
- 3: Debug
|
||||
### Model and SpkModel
|
||||
```
|
||||
new Model(url, storepath, id)
|
||||
new SpkModel(url, storepath, id)
|
||||
model = new Model()
|
||||
spkModel = new SpkModel()
|
||||
// Add events listeners
|
||||
model.init(url, storepath, id)
|
||||
spkModel.init(url, storepath, id)
|
||||
```
|
||||
#### Functions
|
||||
- ***constructor*** : Construct a model from an URL, storage path, and an ID.
|
||||
- ***constructor***: Construct the EventTarget part to enable addEventListener
|
||||
- ***init*** : Initialize the internal object with an URL, storage path, and an ID.
|
||||
- If **storepath** contains valid model files and **id** is the same, there will not be a fetch from **url**.
|
||||
- If **storepath** doesn't contain valid model files, or if it contains valid model files but **id** is different, there will be a fetch from **url**, and the model is stored with **id**.
|
||||
- ***delete***: Delete self and free resources
|
||||
@@ -24,10 +28,13 @@ new SpkModel(url, storepath, id)
|
||||
- ***error***: An error occured, check the event's **details** property.
|
||||
### Recognizer
|
||||
```
|
||||
new Recognizer(model)
|
||||
recognizer = new Recognizer()
|
||||
// Add event listeners
|
||||
recognizer.init(model)
|
||||
```
|
||||
#### Functions
|
||||
- ***constructor***: Construct a recognizer from a model object.
|
||||
- ***constructor***: Construct the EventTarget part to enable addEventListener
|
||||
- ***init***: Construct the real internal object from a model
|
||||
- ***start***: Start recognizing
|
||||
- ***stop***: Stop recognizing
|
||||
- ***setWords***: Return words' information in a result event (default: false)
|
||||
@@ -49,8 +56,7 @@ new Recognizer(model)
|
||||
__genericObj__.objects.forEach(obj => obj.delete())
|
||||
```
|
||||
at the end of your program to automatically do that. We have to do this because Emscripten doesn't call destructors. See [here](https://emscripten.org/docs/getting_started/FAQ.html#what-does-exiting-the-runtime-mean-why-don-t-atexit-s-run).
|
||||
- After calling the constructor, event listener s can be added right away while things are still loading. Calling an interface function at this time though, will block until loading is finished.
|
||||
- To be safe, always handle the API through emitted events.
|
||||
- To be safe, always handle the API through events by adding all event listener before calling init().
|
||||
### Guarantees
|
||||
- If an error occurs (error event is fired), no changes was made, and no other dependent events will fire. For example, if an error occur while loading the model, the "ready" event won't fire in order to prevent executing code on a nonexistent model.
|
||||
### Limitations compared to vosk-browser:
|
||||
@@ -69,5 +75,9 @@ new Recognizer(model)
|
||||
## Usage
|
||||
```
|
||||
<!--Load this from a script tag-->
|
||||
<script src="BrowserRecognizer.js"></script>
|
||||
<!-->
|
||||
<script>
|
||||
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
using namespace emscripten;
|
||||
EMSCRIPTEN_BINDINGS() {
|
||||
function("setLogLevel", &vosk_set_log_level, allow_raw_pointers());
|
||||
class_<model, base<genericModel>>("__model__")
|
||||
class_<model>("__model__")
|
||||
.constructor<std::string, std::string, std::string, int>(allow_raw_pointers());
|
||||
|
||||
class_<spkModel, base<genericModel>>("__spkModel__")
|
||||
class_<spkModel>("__spkModel__")
|
||||
.constructor<std::string, std::string, std::string, const int>(allow_raw_pointers());
|
||||
|
||||
class_<recognizer, base<genericObj>>("__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())
|
||||
|
||||
@@ -34,12 +34,15 @@ bool genericModel::loadModel() {
|
||||
fireEv("error", "Unable to fetch model");
|
||||
return false;
|
||||
}
|
||||
if(!extractModel(".")) {
|
||||
if(!extractModel()) {
|
||||
fireEv("error", "Unable to extract model");
|
||||
return false;
|
||||
}
|
||||
fs::remove("opfs/model.tzst");
|
||||
if(!checkModel()) {
|
||||
fireEv("error", "Model URL contains invalid model files");
|
||||
fs::remove_all(".");
|
||||
return false;
|
||||
}
|
||||
std::ofstream idFile("id");
|
||||
if(!idFile.is_open()) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
|
||||
#include <vosk_api.h>
|
||||
#include <archive.h>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
class Model extends EventTarget{
|
||||
constructor(url, storepath, id) {
|
||||
constructor() {
|
||||
super()
|
||||
this.obj = (async () => {
|
||||
return new Module.__model__(url, storepath, id, __genericObj__.objects.length)
|
||||
})()
|
||||
}
|
||||
init(url, storepath, id) {
|
||||
this.obj = new Module.__model__(url, storepath, id, __genericObj__.objects.length);
|
||||
__genericObj__.objects.push(this)
|
||||
}
|
||||
delete() {
|
||||
|
||||
@@ -1,57 +1,39 @@
|
||||
class Recognizer extends EventTarget {
|
||||
constructor(model) {
|
||||
constructor() {
|
||||
super()
|
||||
}
|
||||
init(model) {
|
||||
ctx = new (AudioContext || webkitAudioContext)()
|
||||
this.obj = (async () => {
|
||||
new Module.__recognizer__(model.obj,ctx.sampleRate,__genericObj__.objects.length)
|
||||
})()
|
||||
__genericObj__.objects.push(this)
|
||||
new Module.__recognizer__(model.obj,ctx.sampleRate,__genericObj__.objects.length)
|
||||
ctx.close()
|
||||
return this;
|
||||
__genericObj__.objects.push(this)
|
||||
}
|
||||
start() {
|
||||
this.obj.then(() => {
|
||||
this.obj.start()
|
||||
})
|
||||
}
|
||||
stop() {
|
||||
this.obj.then(() => {
|
||||
this.obj.stop()
|
||||
})
|
||||
}
|
||||
delete() {
|
||||
this.obj.then(() => {
|
||||
this.obj.deinit()
|
||||
this.obj.delete()
|
||||
})
|
||||
}
|
||||
setWords(words) {
|
||||
this.obj.then(() => {
|
||||
this.obj.setWords(words)
|
||||
})
|
||||
}
|
||||
setPartialWords(partialWords) {
|
||||
this.obj.then(() => {
|
||||
this.obj.setPartialWords(partialWords)
|
||||
})
|
||||
}
|
||||
setGrm(grm) {
|
||||
this.obj.then(() => {
|
||||
this.obj.setGrm(grm)
|
||||
})
|
||||
}
|
||||
setSpkModel(model) {
|
||||
this.obj.then(() => {
|
||||
this.obj.setSpkModel(model.obj)
|
||||
})
|
||||
}
|
||||
setNLSML(nlsml) {
|
||||
this.obj.then(() => {
|
||||
this.obj.setNLSML(nlsml)
|
||||
})
|
||||
}
|
||||
setMaxAlternatives(alts) {
|
||||
this.obj.then(() => {
|
||||
this.obj.setMaxAlternatives(alts)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,12 @@
|
||||
class SpkModel extends EventTarget{
|
||||
constructor(url, storepath, id) {
|
||||
constructor() {
|
||||
super()
|
||||
this.obj = (async () => {
|
||||
return new Module.__spkModel__(url, storepath, id, __genericObj__.objects.length)
|
||||
})()
|
||||
}
|
||||
init(url, storepath, id) {
|
||||
this.obj = new Module.__spkModel__(url, storepath, id, __genericObj__.objects.length)
|
||||
__genericObj__.objects.push(this)
|
||||
}
|
||||
delete() {
|
||||
this.obj.then(() => {
|
||||
this.obj.delete()
|
||||
})
|
||||
this.obj.delete()
|
||||
}
|
||||
}
|
||||
19
test.cc
19
test.cc
@@ -1,19 +0,0 @@
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/console.h>
|
||||
#include <emscripten/bind.h>
|
||||
using namespace emscripten;
|
||||
struct A {
|
||||
void doit() {
|
||||
char bro[] {"Bro"};
|
||||
MAIN_THREAD_EM_ASM({
|
||||
console.log(UTF8ToString($0));
|
||||
},bro);
|
||||
}
|
||||
~A() {
|
||||
emscripten_console_log("Destructor called");
|
||||
}
|
||||
};
|
||||
EMSCRIPTEN_BINDINGS() {
|
||||
class_<A>("A")
|
||||
.smart_ptr_constructor<
|
||||
}
|
||||
Reference in New Issue
Block a user