Fangjun Kuang
Committed by GitHub

Add JavaScript API (WASM) for homophone replacer (#2157)

@@ -144,7 +144,18 @@ tar xvf sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17.tar.bz2 @@ -144,7 +144,18 @@ tar xvf sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17.tar.bz2
144 rm sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17.tar.bz2 144 rm sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17.tar.bz2
145 145
146 node ./test-offline-sense-voice.js 146 node ./test-offline-sense-voice.js
  147 +
  148 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/hr-files/dict.tar.bz2
  149 +tar xf dict.tar.bz2
  150 +
  151 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/hr-files/replace.fst
  152 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/hr-files/test-hr.wav
  153 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/hr-files/lexicon.txt
  154 +
  155 +node ./test-offline-sense-voice-with-hr.js
  156 +
147 rm -rf sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17 157 rm -rf sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17
  158 +rm -rf dict replace.fst test-hr.wav lexicon.txt
148 159
149 curl -LS -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-paraformer-zh-2023-09-14.tar.bz2 160 curl -LS -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-paraformer-zh-2023-09-14.tar.bz2
150 ls -lh 161 ls -lh
@@ -20,7 +20,7 @@ jobs: @@ -20,7 +20,7 @@ jobs:
20 strategy: 20 strategy:
21 fail-fast: false 21 fail-fast: false
22 matrix: 22 matrix:
23 - os: [ubuntu-20.04] 23 + os: [ubuntu-22.04]
24 python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] 24 python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
25 25
26 steps: 26 steps:
@@ -20,7 +20,7 @@ jobs: @@ -20,7 +20,7 @@ jobs:
20 strategy: 20 strategy:
21 fail-fast: false 21 fail-fast: false
22 matrix: 22 matrix:
23 - os: [ubuntu-latest] 23 + os: [ubuntu-22.04]
24 python-version: ["cp37", "cp38", "cp39", "cp310", "cp311", "cp312", "cp313"] 24 python-version: ["cp37", "cp38", "cp39", "cp310", "cp311", "cp312", "cp313"]
25 manylinux: [manylinux2014] #, manylinux_2_28] 25 manylinux: [manylinux2014] #, manylinux_2_28]
26 26
@@ -35,11 +35,11 @@ jobs: @@ -35,11 +35,11 @@ jobs:
35 matrix: 35 matrix:
36 # See https://github.com/actions/runner-images 36 # See https://github.com/actions/runner-images
37 include: 37 include:
38 - - os: ubuntu-20.04 38 + - os: ubuntu-22.04
39 python-version: "3.7" 39 python-version: "3.7"
40 - - os: ubuntu-20.04 40 + - os: ubuntu-22.04
41 python-version: "3.8" 41 python-version: "3.8"
42 - - os: ubuntu-20.04 42 + - os: ubuntu-22.04
43 python-version: "3.9" 43 python-version: "3.9"
44 - os: ubuntu-22.04 44 - os: ubuntu-22.04
45 python-version: "3.10" 45 python-version: "3.10"
@@ -48,7 +48,7 @@ jobs: @@ -48,7 +48,7 @@ jobs:
48 - os: ubuntu-22.04 48 - os: ubuntu-22.04
49 python-version: "3.12" 49 python-version: "3.12"
50 50
51 - - os: macos-12 51 + - os: macos-13
52 python-version: "3.8" 52 python-version: "3.8"
53 53
54 - os: macos-13 54 - os: macos-13
@@ -137,8 +137,8 @@ jobs: @@ -137,8 +137,8 @@ jobs:
137 export PATH=/c/hostedtoolcache/windows/Python/3.9.13/x64/bin:$PATH 137 export PATH=/c/hostedtoolcache/windows/Python/3.9.13/x64/bin:$PATH
138 export PATH=/c/hostedtoolcache/windows/Python/3.10.11/x64/bin:$PATH 138 export PATH=/c/hostedtoolcache/windows/Python/3.10.11/x64/bin:$PATH
139 export PATH=/c/hostedtoolcache/windows/Python/3.11.9/x64/bin:$PATH 139 export PATH=/c/hostedtoolcache/windows/Python/3.11.9/x64/bin:$PATH
140 - export PATH=/c/hostedtoolcache/windows/Python/3.12.9/x64/bin:$PATH  
141 - export PATH=/c/hostedtoolcache/windows/Python/3.13.2/x64/bin:$PATH 140 + export PATH=/c/hostedtoolcache/windows/Python/3.12.10/x64/bin:$PATH
  141 + export PATH=/c/hostedtoolcache/windows/Python/3.13.3/x64/bin:$PATH
