Version 1.0.0
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
#include "genericModel.h"
|
||||
|
||||
genericModel::genericModel(int index, bool normalMdl, std::string storepath, std::string id) : index{index}, normalMdl{normalMdl}, storepath{std::move(storepath)}, id{std::move(id)}, entry{archive_entry_new()} {
|
||||
blocker.acquire();
|
||||
}
|
||||
genericModel::genericModel(int index, bool normalMdl, std::string storepath, std::string id) : index{index}, normalMdl{normalMdl}, storepath{std::move(storepath)}, id{std::move(id)}, entry{archive_entry_new()} {}
|
||||
void genericModel::extractAndLoad(int tarStart, int tarSize) {
|
||||
static fs::path path{};
|
||||
static int fd{};
|
||||
@@ -50,8 +48,7 @@ void genericModel::extractAndLoad(int tarStart, int tarSize) {
|
||||
};
|
||||
std::thread t{[this](){
|
||||
func();
|
||||
blocker.acquire();
|
||||
blocker.release();
|
||||
blocker.wait(false, std::memory_order_relaxed);
|
||||
func();
|
||||
}};
|
||||
t.detach();
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
#pragma once
|
||||
#include "link.h"
|
||||
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include <variant>
|
||||
#include <thread>
|
||||
#include <semaphore>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <emscripten/console.h>
|
||||
#include <vosk_api.h>
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
extern void free(void*);
|
||||
struct genericModel {
|
||||
bool normalMdl;
|
||||
bool resourceUsed{};
|
||||
std::atomic_bool blocker{};
|
||||
int index;
|
||||
std::string storepath;
|
||||
std::string id;
|
||||
std::variant<VoskModel*, VoskSpkModel*> mdl;
|
||||
std::binary_semaphore blocker{1};
|
||||
std::function<void()> func;
|
||||
archive_entry* entry;
|
||||
void extractAndLoad(int tarStart, int tarSize);
|
||||
|
||||
21
src/pre.js
21
src/pre.js
@@ -1,8 +1,20 @@
|
||||
let objs = []
|
||||
let processorURL = URL.createObjectURL(new Blob(['(', (() => {
|
||||
registerProcessor("VoskletTransferer", class extends AudioWorkletProcessor {
|
||||
constructor(opts) {
|
||||
super()
|
||||
this.count = 0
|
||||
this.maxCount = opts.processorOptions.maxCount
|
||||
this.buffer = new Float32Array(this.maxCount * 128)
|
||||
}
|
||||
process(inputs) {
|
||||
this.port.postMessage(inputs[0][0].buffer, [inputs[0][0].buffer])
|
||||
this.buffer.set(inputs[0][0], this.count * 128)
|
||||
this.count++
|
||||
if(this.count >= this.maxCount) {
|
||||
this.count = 0
|
||||
this.port.postMessage(this.buffer, [this.buffer.buffer])
|
||||
this.buffer = new Float32Array(this.maxCount * 128)
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
@@ -176,13 +188,14 @@ Module.cleanUp = () => {
|
||||
URL.revokeObjectURL(pthreadURL)
|
||||
URL.revokeObjectURL(processorURL)
|
||||
}
|
||||
Module.createTransferer = async (ctx) => {
|
||||
Module.createTransferer = async (ctx, bufferSize) => {
|
||||
await ctx.audioWorklet.addModule(processorURL)
|
||||
return new AudioWorkletNode(ctx, "VoskletTransferer", {
|
||||
channelCountMode : "explicit",
|
||||
numberOfInputs : 1,
|
||||
numberOfOutputs : 0,
|
||||
channelCount : 1
|
||||
numberOfOutputs : 1,
|
||||
channelCount : 1,
|
||||
processorOptions : { maxCount: bufferSize / 128 }
|
||||
})
|
||||
}
|
||||
Module.locateFile = (path, scriptDir) => {
|
||||
|
||||
@@ -21,8 +21,8 @@ void recognizer::finishConstruction(genericModel* model, genericModel* spkModel)
|
||||
auto main {[this](){
|
||||
fireEv(index, "0");
|
||||
while(!done) {
|
||||
blocker.acquire();
|
||||
blocker.release();
|
||||
blocker.wait(done, std::memory_order_relaxed);
|
||||
blocker = false;
|
||||
while(!dataQ.empty()) {
|
||||
switch(vosk_recognizer_accept_waveform_f(rec, dataQ.front().data, dataQ.front().len)) {
|
||||
case 0:
|
||||
@@ -39,13 +39,15 @@ void recognizer::finishConstruction(genericModel* model, genericModel* spkModel)
|
||||
if(!model->resourceUsed) {
|
||||
model->resourceUsed = true;
|
||||
model->func = main;
|
||||
model->blocker.release();
|
||||
model->blocker = true;
|
||||
model->blocker.notify_one();
|
||||
return;
|
||||
}
|
||||
if(spkModel != nullptr && !spkModel->resourceUsed) {
|
||||
spkModel->resourceUsed = true;
|
||||
spkModel->func = main;
|
||||
spkModel->blocker.release();
|
||||
spkModel->blocker = true;
|
||||
model->blocker.notify_one();
|
||||
return;
|
||||
}
|
||||
std::thread t{main};
|
||||
@@ -53,8 +55,8 @@ void recognizer::finishConstruction(genericModel* model, genericModel* spkModel)
|
||||
}
|
||||
void recognizer::pushData(int start, int len) {
|
||||
dataQ.emplace(start, len);
|
||||
blocker.release();
|
||||
blocker.acquire();
|
||||
blocker = true;
|
||||
blocker.notify_one();
|
||||
}
|
||||
void recognizer::reset() {
|
||||
vosk_recognizer_reset(rec);
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
#pragma once
|
||||
#include "genericModel.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include <emscripten/console.h>
|
||||
|
||||
struct audioData {
|
||||
float* data;
|
||||
int len;
|
||||
audioData(int start, int len) : data{reinterpret_cast<float*>(start)}, len{len} {}
|
||||
};
|
||||
struct recognizer {
|
||||
std::atomic_bool done;
|
||||
std::atomic_bool done{};
|
||||
std::atomic_bool blocker{};
|
||||
int index;
|
||||
std::binary_semaphore blocker{1};
|
||||
std::queue<audioData> dataQ{};
|
||||
VoskRecognizer* rec;
|
||||
std::queue<audioData> dataQ{};
|
||||
recognizer(int index, float sampleRate, genericModel* model);
|
||||
recognizer(int index, float sampleRate, genericModel* model, genericModel* spkModel);
|
||||
recognizer(int index, float sampleRate, genericModel* model, const std::string& grm, int dummy);
|
||||
|
||||
Reference in New Issue
Block a user