727 lines
19 KiB
JavaScript
727 lines
19 KiB
JavaScript
function freeConfig(config, Module) {
|
|
if ('buffer' in config) {
|
|
Module._free(config.buffer);
|
|
}
|
|
|
|
if ('config' in config) {
|
|
freeConfig(config.config, Module)
|
|
}
|
|
|
|
if ('transducer' in config) {
|
|
freeConfig(config.transducer, Module)
|
|
}
|
|
|
|
if ('paraformer' in config) {
|
|
freeConfig(config.paraformer, Module)
|
|
}
|
|
|
|
if ('ctc' in config) {
|
|
freeConfig(config.ctc, Module)
|
|
}
|
|
|
|
if ('feat' in config) {
|
|
freeConfig(config.feat, Module)
|
|
}
|
|
|
|
if ('model' in config) {
|
|
freeConfig(config.model, Module)
|
|
}
|
|
|
|
if ('nemoCtc' in config) {
|
|
freeConfig(config.nemoCtc, Module)
|
|
}
|
|
|
|
if ('whisper' in config) {
|
|
freeConfig(config.whisper, Module)
|
|
}
|
|
|
|
if ('tdnn' in config) {
|
|
freeConfig(config.tdnn, Module)
|
|
}
|
|
|
|
if ('lm' in config) {
|
|
freeConfig(config.lm, Module)
|
|
}
|
|
|
|
Module._free(config.ptr);
|
|
}
|
|
|
|
// The user should free the returned pointers
|
|
function initSherpaOnnxOnlineTransducerModelConfig(config, Module) {
|
|
const encoderLen = Module.lengthBytesUTF8(config.encoder) + 1;
|
|
const decoderLen = Module.lengthBytesUTF8(config.decoder) + 1;
|
|
const joinerLen = Module.lengthBytesUTF8(config.joiner) + 1;
|
|
|
|
const n = encoderLen + decoderLen + joinerLen;
|
|
|
|
const buffer = Module._malloc(n);
|
|
|
|
const len = 3 * 4; // 3 pointers
|
|
const ptr = Module._malloc(len);
|
|
|
|
let offset = 0;
|
|
Module.stringToUTF8(config.encoder, buffer + offset, encoderLen);
|
|
offset += encoderLen;
|
|
|
|
Module.stringToUTF8(config.decoder, buffer + offset, decoderLen);
|
|
offset += decoderLen;
|
|
|
|
Module.stringToUTF8(config.joiner, buffer + offset, joinerLen);
|
|
|
|
offset = 0;
|
|
Module.setValue(ptr, buffer + offset, 'i8*');
|
|
offset += encoderLen;
|
|
|
|
Module.setValue(ptr + 4, buffer + offset, 'i8*');
|
|
offset += decoderLen;
|
|
|
|
Module.setValue(ptr + 8, buffer + offset, 'i8*');
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len,
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxOnlineParaformerModelConfig(config, Module) {
|
|
const encoderLen = Module.lengthBytesUTF8(config.encoder) + 1;
|
|
const decoderLen = Module.lengthBytesUTF8(config.decoder) + 1;
|
|
|
|
const n = encoderLen + decoderLen;
|
|
const buffer = Module._malloc(n);
|
|
|
|
const len = 2 * 4; // 2 pointers
|
|
const ptr = Module._malloc(len);
|
|
|
|
let offset = 0;
|
|
Module.stringToUTF8(config.encoder, buffer + offset, encoderLen);
|
|
offset += encoderLen;
|
|
|
|
Module.stringToUTF8(config.decoder, buffer + offset, decoderLen);
|
|
|
|
offset = 0;
|
|
Module.setValue(ptr, buffer + offset, 'i8*');
|
|
offset += encoderLen;
|
|
|
|
Module.setValue(ptr + 4, buffer + offset, 'i8*');
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len,
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxOnlineZipformer2CtcModelConfig(config, Module) {
|
|
const n = Module.lengthBytesUTF8(config.model) + 1;
|
|
const buffer = Module._malloc(n);
|
|
|
|
const len = 1 * 4; // 1 pointer
|
|
const ptr = Module._malloc(len);
|
|
|
|
Module.stringToUTF8(config.model, buffer, n);
|
|
|
|
Module.setValue(ptr, buffer, 'i8*');
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len,
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxOnlineModelConfig(config, Module) {
|
|
const transducer =
|
|
initSherpaOnnxOnlineTransducerModelConfig(config.transducer, Module);
|
|
const paraformer =
|
|
initSherpaOnnxOnlineParaformerModelConfig(config.paraformer, Module);
|
|
const ctc = initSherpaOnnxOnlineZipformer2CtcModelConfig(
|
|
config.zipformer2Ctc, Module);
|
|
|
|
const len = transducer.len + paraformer.len + ctc.len + 5 * 4;
|
|
const ptr = Module._malloc(len);
|
|
|
|
let offset = 0;
|
|
Module._CopyHeap(transducer.ptr, transducer.len, ptr + offset);
|
|
offset += transducer.len;
|
|
|
|
Module._CopyHeap(paraformer.ptr, paraformer.len, ptr + offset);
|
|
offset += paraformer.len;
|
|
|
|
Module._CopyHeap(ctc.ptr, ctc.len, ptr + offset);
|
|
offset += ctc.len;
|
|
|
|
const tokensLen = Module.lengthBytesUTF8(config.tokens) + 1;
|
|
const providerLen = Module.lengthBytesUTF8(config.provider) + 1;
|
|
const modelTypeLen = Module.lengthBytesUTF8(config.modelType) + 1;
|
|
const bufferLen = tokensLen + providerLen + modelTypeLen;
|
|
const buffer = Module._malloc(bufferLen);
|
|
|
|
offset = 0;
|
|
Module.stringToUTF8(config.tokens, buffer, tokensLen);
|
|
offset += tokensLen;
|
|
|
|
Module.stringToUTF8(config.provider, buffer + offset, providerLen);
|
|
offset += providerLen;
|
|
|
|
Module.stringToUTF8(config.modelType, buffer + offset, modelTypeLen);
|
|
|
|
offset = transducer.len + paraformer.len + ctc.len;
|
|
Module.setValue(ptr + offset, buffer, 'i8*'); // tokens
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.numThreads, 'i32');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, buffer + tokensLen, 'i8*'); // provider
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.debug, 'i32');
|
|
offset += 4;
|
|
|
|
Module.setValue(
|
|
ptr + offset, buffer + tokensLen + providerLen, 'i8*'); // modelType
|
|
offset += 4;
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len, transducer: transducer,
|
|
paraformer: paraformer, ctc: ctc
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxFeatureConfig(config, Module) {
|
|
const len = 2 * 4; // 2 pointers
|
|
const ptr = Module._malloc(len);
|
|
|
|
Module.setValue(ptr, config.sampleRate, 'i32');
|
|
Module.setValue(ptr + 4, config.featureDim, 'i32');
|
|
return {ptr: ptr, len: len};
|
|
}
|
|
|
|
function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
|
|
const feat = initSherpaOnnxFeatureConfig(config.featConfig, Module);
|
|
const model = initSherpaOnnxOnlineModelConfig(config.modelConfig, Module);
|
|
|
|
const len = feat.len + model.len + 8 * 4;
|
|
const ptr = Module._malloc(len);
|
|
|
|
let offset = 0;
|
|
Module._CopyHeap(feat.ptr, feat.len, ptr + offset);
|
|
offset += feat.len;
|
|
|
|
Module._CopyHeap(model.ptr, model.len, ptr + offset);
|
|
offset += model.len;
|
|
|
|
const decodingMethodLen = Module.lengthBytesUTF8(config.decodingMethod) + 1;
|
|
const hotwordsFileLen = Module.lengthBytesUTF8(config.hotwordsFile) + 1;
|
|
const bufferLen = decodingMethodLen + hotwordsFileLen;
|
|
const buffer = Module._malloc(bufferLen);
|
|
|
|
offset = 0;
|
|
Module.stringToUTF8(config.decodingMethod, buffer, decodingMethodLen);
|
|
offset += decodingMethodLen;
|
|
|
|
Module.stringToUTF8(config.hotwordsFile, buffer + offset, hotwordsFileLen);
|
|
|
|
offset = feat.len + model.len;
|
|
Module.setValue(ptr + offset, buffer, 'i8*'); // decoding method
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.maxActivePaths, 'i32');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.enableEndpoint, 'i32');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.rule1MinTrailingSilence, 'float');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.rule2MinTrailingSilence, 'float');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.rule3MinUtteranceLength, 'float');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, buffer + decodingMethodLen, 'i8*');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.hotwordsScore, 'float');
|
|
offset += 4;
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len, feat: feat, model: model
|
|
}
|
|
}
|
|
|
|
|
|
function createOnlineRecognizer(Module, myConfig) {
|
|
const onlineTransducerModelConfig = {
|
|
encoder: '',
|
|
decoder: '',
|
|
joiner: '',
|
|
};
|
|
|
|
const onlineParaformerModelConfig = {
|
|
encoder: '',
|
|
decoder: '',
|
|
};
|
|
|
|
const onlineZipformer2CtcModelConfig = {
|
|
model: '',
|
|
};
|
|
|
|
let type = 0;
|
|
|
|
switch (type) {
|
|
case 0:
|
|
// transducer
|
|
onlineTransducerModelConfig.encoder = './encoder.onnx';
|
|
onlineTransducerModelConfig.decoder = './decoder.onnx';
|
|
onlineTransducerModelConfig.joiner = './joiner.onnx';
|
|
break;
|
|
case 1:
|
|
// paraformer
|
|
onlineParaformerModelConfig.encoder = './encoder.onnx';
|
|
onlineParaformerModelConfig.decoder = './decoder.onnx';
|
|
break;
|
|
case 2:
|
|
// ctc
|
|
onlineZipformer2CtcModelConfig.model = './encoder.onnx';
|
|
break;
|
|
}
|
|
|
|
|
|
const onlineModelConfig = {
|
|
transducer: onlineTransducerModelConfig,
|
|
paraformer: onlineParaformerModelConfig,
|
|
zipformer2Ctc: onlineZipformer2CtcModelConfig,
|
|
tokens: './tokens.txt',
|
|
numThreads: 1,
|
|
provider: 'cpu',
|
|
debug: 1,
|
|
modelType: '',
|
|
};
|
|
|
|
const featureConfig = {
|
|
sampleRate: 16000,
|
|
featureDim: 80,
|
|
};
|
|
|
|
let recognizerConfig = {
|
|
featConfig: featureConfig,
|
|
modelConfig: onlineModelConfig,
|
|
decodingMethod: 'greedy_search',
|
|
maxActivePaths: 4,
|
|
enableEndpoint: 1,
|
|
rule1MinTrailingSilence: 2.4,
|
|
rule2MinTrailingSilence: 1.2,
|
|
rule3MinUtteranceLength: 20,
|
|
hotwordsFile: '',
|
|
hotwordsScore: 1.5,
|
|
};
|
|
if (myConfig) {
|
|
recognizerConfig = myConfig;
|
|
}
|
|
|
|
return new OnlineRecognizer(recognizerConfig, Module);
|
|
}
|
|
|
|
function initSherpaOnnxOfflineTransducerModelConfig(config, Module) {
|
|
const encoderLen = Module.lengthBytesUTF8(config.encoder) + 1;
|
|
const decoderLen = Module.lengthBytesUTF8(config.decoder) + 1;
|
|
const joinerLen = Module.lengthBytesUTF8(config.joiner) + 1;
|
|
|
|
const n = encoderLen + decoderLen + joinerLen;
|
|
|
|
const buffer = Module._malloc(n);
|
|
|
|
const len = 3 * 4; // 3 pointers
|
|
const ptr = Module._malloc(len);
|
|
|
|
let offset = 0;
|
|
Module.stringToUTF8(config.encoder, buffer + offset, encoderLen);
|
|
offset += encoderLen;
|
|
|
|
Module.stringToUTF8(config.decoder, buffer + offset, decoderLen);
|
|
offset += decoderLen;
|
|
|
|
Module.stringToUTF8(config.joiner, buffer + offset, joinerLen);
|
|
|
|
offset = 0;
|
|
Module.setValue(ptr, buffer + offset, 'i8*');
|
|
offset += encoderLen;
|
|
|
|
Module.setValue(ptr + 4, buffer + offset, 'i8*');
|
|
offset += decoderLen;
|
|
|
|
Module.setValue(ptr + 8, buffer + offset, 'i8*');
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len,
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxOfflineParaformerModelConfig(config, Module) {
|
|
const n = Module.lengthBytesUTF8(config.model) + 1;
|
|
|
|
const buffer = Module._malloc(n);
|
|
|
|
const len = 1 * 4; // 1 pointer
|
|
const ptr = Module._malloc(len);
|
|
|
|
Module.stringToUTF8(config.model, buffer, n);
|
|
|
|
Module.setValue(ptr, buffer, 'i8*');
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len,
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxOfflineNemoEncDecCtcModelConfig(config, Module) {
|
|
const n = Module.lengthBytesUTF8(config.model) + 1;
|
|
|
|
const buffer = Module._malloc(n);
|
|
|
|
const len = 1 * 4; // 1 pointer
|
|
const ptr = Module._malloc(len);
|
|
|
|
Module.stringToUTF8(config.model, buffer, n);
|
|
|
|
Module.setValue(ptr, buffer, 'i8*');
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len,
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxOfflineWhisperModelConfig(config, Module) {
|
|
const encoderLen = Module.lengthBytesUTF8(config.encoder) + 1;
|
|
const decoderLen = Module.lengthBytesUTF8(config.decoder) + 1;
|
|
|
|
const n = encoderLen + decoderLen;
|
|
const buffer = Module._malloc(n);
|
|
|
|
const len = 2 * 4; // 2 pointers
|
|
const ptr = Module._malloc(len);
|
|
|
|
let offset = 0;
|
|
Module.stringToUTF8(config.encoder, buffer + offset, encoderLen);
|
|
offset += encoderLen;
|
|
|
|
Module.stringToUTF8(config.decoder, buffer + offset, decoderLen);
|
|
|
|
offset = 0;
|
|
Module.setValue(ptr, buffer + offset, 'i8*');
|
|
offset += encoderLen;
|
|
|
|
Module.setValue(ptr + 4, buffer + offset, 'i8*');
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len,
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxOfflineTdnnModelConfig(config, Module) {
|
|
const n = Module.lengthBytesUTF8(config.model) + 1;
|
|
const buffer = Module._malloc(n);
|
|
|
|
const len = 1 * 4; // 1 pointer
|
|
const ptr = Module._malloc(len);
|
|
|
|
Module.stringToUTF8(config.model, buffer, n);
|
|
|
|
Module.setValue(ptr, buffer, 'i8*');
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len,
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxOfflineLMConfig(config, Module) {
|
|
const n = Module.lengthBytesUTF8(config.model) + 1;
|
|
const buffer = Module._malloc(n);
|
|
|
|
const len = 2 * 4;
|
|
const ptr = Module._malloc(len);
|
|
|
|
Module.stringToUTF8(config.model, buffer, n);
|
|
Module.setValue(ptr, buffer, 'i8*');
|
|
Module.setValue(ptr + 4, config.scale, 'float');
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len,
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxOfflineModelConfig(config, Module) {
|
|
const transducer =
|
|
initSherpaOnnxOfflineTransducerModelConfig(config.transducer, Module);
|
|
const paraformer =
|
|
initSherpaOnnxOfflineParaformerModelConfig(config.paraformer, Module);
|
|
const nemoCtc =
|
|
initSherpaOnnxOfflineNemoEncDecCtcModelConfig(config.nemoCtc, Module);
|
|
const whisper =
|
|
initSherpaOnnxOfflineWhisperModelConfig(config.whisper, Module);
|
|
const tdnn = initSherpaOnnxOfflineTdnnModelConfig(config.tdnn, Module);
|
|
|
|
const len = transducer.len + paraformer.len + nemoCtc.len + whisper.len +
|
|
tdnn.len + 5 * 4;
|
|
const ptr = Module._malloc(len);
|
|
|
|
let offset = 0;
|
|
Module._CopyHeap(transducer.ptr, transducer.len, ptr + offset);
|
|
offset += transducer.len;
|
|
|
|
Module._CopyHeap(paraformer.ptr, paraformer.len, ptr + offset);
|
|
offset += paraformer.len;
|
|
|
|
Module._CopyHeap(nemoCtc.ptr, nemoCtc.len, ptr + offset);
|
|
offset += nemoCtc.len;
|
|
|
|
Module._CopyHeap(whisper.ptr, whisper.len, ptr + offset);
|
|
offset += whisper.len;
|
|
|
|
Module._CopyHeap(tdnn.ptr, tdnn.len, ptr + offset);
|
|
offset += tdnn.len;
|
|
|
|
const tokensLen = Module.lengthBytesUTF8(config.tokens) + 1;
|
|
const providerLen = Module.lengthBytesUTF8(config.provider) + 1;
|
|
const modelTypeLen = Module.lengthBytesUTF8(config.modelType) + 1;
|
|
const bufferLen = tokensLen + providerLen + modelTypeLen;
|
|
const buffer = Module._malloc(bufferLen);
|
|
|
|
offset = 0;
|
|
Module.stringToUTF8(config.tokens, buffer, tokensLen);
|
|
offset += tokensLen;
|
|
|
|
Module.stringToUTF8(config.provider, buffer + offset, providerLen);
|
|
offset += providerLen;
|
|
|
|
Module.stringToUTF8(config.modelType, buffer + offset, modelTypeLen);
|
|
|
|
offset =
|
|
transducer.len + paraformer.len + nemoCtc.len + whisper.len + tdnn.len;
|
|
Module.setValue(ptr + offset, buffer, 'i8*'); // tokens
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.numThreads, 'i32');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.debug, 'i32');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, buffer + tokensLen, 'i8*'); // provider
|
|
offset += 4;
|
|
|
|
Module.setValue(
|
|
ptr + offset, buffer + tokensLen + providerLen, 'i8*'); // modelType
|
|
offset += 4;
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len, transducer: transducer,
|
|
paraformer: paraformer, nemoCtc: nemoCtc, whisper: whisper, tdnn: tdnn
|
|
}
|
|
}
|
|
|
|
function initSherpaOnnxOfflineRecognizerConfig(config, Module) {
|
|
const feat = initSherpaOnnxFeatureConfig(config.featConfig, Module);
|
|
const model = initSherpaOnnxOfflineModelConfig(config.modelConfig, Module);
|
|
const lm = initSherpaOnnxOfflineLMConfig(config.lmConfig, Module);
|
|
|
|
const len = feat.len + model.len + lm.len + 4 * 4;
|
|
const ptr = Module._malloc(len);
|
|
|
|
let offset = 0;
|
|
Module._CopyHeap(feat.ptr, feat.len, ptr + offset);
|
|
offset += feat.len;
|
|
|
|
Module._CopyHeap(model.ptr, model.len, ptr + offset);
|
|
offset += model.len;
|
|
|
|
Module._CopyHeap(lm.ptr, lm.len, ptr + offset);
|
|
offset += lm.len;
|
|
|
|
const decodingMethodLen = Module.lengthBytesUTF8(config.decodingMethod) + 1;
|
|
const hotwordsFileLen = Module.lengthBytesUTF8(config.hotwordsFile) + 1;
|
|
const bufferLen = decodingMethodLen + hotwordsFileLen;
|
|
const buffer = Module._malloc(bufferLen);
|
|
|
|
offset = 0;
|
|
Module.stringToUTF8(config.decodingMethod, buffer, decodingMethodLen);
|
|
offset += decodingMethodLen;
|
|
|
|
Module.stringToUTF8(config.hotwordsFile, buffer + offset, hotwordsFileLen);
|
|
|
|
offset = feat.len + model.len + lm.len;
|
|
|
|
Module.setValue(ptr + offset, buffer, 'i8*'); // decoding method
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.maxActivePaths, 'i32');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, buffer + decodingMethodLen, 'i8*');
|
|
offset += 4;
|
|
|
|
Module.setValue(ptr + offset, config.hotwordsScore, 'float');
|
|
offset += 4;
|
|
|
|
return {
|
|
buffer: buffer, ptr: ptr, len: len, feat: feat, model: model, lm: lm
|
|
}
|
|
}
|
|
|
|
class OfflineStream {
|
|
constructor(handle, Module) {
|
|
this.handle = handle;
|
|
this.Module = Module;
|
|
}
|
|
|
|
free() {
|
|
if (this.handle) {
|
|
this.Module._DestroyOfflineStream(this.handle);
|
|
this.handle = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param sampleRate {Number}
|
|
* @param samples {Float32Array} Containing samples in the range [-1, 1]
|
|
*/
|
|
acceptWaveform(sampleRate, samples) {
|
|
const pointer =
|
|
this.Module._malloc(samples.length * samples.BYTES_PER_ELEMENT);
|
|
this.Module.HEAPF32.set(samples, pointer / samples.BYTES_PER_ELEMENT);
|
|
this.Module._AcceptWaveformOffline(
|
|
this.handle, sampleRate, pointer, samples.length);
|
|
this.Module._free(pointer);
|
|
}
|
|
};
|
|
|
|
class OfflineRecognizer {
|
|
constructor(configObj, Module) {
|
|
this.config = configObj;
|
|
const config = initSherpaOnnxOfflineRecognizerConfig(configObj, Module);
|
|
const handle = Module._CreateOfflineRecognizer(config.ptr);
|
|
freeConfig(config, Module);
|
|
|
|
this.handle = handle;
|
|
this.Module = Module;
|
|
}
|
|
|
|
free() {
|
|
this.Module._DestroyOfflineRecognizer(this.handle);
|
|
this.handle = 0
|
|
}
|
|
|
|
createStream() {
|
|
const handle = this.Module._CreateOfflineStream(this.handle);
|
|
return new OfflineStream(handle, this.Module);
|
|
}
|
|
|
|
decode(stream) {
|
|
this.Module._DecodeOfflineStream(this.handle, stream.handle);
|
|
}
|
|
|
|
getResult(stream) {
|
|
const r = this.Module._GetOfflineStreamResult(stream.handle);
|
|
|
|
const textPtr = this.Module.getValue(r, 'i8*');
|
|
const text = this.Module.UTF8ToString(textPtr);
|
|
|
|
this.Module._DestroyOfflineRecognizerResult(r);
|
|
return text;
|
|
}
|
|
};
|
|
|
|
class OnlineStream {
|
|
constructor(handle, Module) {
|
|
this.handle = handle;
|
|
this.pointer = null; // buffer
|
|
this.n = 0; // buffer size
|
|
this.Module = Module;
|
|
}
|
|
|
|
free() {
|
|
if (this.handle) {
|
|
this.Module._DestroyOnlineStream(this.handle);
|
|
this.handle = null;
|
|
this.Module._free(this.pointer);
|
|
this.pointer = null;
|
|
this.n = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param sampleRate {Number}
|
|
* @param samples {Float32Array} Containing samples in the range [-1, 1]
|
|
*/
|
|
acceptWaveform(sampleRate, samples) {
|
|
if (this.n < samples.length) {
|
|
this.Module._free(this.pointer);
|
|
this.pointer =
|
|
this.Module._malloc(samples.length * samples.BYTES_PER_ELEMENT);
|
|
this.n = samples.length
|
|
}
|
|
|
|
this.Module.HEAPF32.set(samples, this.pointer / samples.BYTES_PER_ELEMENT);
|
|
this.Module._AcceptWaveform(
|
|
this.handle, sampleRate, this.pointer, samples.length);
|
|
}
|
|
|
|
inputFinished() {
|
|
this.Module._InputFinished(this.handle);
|
|
}
|
|
};
|
|
|
|
class OnlineRecognizer {
|
|
constructor(configObj, Module) {
|
|
this.config = configObj;
|
|
const config = initSherpaOnnxOnlineRecognizerConfig(configObj, Module)
|
|
const handle = Module._CreateOnlineRecognizer(config.ptr);
|
|
|
|
freeConfig(config, Module);
|
|
|
|
this.handle = handle;
|
|
this.Module = Module;
|
|
}
|
|
|
|
free() {
|
|
this.Module._DestroyOnlineRecognizer(this.handle);
|
|
this.handle = 0
|
|
}
|
|
|
|
createStream() {
|
|
const handle = this.Module._CreateOnlineStream(this.handle);
|
|
return new OnlineStream(handle, this.Module);
|
|
}
|
|
|
|
isReady(stream) {
|
|
return this.Module._IsOnlineStreamReady(this.handle, stream.handle) == 1;
|
|
}
|
|
|
|
decode(stream) {
|
|
this.Module._DecodeOnlineStream(this.handle, stream.handle);
|
|
}
|
|
|
|
isEndpoint(stream) {
|
|
return this.Module._IsEndpoint(this.handle, stream.handle) == 1;
|
|
}
|
|
|
|
reset(stream) {
|
|
this.Module._Reset(this.handle, stream.handle);
|
|
}
|
|
|
|
getResult(stream) {
|
|
const r = this.Module._GetOnlineStreamResult(this.handle, stream.handle);
|
|
const textPtr = this.Module.getValue(r, 'i8*');
|
|
const text = this.Module.UTF8ToString(textPtr);
|
|
this.Module._DestroyOnlineRecognizerResult(r);
|
|
return text;
|
|
}
|
|
}
|
|
|
|
if (typeof process == 'object' && typeof process.versions == 'object' &&
|
|
typeof process.versions.node == 'string') {
|
|
module.exports = {
|
|
createOnlineRecognizer,
|
|
OfflineRecognizer,
|
|
};
|
|
}
|