142 142
143 which sherpa-onnx 143 which sherpa-onnx
144 sherpa-onnx --help 144 sherpa-onnx --help
@@ -40,7 +40,7 @@ jobs: @@ -40,7 +40,7 @@ jobs:
40 strategy: 40 strategy:
41 fail-fast: false 41 fail-fast: false
42 matrix: 42 matrix:
43 - os: [macos-latest, macos-14, ubuntu-20.04, ubuntu-22.04, windows-latest] 43 + os: [macos-latest, macos-14, ubuntu-latest, ubuntu-22.04, windows-latest]
44 node-version: ["16", "17", "18", "19", "21", "22"] 44 node-version: ["16", "17", "18", "19", "21", "22"]
45 45
46 steps: 46 steps:
@@ -30,11 +30,11 @@ jobs: @@ -30,11 +30,11 @@ jobs:
30 matrix: 30 matrix:
31 # See https://github.com/actions/runner-images 31 # See https://github.com/actions/runner-images
32 include: 32 include:
33 - - os: ubuntu-20.04 33 + - os: ubuntu-22.04
34 python-version: "3.7" 34 python-version: "3.7"
35 - - os: ubuntu-20.04 35 + - os: ubuntu-22.04
36 python-version: "3.8" 36 python-version: "3.8"
37 - - os: ubuntu-20.04 37 + - os: ubuntu-22.04
38 python-version: "3.9" 38 python-version: "3.9"
39 - os: ubuntu-22.04 39 - os: ubuntu-22.04
40 python-version: "3.10" 40 python-version: "3.10"
@@ -45,7 +45,7 @@ jobs: @@ -45,7 +45,7 @@ jobs:
45 - os: ubuntu-22.04 45 - os: ubuntu-22.04
46 python-version: "3.13" 46 python-version: "3.13"
47 47
48 - - os: macos-12 48 + - os: macos-13
49 python-version: "3.8" 49 python-version: "3.8"
50 50
51 - os: macos-13 51 - os: macos-13
@@ -110,8 +110,8 @@ jobs: @@ -110,8 +110,8 @@ jobs:
110 export PATH=/c/hostedtoolcache/windows/Python/3.9.13/x64/bin:$PATH 110 export PATH=/c/hostedtoolcache/windows/Python/3.9.13/x64/bin:$PATH
111 export PATH=/c/hostedtoolcache/windows/Python/3.10.11/x64/bin:$PATH 111 export PATH=/c/hostedtoolcache/windows/Python/3.10.11/x64/bin:$PATH
112 export PATH=/c/hostedtoolcache/windows/Python/3.11.9/x64/bin:$PATH 112 export PATH=/c/hostedtoolcache/windows/Python/3.11.9/x64/bin:$PATH
113 - export PATH=/c/hostedtoolcache/windows/Python/3.12.9/x64/bin:$PATH  
114 - export PATH=/c/hostedtoolcache/windows/Python/3.13.2/x64/bin:$PATH 113 + export PATH=/c/hostedtoolcache/windows/Python/3.12.10/x64/bin:$PATH
  114 + export PATH=/c/hostedtoolcache/windows/Python/3.13.3/x64/bin:$PATH
