Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/scripts/test-nodejs-npm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ git status
ls -lh
ls -lh node_modules

curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2
tar xvf sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2
rm sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2

node ./test-offline-omnilingual-asr-ctc.js

rm -rf sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12
Comment on lines +12 to +18

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The script repeats a long model filename and directory name, which makes it harder to read and maintain. Using a variable for these repeated strings would make the script cleaner and less error-prone. Additionally, the v flag in tar xvf is verbose for CI logs; xf is generally sufficient.

Suggested change
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2
tar xvf sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2
rm sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2
node ./test-offline-omnilingual-asr-ctc.js
rm -rf sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12
MODEL_NAME="sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12"
curl -SL -O "https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/${MODEL_NAME}.tar.bz2"
tar xf "${MODEL_NAME}.tar.bz2"
rm "${MODEL_NAME}.tar.bz2"
node ./test-offline-omnilingual-asr-ctc.js
rm -rf "${MODEL_NAME}"


curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-wenetspeech-yue-u2pp-conformer-ctc-zh-en-cantonese-int8-2025-09-10.tar.bz2
tar xvf sherpa-onnx-wenetspeech-yue-u2pp-conformer-ctc-zh-en-cantonese-int8-2025-09-10.tar.bz2
rm sherpa-onnx-wenetspeech-yue-u2pp-conformer-ctc-zh-en-cantonese-int8-2025-09-10.tar.bz2
Expand Down
18 changes: 17 additions & 1 deletion nodejs-examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,26 @@ rm sherpa-onnx-zipformer-ctc-zh-int8-2025-07-03.tar.bz2
node ./test-offline-zipformer-ctc.js
```

## ./test-offline-omnilingual-asr-ctc.js

[./test-offline-omnilingual-asr-ctc.js](./test-offline-omnilingual-asr-ctc.js) demonstrates
how to decode a file with a Omnilingual ASR CTC model. In the code we use

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is a minor grammatical error. It should be "an Omnilingual" instead of "a Omnilingual".

Suggested change
how to decode a file with a Omnilingual ASR CTC model. In the code we use
how to decode a file with an Omnilingual ASR CTC model. In the code we use

[sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2](https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2).

You can use the following command to run it:

```bash
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2
tar xvf sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2
rm sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2

node ./test-offline-omnilingual-asr-ctc.js
Comment on lines +215 to +219

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The example commands repeat a very long filename, which can be hard to read and is prone to typos. Using a shell variable would make the example clearer and easier for users to adapt. Also, tar xvf is verbose; xf is sufficient.

Suggested change
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2
tar xvf sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2
rm sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2
node ./test-offline-omnilingual-asr-ctc.js
MODEL_NAME="sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12"
wget "https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/${MODEL_NAME}.tar.bz2"
tar xf "${MODEL_NAME}.tar.bz2"
rm "${MODEL_NAME}.tar.bz2"
node ./test-offline-omnilingual-asr-ctc.js

