csukuangfj's picture
update model
020d2d4
function freeConfig(config, Module) {
if ('buffer' in config) {
Module._free(config.buffer);
}
Module._free(config.ptr);
}
// The user should free the returned pointers
function initSherpaNcnnModelConfig(config, Module) {
let encoderParamLen = Module.lengthBytesUTF8(config.encoderParam) + 1;
let decoderParamLen = Module.lengthBytesUTF8(config.decoderParam) + 1;
let joinerParamLen = Module.lengthBytesUTF8(config.joinerParam) + 1;
let encoderBinLen = Module.lengthBytesUTF8(config.encoderBin) + 1;
let decoderBinLen = Module.lengthBytesUTF8(config.decoderBin) + 1;
let joinerBinLen = Module.lengthBytesUTF8(config.joinerBin) + 1;
let tokensLen = Module.lengthBytesUTF8(config.tokens) + 1;
let n = encoderParamLen + decoderParamLen + joinerParamLen;
n += encoderBinLen + decoderBinLen + joinerBinLen;
n += tokensLen;
let buffer = Module._malloc(n);
let ptr = Module._malloc(4 * 9);
let offset = 0;
Module.stringToUTF8(config.encoderParam, buffer + offset, encoderParamLen);
offset += encoderParamLen;
Module.stringToUTF8(config.encoderBin, buffer + offset, encoderBinLen);
offset += encoderBinLen;
Module.stringToUTF8(config.decoderParam, buffer + offset, decoderParamLen);
offset += decoderParamLen;
Module.stringToUTF8(config.decoderBin, buffer + offset, decoderBinLen);
offset += decoderBinLen;
Module.stringToUTF8(config.joinerParam, buffer + offset, joinerParamLen);
offset += joinerParamLen;
Module.stringToUTF8(config.joinerBin, buffer + offset, joinerBinLen);
offset += joinerBinLen;
Module.stringToUTF8(config.tokens, buffer + offset, tokensLen);
offset += tokensLen;
offset = 0;
Module.setValue(ptr, buffer + offset, 'i8*'); // encoderParam
offset += encoderParamLen;
Module.setValue(ptr + 4, buffer + offset, 'i8*'); // encoderBin
offset += encoderBinLen;
Module.setValue(ptr + 8, buffer + offset, 'i8*'); // decoderParam
offset += decoderParamLen;
Module.setValue(ptr + 12, buffer + offset, 'i8*'); // decoderBin
offset += decoderBinLen;
Module.setValue(ptr + 16, buffer + offset, 'i8*'); // joinerParam
offset += joinerParamLen;
Module.setValue(ptr + 20, buffer + offset, 'i8*'); // joinerBin
offset += joinerBinLen;
Module.setValue(ptr + 24, buffer + offset, 'i8*'); // tokens
offset += tokensLen;
Module.setValue(ptr + 28, config.useVulkanCompute, 'i32');
Module.setValue(ptr + 32, config.numThreads, 'i32');
return {
buffer: buffer, ptr: ptr, len: 36,
}
}
function initSherpaNcnnDecoderConfig(config, Module) {
let n = Module.lengthBytesUTF8(config.decodingMethod) + 1;
let buffer = Module._malloc(n);
let ptr = Module._malloc(4 * 2);
Module.stringToUTF8(config.decodingMethod, buffer, n);
Module.setValue(ptr, buffer, 'i8*');
Module.setValue(ptr + 4, config.numActivePaths, 'i32');
return {
buffer: buffer, ptr: ptr, len: 8,
}
}
function initSherpaNcnnFeatureExtractorConfig(config, Module) {
let ptr = Module._malloc(4 * 2);
Module.setValue(ptr, config.samplingRate, 'float');
Module.setValue(ptr + 4, config.featureDim, 'i32');
return {
ptr: ptr, len: 8,
}
}
function initSherpaNcnnRecognizerConfig(config, Module) {
let featConfig =
initSherpaNcnnFeatureExtractorConfig(config.featConfig, Module);
let modelConfig = initSherpaNcnnModelConfig(config.modelConfig, Module);
let decoderConfig = initSherpaNcnnDecoderConfig(config.decoderConfig, Module);
let numBytes =
featConfig.len + modelConfig.len + decoderConfig.len + 4 * 4 + 4 * 2;
let ptr = Module._malloc(numBytes);
let offset = 0;
Module._CopyHeap(featConfig.ptr, featConfig.len, ptr + offset);
offset += featConfig.len;
Module._CopyHeap(modelConfig.ptr, modelConfig.len, ptr + offset)
offset += modelConfig.len;
Module._CopyHeap(decoderConfig.ptr, decoderConfig.len, ptr + offset)
offset += decoderConfig.len;
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.rule3MinUtternceLength, 'float');
offset += 4;
Module.setValue(ptr + offset, 0, 'i32'); // hotwords file
offset += 4;
Module.setValue(ptr + offset, 0.5, 'float'); // hotwords_score
offset += 4;
return {
ptr: ptr, len: numBytes, featConfig: featConfig, modelConfig: modelConfig,
decoderConfig: decoderConfig,
}
}
class Stream {
constructor(handle, Module) {
this.handle = handle;
this.pointer = null;
this.n = 0;
this.Module = Module;
}
free() {
if (this.handle) {
this.Module._DestroyStream(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() {
_InputFinished(this.handle);
}
};
class Recognizer {
constructor(configObj, Module) {
this.config = configObj;
let config = initSherpaNcnnRecognizerConfig(configObj, Module)
let handle = Module._CreateRecognizer(config.ptr);
freeConfig(config.featConfig, Module);
freeConfig(config.modelConfig, Module);
freeConfig(config.decoderConfig, Module);
freeConfig(config, Module);
this.handle = handle;
this.Module = Module;
}
free() {
this.Module._DestroyRecognizer(this.handle);
this.handle = 0
}
createStream() {
let handle = this.Module._CreateStream(this.handle);
return new Stream(handle, this.Module);
}
isReady(stream) {
return this.Module._IsReady(this.handle, stream.handle) == 1;
}
isEndpoint(stream) {
return this.Module._IsEndpoint(this.handle, stream.handle) == 1;
}
decode(stream) {
return this.Module._Decode(this.handle, stream.handle);
}
reset(stream) {
this.Module._Reset(this.handle, stream.handle);
}
getResult(stream) {
let r = this.Module._GetResult(this.handle, stream.handle);
let textPtr = this.Module.getValue(r, 'i8*');
let text = this.Module.UTF8ToString(textPtr);
this.Module._DestroyResult(r);
return text;
}
}
function createRecognizer(Module, myConfig) {
let modelConfig = {
encoderParam: './encoder_jit_trace-pnnx.ncnn.param',
encoderBin: './encoder_jit_trace-pnnx.ncnn.bin',
decoderParam: './decoder_jit_trace-pnnx.ncnn.param',
decoderBin: './decoder_jit_trace-pnnx.ncnn.bin',
joinerParam: './joiner_jit_trace-pnnx.ncnn.param',
joinerBin: './joiner_jit_trace-pnnx.ncnn.bin',
tokens: './tokens.txt',
useVulkanCompute: 0,
numThreads: 1,
};
let decoderConfig = {
decodingMethod: 'greedy_search',
numActivePaths: 4,
};
let featConfig = {
samplingRate: 16000,
featureDim: 80,
};
let configObj = {
featConfig: featConfig,
modelConfig: modelConfig,
decoderConfig: decoderConfig,
enableEndpoint: 1,
rule1MinTrailingSilence: 1.2,
rule2MinTrailingSilence: 2.4,
rule3MinUtternceLength: 20,
};
if (myConfig) {
configObj = myConfig;
}
return new Recognizer(configObj, Module);
}
if (typeof process == 'object' && typeof process.versions == 'object' &&
typeof process.versions.node == 'string') {
module.exports = {
createRecognizer,
};
}