115 115
116 sherpa-onnx --help 116 sherpa-onnx --help
117 sherpa-onnx-keyword-spotter --help 117 sherpa-onnx-keyword-spotter --help
@@ -33,7 +33,7 @@ jobs: @@ -33,7 +33,7 @@ jobs:
33 strategy: 33 strategy:
34 fail-fast: false 34 fail-fast: false
35 matrix: 35 matrix:
36 - os: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest, macos-14] 36 + os: [ubuntu-latest, ubuntu-22.04, windows-latest, macos-latest, macos-14]
37 python-version: ["3.10"] 37 python-version: ["3.10"]
38 model_type: ["transducer", "paraformer", "nemo_ctc", "whisper", "tdnn"] 38 model_type: ["transducer", "paraformer", "nemo_ctc", "whisper", "tdnn"]
39 39
@@ -33,7 +33,7 @@ jobs: @@ -33,7 +33,7 @@ jobs:
33 strategy: 33 strategy:
34 fail-fast: false 34 fail-fast: false
35 matrix: 35 matrix:
36 - os: [ubuntu-20.04, ubuntu-22.04, windows-latest, macos-latest, macos-14] 36 + os: [ubuntu-latest, ubuntu-22.04, windows-latest, macos-latest, macos-14]
37 python-version: ["3.10"] 37 python-version: ["3.10"]
38 model_type: ["transducer", "paraformer", "zipformer2-ctc"] 38 model_type: ["transducer", "paraformer", "zipformer2-ctc"]
39 39
@@ -182,10 +182,32 @@ tar xvf sherpa-onnx-paraformer-zh-2023-09-14.tar.bz2 @@ -182,10 +182,32 @@ tar xvf sherpa-onnx-paraformer-zh-2023-09-14.tar.bz2
182 node ./test-offline-paraformer.js 182 node ./test-offline-paraformer.js
183 ``` 183 ```
184 184
  185 +## ./test-offline-sense-voice-with-hr.js
  186 +
  187 +[./test-offline-sense-voice-with-hr.js](./test-offline-sense-voice-with-hr.js) demonstrates
  188 +how to decode a file with a non-streaming SenseVoice model with homophone replacer.
  189 +
  190 +You can use the following command to run it:
  191 +
  192 +```bash
  193 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17.tar.bz2
  194 +tar xvf sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17.tar.bz2
  195 +rm sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17.tar.bz2
  196 +
  197 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/hr-files/dict.tar.bz2
  198 +tar xf dict.tar.bz2
  199 +
  200 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/hr-files/replace.fst
  201 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/hr-files/test-hr.wav
  202 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/hr-files/lexicon.txt
  203 +
  204 +node ./test-offline-sense-voice-with-hr.js
  205 +```
  206 +
185 ## ./test-offline-sense-voice.js 207 ## ./test-offline-sense-voice.js
186 208
187 [./test-offline-sense-voice.js](./test-offline-sense-voice.js) demonstrates 209 [./test-offline-sense-voice.js](./test-offline-sense-voice.js) demonstrates
188 -how to decode a file with a non-streaming Paraformer model. 210 +how to decode a file with a non-streaming SenseVoice model.
189 211
190 You can use the following command to run it: 212 You can use the following command to run it:
191 213
  1 +// Copyright (c) 2024-2025 Xiaomi Corporation (authors: Fangjun Kuang)
  2 +
  3 +const sherpa_onnx = require('sherpa-onnx');
  4 +
  5 +function createOfflineRecognizer() {
  6 + let modelConfig = {
  7 + senseVoice: {
  8 + model:
  9 + './sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17/model.int8.onnx',
  10 + language: '',
  11 + useInverseTextNormalization: 1,
  12 + },
  13 + tokens: './sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17/tokens.txt',
  14 + };
  15 +
  16 + let config = {
  17 + modelConfig: modelConfig,
  18 + hr: {
  19 + dictDir: './dict',
  20 + lexicon: './lexicon.txt',
  21 + ruleFsts: './replace.fst',
  22 + },
  23 + };
  24 +
  25 + return sherpa_onnx.createOfflineRecognizer(config);
  26 +}
  27 +
  28 +const recognizer = createOfflineRecognizer();
  29 +const stream = recognizer.createStream();
  30 +
  31 +const waveFilename = './test-hr.wav';
  32 +const wave = sherpa_onnx.readWave(waveFilename);
  33 +stream.acceptWaveform(wave.sampleRate, wave.samples);
  34 +
  35 +recognizer.decode(stream);
  36 +const text = recognizer.getResult(stream).text;
  37 +console.log(text);
  38 +
  39 +stream.free();
  40 +recognizer.free();