```

## ./test-offline-wenet-ctc.js

[./test-offline-wenet-ctc.js](./test-offline-wenet-ctc.js) demonstrates
how to decode a file with a Wenet CTC model. In the code we use
how to decode a file with a WeNet CTC model. In the code we use
[sherpa-onnx-wenetspeech-yue-u2pp-conformer-ctc-zh-en-cantonese-int8-2025-09-10.tar.bz2](https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-wenetspeech-yue-u2pp-conformer-ctc-zh-en-cantonese-int8-2025-09-10.tar.bz2).

You can use the following command to run it:
Expand Down
37 changes: 37 additions & 0 deletions nodejs-examples/test-offline-omnilingual-asr-ctc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) 2025 Xiaomi Corporation (authors: Fangjun Kuang)
//
const fs = require('fs');
const {Readable} = require('stream');
const wav = require('wav');
Comment on lines +3 to +5

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The modules fs, stream (Readable), and wav are imported but are not used in this file. These unused imports should be removed to keep the code clean.


const sherpa_onnx = require('sherpa-onnx');

function createOfflineRecognizer() {
let config = {
modelConfig: {
omnilingual: {
model:
'./sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12/model.int8.onnx',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The directory path './sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12' is hardcoded here and in other places in the file (lines 17 and 28). To improve maintainability, consider defining this path as a constant at the top of the file and reusing it. For example: const modelDir = './sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12';

},
tokens:
'./sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12/tokens.txt',
}
};

return sherpa_onnx.createOfflineRecognizer(config);
}

const recognizer = createOfflineRecognizer();
const stream = recognizer.createStream();

const waveFilename =
'./sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12/test_wavs/en.wav';
const wave = sherpa_onnx.readWave(waveFilename);
stream.acceptWaveform(wave.sampleRate, wave.samples);

recognizer.decode(stream);
const text = recognizer.getResult(stream).text;
console.log(text);

stream.free();
recognizer.free();
38 changes: 36 additions & 2 deletions wasm/asr/sherpa-onnx-asr.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ function freeConfig(config, Module) {
freeConfig(config.wenetCtc, Module)
}

if ('omnilingual' in config) {
freeConfig(config.omnilingual, Module)
}

if ('moonshine' in config) {
freeConfig(config.moonshine, Module)
}
Expand Down Expand Up @@ -755,6 +759,23 @@ function initSherpaOnnxOfflineWenetCtcModelConfig(config, Module) {
}
}

function initSherpaOnnxOfflineOmnilingualAsrCtcModelConfig(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;
Expand Down Expand Up @@ -1025,6 +1046,12 @@ function initSherpaOnnxOfflineModelConfig(config, Module) {
};
}

if (!('omnilingual' in config)) {
config.omnilingual = {
model: '',
};
}

if (!('whisper' in config)) {
config.whisper = {
encoder: '',
Expand Down Expand Up @@ -1109,9 +1136,13 @@ function initSherpaOnnxOfflineModelConfig(config, Module) {
const wenetCtc =
initSherpaOnnxOfflineWenetCtcModelConfig(config.wenetCtc, Module);

const omnilingual = initSherpaOnnxOfflineOmnilingualAsrCtcModelConfig(
config.omnilingual, Module);

const len = transducer.len + paraformer.len + nemoCtc.len + whisper.len +
tdnn.len + 8 * 4 + senseVoice.len + moonshine.len + fireRedAsr.len +
dolphin.len + zipformerCtc.len + canary.len + wenetCtc.len;
dolphin.len + zipformerCtc.len + canary.len + wenetCtc.len +
omnilingual.len;

const ptr = Module._malloc(len);

Expand Down Expand Up @@ -1222,12 +1253,15 @@ function initSherpaOnnxOfflineModelConfig(config, Module) {
Module._CopyHeap(wenetCtc.ptr, wenetCtc.len, ptr + offset);
offset += wenetCtc.len;

Module._CopyHeap(omnilingual.ptr, omnilingual.len, ptr + offset);
offset += omnilingual.len;

return {
buffer: buffer, ptr: ptr, len: len, transducer: transducer,
paraformer: paraformer, nemoCtc: nemoCtc, whisper: whisper, tdnn: tdnn,
senseVoice: senseVoice, moonshine: moonshine, fireRedAsr: fireRedAsr,
dolphin: dolphin, zipformerCtc: zipformerCtc, canary: canary,
wenetCtc: wenetCtc,
wenetCtc: wenetCtc, omnilingual: omnilingual
}
}

Expand Down
8 changes: 7 additions & 1 deletion wasm/nodejs/sherpa-onnx-wasm-nodejs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ static_assert(sizeof(SherpaOnnxOfflineParaformerModelConfig) == 4, "");

static_assert(sizeof(SherpaOnnxOfflineZipformerCtcModelConfig) == 4, "");
static_assert(sizeof(SherpaOnnxOfflineWenetCtcModelConfig) == 4, "");
static_assert(sizeof(SherpaOnnxOfflineOmnilingualAsrCtcModelConfig) == 4, "");
static_assert(sizeof(SherpaOnnxOfflineDolphinModelConfig) == 4, "");
static_assert(sizeof(SherpaOnnxOfflineNemoEncDecCtcModelConfig) == 4, "");
static_assert(sizeof(SherpaOnnxOfflineWhisperModelConfig) == 5 * 4, "");
Expand All @@ -37,7 +38,8 @@ static_assert(sizeof(SherpaOnnxOfflineModelConfig) ==
sizeof(SherpaOnnxOfflineDolphinModelConfig) +
sizeof(SherpaOnnxOfflineZipformerCtcModelConfig) +
sizeof(SherpaOnnxOfflineCanaryModelConfig) +
sizeof(SherpaOnnxOfflineWenetCtcModelConfig),
sizeof(SherpaOnnxOfflineWenetCtcModelConfig) +
sizeof(SherpaOnnxOfflineOmnilingualAsrCtcModelConfig),

"");
static_assert(sizeof(SherpaOnnxFeatureConfig) == 2 * 4, "");
Expand Down Expand Up @@ -86,6 +88,7 @@ void PrintOfflineRecognizerConfig(SherpaOnnxOfflineRecognizerConfig *config) {
auto zipformer_ctc = &model_config->zipformer_ctc;
auto canary = &model_config->canary;
auto wenet_ctc = &model_config->wenet_ctc;
auto omnilingual = &model_config->omnilingual;

fprintf(stdout, "----------offline transducer model config----------\n");
fprintf(stdout, "encoder: %s\n", transducer->encoder);
Expand Down Expand Up @@ -139,6 +142,9 @@ void PrintOfflineRecognizerConfig(SherpaOnnxOfflineRecognizerConfig *config) {
fprintf(stdout, "----------offline wenet ctc model config----------\n");
fprintf(stdout, "model: %s\n", wenet_ctc->model);

fprintf(stdout, "----------offline Omnilingual ASR model config----------\n");
fprintf(stdout, "model: %s\n", omnilingual->model);

fprintf(stdout, "tokens: %s\n", model_config->tokens);
fprintf(stdout, "num_threads: %d\n", model_config->num_threads);
fprintf(stdout, "provider: %s\n", model_config->provider);
Expand Down
Loading