@@ -63,6 +63,10 @@ function freeConfig(config, Module) { @@ -63,6 +63,10 @@ function freeConfig(config, Module) {
63 freeConfig(config.ctcFstDecoder, Module) 63 freeConfig(config.ctcFstDecoder, Module)
64 } 64 }
65 65
  66 + if ('hr' in config) {
  67 + freeConfig(config.hr, Module)
  68 + }
  69 +
66 Module._free(config.ptr); 70 Module._free(config.ptr);
67 } 71 }
68 72
@@ -281,6 +285,34 @@ function initSherpaOnnxFeatureConfig(config, Module) { @@ -281,6 +285,34 @@ function initSherpaOnnxFeatureConfig(config, Module) {
281 return {ptr: ptr, len: len}; 285 return {ptr: ptr, len: len};
282 } 286 }
283 287
  288 +function initSherpaOnnxHomophoneReplacerConfig(config, Module) {
  289 + const len = 3 * 4;
  290 + const ptr = Module._malloc(len);
  291 +
  292 + const dictDirLen = Module.lengthBytesUTF8(config.dictDir || '') + 1;
  293 + const lexiconLen = Module.lengthBytesUTF8(config.lexicon || '') + 1;
  294 + const ruleFstsLen = Module.lengthBytesUTF8(config.ruleFsts || '') + 1;
  295 +
  296 + const bufferLen = dictDirLen + lexiconLen + ruleFstsLen;
  297 +
  298 + const buffer = Module._malloc(bufferLen);
  299 + let offset = 0
  300 + Module.stringToUTF8(config.dictDir || '', buffer + offset, dictDirLen);
  301 + offset += dictDirLen;
  302 +
  303 + Module.stringToUTF8(config.lexicon || '', buffer + offset, lexiconLen);
  304 + offset += lexiconLen;
  305 +
  306 + Module.stringToUTF8(config.ruleFsts || '', buffer + offset, ruleFstsLen);
  307 + offset += ruleFstsLen;
  308 +
  309 + Module.setValue(ptr, buffer, 'i8*');
  310 + Module.setValue(ptr + 4, buffer + dictDirLen, 'i8*');
  311 + Module.setValue(ptr + 8, buffer + dictDirLen + lexiconLen, 'i8*');
  312 +
  313 + return {ptr: ptr, len: len, buffer: buffer};
  314 +}
  315 +
284 function initSherpaOnnxOnlineCtcFstDecoderConfig(config, Module) { 316 function initSherpaOnnxOnlineCtcFstDecoderConfig(config, Module) {
285 const len = 2 * 4; 317 const len = 2 * 4;
286 const ptr = Module._malloc(len); 318 const ptr = Module._malloc(len);
@@ -317,12 +349,21 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) { @@ -317,12 +349,21 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
317 config.hotwordsBufSize = 0; 349 config.hotwordsBufSize = 0;
318 } 350 }
319 351
  352 + if (!('hr' in config)) {
  353 + config.hr = {
  354 + dictDir: '',
  355 + lexicon: '',
  356 + ruleFsts: '',
  357 + };
  358 + }
  359 +
320 const feat = initSherpaOnnxFeatureConfig(config.featConfig, Module); 360 const feat = initSherpaOnnxFeatureConfig(config.featConfig, Module);
321 const model = initSherpaOnnxOnlineModelConfig(config.modelConfig, Module); 361 const model = initSherpaOnnxOnlineModelConfig(config.modelConfig, Module);
322 const ctcFstDecoder = initSherpaOnnxOnlineCtcFstDecoderConfig( 362 const ctcFstDecoder = initSherpaOnnxOnlineCtcFstDecoderConfig(
323 config.ctcFstDecoderConfig, Module) 363 config.ctcFstDecoderConfig, Module)
  364 + const hr = initSherpaOnnxHomophoneReplacerConfig(config.hr, Module);
324 365
325 - const len = feat.len + model.len + 8 * 4 + ctcFstDecoder.len + 5 * 4; 366 + const len = feat.len + model.len + 8 * 4 + ctcFstDecoder.len + 5 * 4 + hr.len;
326 const ptr = Module._malloc(len); 367 const ptr = Module._malloc(len);
327 368
328 let offset = 0; 369 let offset = 0;
@@ -411,9 +452,12 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) { @@ -411,9 +452,12 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
411 Module.setValue(ptr + offset, config.hotwordsBufSize || 0, 'i32'); 452 Module.setValue(ptr + offset, config.hotwordsBufSize || 0, 'i32');
412 offset += 4; 453 offset += 4;
413 454
  455 + Module._CopyHeap(hr.ptr, hr.len, ptr + offset);
  456 + offset += hr.len;
  457 +
414 return { 458 return {
415 buffer: buffer, ptr: ptr, len: len, feat: feat, model: model, 459 buffer: buffer, ptr: ptr, len: len, feat: feat, model: model,
416 - ctcFstDecoder: ctcFstDecoder 460 + ctcFstDecoder: ctcFstDecoder, hr: hr,
417 } 461 }
418 } 462 }
419 463
@@ -989,11 +1033,20 @@ function initSherpaOnnxOfflineRecognizerConfig(config, Module) { @@ -989,11 +1033,20 @@ function initSherpaOnnxOfflineRecognizerConfig(config, Module) {
989 }; 1033 };
990 } 1034 }
991 1035
  1036 + if (!('hr' in config)) {
  1037 + config.hr = {
  1038 + dictDir: '',
  1039 + lexicon: '',
  1040 + ruleFsts: '',
  1041 + };
  1042 + }
  1043 +
992 const feat = initSherpaOnnxFeatureConfig(config.featConfig, Module); 1044 const feat = initSherpaOnnxFeatureConfig(config.featConfig, Module);
993 const model = initSherpaOnnxOfflineModelConfig(config.modelConfig, Module); 1045 const model = initSherpaOnnxOfflineModelConfig(config.modelConfig, Module);
994 const lm = initSherpaOnnxOfflineLMConfig(config.lmConfig, Module); 1046 const lm = initSherpaOnnxOfflineLMConfig(config.lmConfig, Module);
  1047 + const hr = initSherpaOnnxHomophoneReplacerConfig(config.hr, Module);
995 1048
996 - const len = feat.len + model.len + lm.len + 7 * 4; 1049 + const len = feat.len + model.len + lm.len + 7 * 4 + hr.len;
997 const ptr = Module._malloc(len); 1050 const ptr = Module._malloc(len);
998 1051
999 let offset = 0; 1052 let offset = 0;
@@ -1056,8 +1109,12 @@ function initSherpaOnnxOfflineRecognizerConfig(config, Module) { @@ -1056,8 +1109,12 @@ function initSherpaOnnxOfflineRecognizerConfig(config, Module) {
1056 Module.setValue(ptr + offset, config.blankPenalty || 0, 'float'); 1109 Module.setValue(ptr + offset, config.blankPenalty || 0, 'float');
1057 offset += 4; 1110 offset += 4;
1058 1111
  1112 + Module._CopyHeap(hr.ptr, hr.len, ptr + offset);
  1113 + offset += hr.len;
  1114 +
1059 return { 1115 return {
1060 - buffer: buffer, ptr: ptr, len: len, feat: feat, model: model, lm: lm 1116 + buffer: buffer, ptr: ptr, len: len, feat: feat, model: model, lm: lm,
  1117 + hr: hr,
1061 } 1118 }
1062 } 1119 }
1063 1120
@@ -26,7 +26,8 @@ static_assert(sizeof(SherpaOnnxOnlineCtcFstDecoderConfig) == 2 * 4, ""); @@ -26,7 +26,8 @@ static_assert(sizeof(SherpaOnnxOnlineCtcFstDecoderConfig) == 2 * 4, "");
26 static_assert(sizeof(SherpaOnnxOnlineRecognizerConfig) == 26 static_assert(sizeof(SherpaOnnxOnlineRecognizerConfig) ==
27 sizeof(SherpaOnnxFeatureConfig) + 27 sizeof(SherpaOnnxFeatureConfig) +
28 sizeof(SherpaOnnxOnlineModelConfig) + 8 * 4 + 28 sizeof(SherpaOnnxOnlineModelConfig) + 8 * 4 +
29 - sizeof(SherpaOnnxOnlineCtcFstDecoderConfig) + 5 * 4, 29 + sizeof(SherpaOnnxOnlineCtcFstDecoderConfig) + 5 * 4 +
  30 + sizeof(SherpaOnnxHomophoneReplacerConfig),
30 ""); 31 "");
31 32
32 void MyPrint(SherpaOnnxOnlineRecognizerConfig *config) { 33 void MyPrint(SherpaOnnxOnlineRecognizerConfig *config) {
@@ -82,6 +83,11 @@ void MyPrint(SherpaOnnxOnlineRecognizerConfig *config) { @@ -82,6 +83,11 @@ void MyPrint(SherpaOnnxOnlineRecognizerConfig *config) {
82 fprintf(stdout, "graph: %s\n", config->ctc_fst_decoder_config.graph); 83 fprintf(stdout, "graph: %s\n", config->ctc_fst_decoder_config.graph);
83 fprintf(stdout, "max_active: %d\n", 84 fprintf(stdout, "max_active: %d\n",
84 config->ctc_fst_decoder_config.max_active); 85 config->ctc_fst_decoder_config.max_active);
  86 +
  87 + fprintf(stdout, "----------hr config----------\n");
  88 + fprintf(stdout, "dict_dir: %s\n", config->hr.dict_dir);
  89 + fprintf(stdout, "lexicon: %s\n", config->hr.lexicon);
  90 + fprintf(stdout, "rule_fsts: %s\n", config->hr.rule_fsts);
85 } 91 }
86 92
87 void CopyHeap(const char *src, int32_t num_bytes, char *dst) { 93 void CopyHeap(const char *src, int32_t num_bytes, char *dst) {
@@ -38,7 +38,8 @@ static_assert(sizeof(SherpaOnnxFeatureConfig) == 2 * 4, ""); @@ -38,7 +38,8 @@ static_assert(sizeof(SherpaOnnxFeatureConfig) == 2 * 4, "");
38 static_assert(sizeof(SherpaOnnxOfflineRecognizerConfig) == 38 static_assert(sizeof(SherpaOnnxOfflineRecognizerConfig) ==
39 sizeof(SherpaOnnxFeatureConfig) + 39 sizeof(SherpaOnnxFeatureConfig) +
40 sizeof(SherpaOnnxOfflineLMConfig) + 40 sizeof(SherpaOnnxOfflineLMConfig) +
41 - sizeof(SherpaOnnxOfflineModelConfig) + 7 * 4, 41 + sizeof(SherpaOnnxOfflineModelConfig) + 7 * 4 +
  42 + sizeof(SherpaOnnxHomophoneReplacerConfig),
42 ""); 43 "");
43 44
44 void PrintOfflineTtsConfig(SherpaOnnxOfflineTtsConfig *tts_config) { 45 void PrintOfflineTtsConfig(SherpaOnnxOfflineTtsConfig *tts_config) {
@@ -137,6 +138,10 @@ void PrintOfflineRecognizerConfig(SherpaOnnxOfflineRecognizerConfig *config) { @@ -137,6 +138,10 @@ void PrintOfflineRecognizerConfig(SherpaOnnxOfflineRecognizerConfig *config) {
137 fprintf(stdout, "rule_fsts: %s\n", config->rule_fsts); 138 fprintf(stdout, "rule_fsts: %s\n", config->rule_fsts);
138 fprintf(stdout, "rule_fars: %s\n", config->rule_fars); 139 fprintf(stdout, "rule_fars: %s\n", config->rule_fars);
139 fprintf(stdout, "blank_penalty: %f\n", config->blank_penalty); 140 fprintf(stdout, "blank_penalty: %f\n", config->blank_penalty);
  141 + fprintf(stdout, "----------hr config----------\n");
  142 + fprintf(stdout, "dict_dir: %s\n", config->hr.dict_dir);
  143 + fprintf(stdout, "lexicon: %s\n", config->hr.lexicon);
  144 + fprintf(stdout, "rule_fsts: %s\n", config->hr.rule_fsts);
140 } 145 }
141 146
142 void CopyHeap(const char *src, int32_t num_bytes, char *dst) { 147 void CopyHeap(const char *src, int32_t num_bytes, char *dst) {