Fangjun Kuang
Committed by GitHub

Inverse text normalization API of streaming ASR for various programming languages (#1022)

正在显示 64 个修改的文件 包含 845 行增加51 行删除
@@ -66,7 +66,9 @@ echo '----------streaming zipformer ctc----------' @@ -66,7 +66,9 @@ echo '----------streaming zipformer ctc----------'
66 rm -rf sherpa-onnx-* 66 rm -rf sherpa-onnx-*
67 67
68 echo '----------streaming zipformer transducer----------' 68 echo '----------streaming zipformer transducer----------'
  69 +./run-zipformer-transducer-itn.sh
69 ./run-zipformer-transducer.sh 70 ./run-zipformer-transducer.sh
  71 +rm -f itn*
70 rm -rf sherpa-onnx-* 72 rm -rf sherpa-onnx-*
71 73
72 echo '----------streaming NeMo transducer----------' 74 echo '----------streaming NeMo transducer----------'
@@ -2,7 +2,13 @@ @@ -2,7 +2,13 @@
2 2
3 cd dotnet-examples/ 3 cd dotnet-examples/
4 4
5 -cd ./offline-decode-files 5 +cd ./online-decode-files
  6 +./run-transducer-itn.sh
  7 +./run-zipformer2-ctc.sh
  8 +./run-transducer.sh
  9 +./run-paraformer.sh
  10 +
  11 +cd ../offline-decode-files
6 ./run-paraformer-itn.sh 12 ./run-paraformer-itn.sh
7 ./run-telespeech-ctc.sh 13 ./run-telespeech-ctc.sh
8 ./run-nemo-ctc.sh 14 ./run-nemo-ctc.sh
@@ -27,11 +33,6 @@ cd ../streaming-hlg-decoding/ @@ -27,11 +33,6 @@ cd ../streaming-hlg-decoding/
27 cd ../spoken-language-identification 33 cd ../spoken-language-identification
28 ./run.sh 34 ./run.sh
29 35
30 -cd ../online-decode-files  
31 -./run-zipformer2-ctc.sh  
32 -./run-transducer.sh  
33 -./run-paraformer.sh  
34 -  
35 cd ../offline-tts 36 cd ../offline-tts
36 ./run-aishell3.sh 37 ./run-aishell3.sh
37 ./run-piper.sh 38 ./run-piper.sh
@@ -70,6 +70,13 @@ curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/s @@ -70,6 +70,13 @@ curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/s
70 tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2 70 tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
71 rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2 71 rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
72 72
  73 +rm -f itn*
  74 +
  75 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  76 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
  77 +
  78 +node test_asr_streaming_transducer_itn.js
  79 +
73 node test_asr_streaming_transducer.js 80 node test_asr_streaming_transducer.js
74 81
75 rm -rf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20 82 rm -rf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20
@@ -120,6 +127,8 @@ rm sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2 @@ -120,6 +127,8 @@ rm sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
120 127
121 node ./test_asr_non_streaming_paraformer.js 128 node ./test_asr_non_streaming_paraformer.js
122 129
  130 +rm -f itn*
  131 +
123 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst 132 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
124 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav 133 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
125 134
@@ -15,6 +15,8 @@ curl -LS -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/s @@ -15,6 +15,8 @@ curl -LS -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/s
15 ls -lh 15 ls -lh
16 tar xvf sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2 16 tar xvf sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
17 rm sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2 17 rm sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
  18 +
  19 +rm -f itn*
18 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav 20 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
19 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst 21 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
20 node ./test-offline-paraformer-itn.js 22 node ./test-offline-paraformer-itn.js
@@ -57,7 +59,15 @@ rm -rf sherpa-onnx-streaming-paraformer-bilingual-zh-en @@ -57,7 +59,15 @@ rm -rf sherpa-onnx-streaming-paraformer-bilingual-zh-en
57 curl -LS -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2 59 curl -LS -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
58 tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2 60 tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
59 rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2 61 rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  62 +
  63 +rm -f itn*
  64 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
  65 +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  66 +
  67 +node ./test-online-transducer-itn.js
  68 +
60 node ./test-online-transducer.js 69 node ./test-online-transducer.js
  70 +
61 rm -rf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20 71 rm -rf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20
62 72
63 curl -LS -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-ctc-multi-zh-hans-2023-12-13.tar.bz2 73 curl -LS -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-ctc-multi-zh-hans-2023-12-13.tar.bz2
@@ -2,6 +2,8 @@ name: build-wheels-aarch64 @@ -2,6 +2,8 @@ name: build-wheels-aarch64
2 2
3 on: 3 on:
4 push: 4 push:
  5 + branches:
  6 + - wheel
5 tags: 7 tags:
6 - 'v[0-9]+.[0-9]+.[0-9]+*' 8 - 'v[0-9]+.[0-9]+.[0-9]+*'
7 workflow_dispatch: 9 workflow_dispatch:
@@ -2,6 +2,8 @@ name: build-wheels-armv7l @@ -2,6 +2,8 @@ name: build-wheels-armv7l
2 2
3 on: 3 on:
4 push: 4 push:
  5 + branches:
  6 + - wheel
5 tags: 7 tags:
6 - 'v[0-9]+.[0-9]+.[0-9]+*' 8 - 'v[0-9]+.[0-9]+.[0-9]+*'
7 workflow_dispatch: 9 workflow_dispatch:
@@ -2,6 +2,8 @@ name: build-wheels-linux @@ -2,6 +2,8 @@ name: build-wheels-linux
2 2
3 on: 3 on:
4 push: 4 push:
  5 + branches:
  6 + - wheel
5 tags: 7 tags:
6 - 'v[0-9]+.[0-9]+.[0-9]+*' 8 - 'v[0-9]+.[0-9]+.[0-9]+*'
7 workflow_dispatch: 9 workflow_dispatch:
@@ -2,6 +2,8 @@ name: build-wheels-macos-arm64 @@ -2,6 +2,8 @@ name: build-wheels-macos-arm64
2 2
3 on: 3 on:
4 push: 4 push:
  5 + branches:
  6 + - wheel
5 tags: 7 tags:
6 - 'v[0-9]+.[0-9]+.[0-9]+*' 8 - 'v[0-9]+.[0-9]+.[0-9]+*'
7 workflow_dispatch: 9 workflow_dispatch:
@@ -84,7 +86,7 @@ jobs: @@ -84,7 +86,7 @@ jobs:
84 run: | 86 run: |
85 opts='--break-system-packages' 87 opts='--break-system-packages'
86 v=${{ matrix.python-version }} 88 v=${{ matrix.python-version }}
87 - if [[ $v == cp38 || $v == cp39 ]]; then 89 + if [[ $v == cp37 || $v == cp38 || $v == cp39 ]]; then
88 opts='' 90 opts=''
89 fi 91 fi
90 92
@@ -101,7 +101,7 @@ jobs: @@ -101,7 +101,7 @@ jobs:
101 run: | 101 run: |
102 opts='--break-system-packages' 102 opts='--break-system-packages'
103 v=${{ matrix.python-version }} 103 v=${{ matrix.python-version }}
104 - if [[ $v == cp38 || $v == cp39 ]]; then 104 + if [[ $v == cp37 || $v == cp38 || $v == cp39 ]]; then
105 opts='' 105 opts=''
106 fi 106 fi
107 107
@@ -2,6 +2,8 @@ name: build-wheels-win32 @@ -2,6 +2,8 @@ name: build-wheels-win32
2 2
3 on: 3 on:
4 push: 4 push:
  5 + branches:
  6 + - wheel
5 tags: 7 tags:
6 - 'v[0-9]+.[0-9]+.[0-9]+*' 8 - 'v[0-9]+.[0-9]+.[0-9]+*'
7 workflow_dispatch: 9 workflow_dispatch:
@@ -173,6 +173,9 @@ jobs: @@ -173,6 +173,9 @@ jobs:
173 shell: bash 173 shell: bash
174 run: | 174 run: |
175 cd ./java-api-examples 175 cd ./java-api-examples
  176 + ./run-inverse-text-normalization-transducer.sh
  177 + rm -rf sherpa-onnx-streaming-*
  178 +
176 ./run-streaming-decode-file-ctc.sh 179 ./run-streaming-decode-file-ctc.sh
177 # Delete model files to save space 180 # Delete model files to save space
178 rm -rf sherpa-onnx-streaming-* 181 rm -rf sherpa-onnx-streaming-*
@@ -187,6 +187,9 @@ jobs: @@ -187,6 +187,9 @@ jobs:
187 ./run-transducer.sh 187 ./run-transducer.sh
188 rm -rf sherpa-onnx-streaming-zipformer-en-2023-06-26 188 rm -rf sherpa-onnx-streaming-zipformer-en-2023-06-26
189 189
  190 + ./run-transducer-itn.sh
  191 + rm -rf sherpa-onnx-streaming-*
  192 +
190 echo "Test paraformer" 193 echo "Test paraformer"
191 ./run-paraformer.sh 194 ./run-paraformer.sh
192 rm -rf sherpa-onnx-streaming-paraformer-bilingual-zh-en 195 rm -rf sherpa-onnx-streaming-paraformer-bilingual-zh-en
@@ -7,7 +7,8 @@ project(sherpa-onnx) @@ -7,7 +7,8 @@ project(sherpa-onnx)
7 # Remember to update 7 # Remember to update
8 # ./nodejs-addon-examples 8 # ./nodejs-addon-examples
9 # ./dart-api-examples/ 9 # ./dart-api-examples/
10 -set(SHERPA_ONNX_VERSION "1.9.30") 10 +# ./sherpa-onnx/flutter/CHANGELOG.md
  11 +set(SHERPA_ONNX_VERSION "1.10.0")
11 12
12 # Disable warning about 13 # Disable warning about
13 # 14 #
@@ -196,6 +196,9 @@ class MainActivity : AppCompatActivity() { @@ -196,6 +196,9 @@ class MainActivity : AppCompatActivity() {
196 // See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html 196 // See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
197 // for a list of available models 197 // for a list of available models
198 val type = 0 198 val type = 0
  199 + var ruleFsts : String?
  200 + ruleFsts = null
  201 +
199 Log.i(TAG, "Select model type $type") 202 Log.i(TAG, "Select model type $type")
200 val config = OnlineRecognizerConfig( 203 val config = OnlineRecognizerConfig(
201 featConfig = getFeatureConfig(sampleRate = sampleRateInHz, featureDim = 80), 204 featConfig = getFeatureConfig(sampleRate = sampleRateInHz, featureDim = 80),
@@ -205,6 +208,10 @@ class MainActivity : AppCompatActivity() { @@ -205,6 +208,10 @@ class MainActivity : AppCompatActivity() {
205 enableEndpoint = true, 208 enableEndpoint = true,
206 ) 209 )
207 210
  211 + if (ruleFsts != null) {
  212 + config.ruleFsts = ruleFsts
  213 + }
  214 +
208 recognizer = OnlineRecognizer( 215 recognizer = OnlineRecognizer(
209 assetManager = application.assets, 216 assetManager = application.assets,
210 config = config, 217 config = config,
@@ -194,6 +194,8 @@ class MainActivity : AppCompatActivity() { @@ -194,6 +194,8 @@ class MainActivity : AppCompatActivity() {
194 // See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html 194 // See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
195 // for a list of available models 195 // for a list of available models
196 val firstType = 9 196 val firstType = 9
  197 + val firstRuleFsts: String?
  198 + firstRuleFsts = null
197 Log.i(TAG, "Select model type $firstType for the first pass") 199 Log.i(TAG, "Select model type $firstType for the first pass")
198 val config = OnlineRecognizerConfig( 200 val config = OnlineRecognizerConfig(
199 featConfig = getFeatureConfig(sampleRate = sampleRateInHz, featureDim = 80), 201 featConfig = getFeatureConfig(sampleRate = sampleRateInHz, featureDim = 80),
@@ -201,6 +203,9 @@ class MainActivity : AppCompatActivity() { @@ -201,6 +203,9 @@ class MainActivity : AppCompatActivity() {
201 endpointConfig = getEndpointConfig(), 203 endpointConfig = getEndpointConfig(),
202 enableEndpoint = true, 204 enableEndpoint = true,
203 ) 205 )
  206 + if (firstRuleFsts != null) {
  207 + config.ruleFsts = firstRuleFsts;
  208 + }
204 209
205 onlineRecognizer = OnlineRecognizer( 210 onlineRecognizer = OnlineRecognizer(
206 assetManager = application.assets, 211 assetManager = application.assets,
@@ -213,6 +218,8 @@ class MainActivity : AppCompatActivity() { @@ -213,6 +218,8 @@ class MainActivity : AppCompatActivity() {
213 // See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html 218 // See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
214 // for a list of available models 219 // for a list of available models
215 val secondType = 0 220 val secondType = 0
  221 + var secondRuleFsts: String?
  222 + secondRuleFsts = null
216 Log.i(TAG, "Select model type $secondType for the second pass") 223 Log.i(TAG, "Select model type $secondType for the second pass")
217 224
218 val config = OfflineRecognizerConfig( 225 val config = OfflineRecognizerConfig(
@@ -220,6 +227,10 @@ class MainActivity : AppCompatActivity() { @@ -220,6 +227,10 @@ class MainActivity : AppCompatActivity() {
220 modelConfig = getOfflineModelConfig(type = secondType)!!, 227 modelConfig = getOfflineModelConfig(type = secondType)!!,
221 ) 228 )
222 229
  230 + if (secondRuleFsts != null) {
  231 + config.ruleFsts = secondRuleFsts
  232 + }
  233 +
223 offlineRecognizer = OfflineRecognizer( 234 offlineRecognizer = OfflineRecognizer(
224 assetManager = application.assets, 235 assetManager = application.assets,
225 config = config, 236 config = config,
@@ -200,12 +200,17 @@ class MainActivity : AppCompatActivity() { @@ -200,12 +200,17 @@ class MainActivity : AppCompatActivity() {
200 // See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html 200 // See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
201 // for a list of available models 201 // for a list of available models
202 val asrModelType = 0 202 val asrModelType = 0
  203 + val asrRuleFsts: String?
  204 + asrRuleFsts = null
203 Log.i(TAG, "Select model type ${asrModelType} for ASR") 205 Log.i(TAG, "Select model type ${asrModelType} for ASR")
204 206
205 val config = OfflineRecognizerConfig( 207 val config = OfflineRecognizerConfig(
206 featConfig = getFeatureConfig(sampleRate = sampleRateInHz, featureDim = 80), 208 featConfig = getFeatureConfig(sampleRate = sampleRateInHz, featureDim = 80),
207 modelConfig = getOfflineModelConfig(type = asrModelType)!!, 209 modelConfig = getOfflineModelConfig(type = asrModelType)!!,
208 ) 210 )
  211 + if (asrRuleFsts != null) {
  212 + config.ruleFsts = asrRuleFsts;
  213 + }
209 214
210 offlineRecognizer = OfflineRecognizer( 215 offlineRecognizer = OfflineRecognizer(
211 assetManager = application.assets, 216 assetManager = application.assets,
@@ -63,37 +63,25 @@ function(download_kaldi_decoder) @@ -63,37 +63,25 @@ function(download_kaldi_decoder)
63 kaldi-decoder-core 63 kaldi-decoder-core
64 kaldifst_core 64 kaldifst_core
65 fst 65 fst
66 - DESTINATION ..)  
67 - if(SHERPA_ONNX_ENABLE_TTS)  
68 - install(TARGETS  
69 fstfar 66 fstfar
70 DESTINATION ..) 67 DESTINATION ..)
71 - endif()  
72 else() 68 else()
73 install(TARGETS 69 install(TARGETS
74 kaldi-decoder-core 70 kaldi-decoder-core
75 kaldifst_core 71 kaldifst_core
76 fst 72 fst
77 - DESTINATION lib)  
78 - if(SHERPA_ONNX_ENABLE_TTS)  
79 - install(TARGETS  
80 fstfar 73 fstfar
81 DESTINATION lib) 74 DESTINATION lib)
82 endif() 75 endif()
83 - endif()  
84 76
85 if(WIN32 AND BUILD_SHARED_LIBS) 77 if(WIN32 AND BUILD_SHARED_LIBS)
86 install(TARGETS 78 install(TARGETS
87 kaldi-decoder-core 79 kaldi-decoder-core
88 kaldifst_core 80 kaldifst_core
89 fst 81 fst
90 - DESTINATION bin)  
91 - if(SHERPA_ONNX_ENABLE_TTS)  
92 - install(TARGETS  
93 fstfar 82 fstfar
94 DESTINATION bin) 83 DESTINATION bin)
95 endif() 84 endif()
96 - endif()  
97 endfunction() 85 endfunction()
98 86
99 download_kaldi_decoder() 87 download_kaldi_decoder()
@@ -10,7 +10,7 @@ environment: @@ -10,7 +10,7 @@ environment:
10 10
11 # Add regular dependencies here. 11 # Add regular dependencies here.
12 dependencies: 12 dependencies:
13 - sherpa_onnx: ^1.9.30 13 + sherpa_onnx: ^1.10.0
14 path: ^1.9.0 14 path: ^1.9.0
15 args: ^2.5.0 15 args: ^2.5.0
16 16
@@ -15,6 +15,7 @@ void main(List<String> arguments) async { @@ -15,6 +15,7 @@ void main(List<String> arguments) async {
15 ..addOption('decoder', help: 'Path to decoder model') 15 ..addOption('decoder', help: 'Path to decoder model')
16 ..addOption('joiner', help: 'Path to joiner model') 16 ..addOption('joiner', help: 'Path to joiner model')
17 ..addOption('tokens', help: 'Path to tokens.txt') 17 ..addOption('tokens', help: 'Path to tokens.txt')
  18 + ..addOption('rule-fsts', help: 'Path to rule fsts', defaultsTo: '')
18 ..addOption('input-wav', help: 'Path to input.wav to transcribe'); 19 ..addOption('input-wav', help: 'Path to input.wav to transcribe');
19 20
20 final res = parser.parse(arguments); 21 final res = parser.parse(arguments);
@@ -31,6 +32,7 @@ void main(List<String> arguments) async { @@ -31,6 +32,7 @@ void main(List<String> arguments) async {
31 final decoder = res['decoder'] as String; 32 final decoder = res['decoder'] as String;
32 final joiner = res['joiner'] as String; 33 final joiner = res['joiner'] as String;
33 final tokens = res['tokens'] as String; 34 final tokens = res['tokens'] as String;
  35 + final ruleFsts = res['rule-fsts'] as String;
34 final inputWav = res['input-wav'] as String; 36 final inputWav = res['input-wav'] as String;
35 37
36 final transducer = sherpa_onnx.OnlineTransducerModelConfig( 38 final transducer = sherpa_onnx.OnlineTransducerModelConfig(
@@ -45,7 +47,10 @@ void main(List<String> arguments) async { @@ -45,7 +47,10 @@ void main(List<String> arguments) async {
45 debug: true, 47 debug: true,
46 numThreads: 1, 48 numThreads: 1,
47 ); 49 );
48 - final config = sherpa_onnx.OnlineRecognizerConfig(model: modelConfig); 50 + final config = sherpa_onnx.OnlineRecognizerConfig(
  51 + model: modelConfig,
  52 + ruleFsts: ruleFsts,
  53 + );
49 final recognizer = sherpa_onnx.OnlineRecognizer(config); 54 final recognizer = sherpa_onnx.OnlineRecognizer(config);
50 55
51 final waveData = sherpa_onnx.readWave(inputWav); 56 final waveData = sherpa_onnx.readWave(inputWav);
@@ -11,7 +11,7 @@ environment: @@ -11,7 +11,7 @@ environment:
11 11
12 # Add regular dependencies here. 12 # Add regular dependencies here.
13 dependencies: 13 dependencies:
14 - sherpa_onnx: ^1.9.30 14 + sherpa_onnx: ^1.10.0
15 path: ^1.9.0 15 path: ^1.9.0
16 args: ^2.5.0 16 args: ^2.5.0
17 17
  1 +#!/usr/bin/env bash
  2 +
  3 +set -ex
  4 +
  5 +dart pub get
  6 +
  7 +if [ ! -f ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt ]; then
  8 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  9 + tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  10 + rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  11 +fi
  12 +
  13 +if [ ! -f ./itn-zh-number.wav ]; then
  14 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
  15 +fi
  16 +
  17 +if [ ! -f ./itn_zh_number.fst ]; then
  18 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  19 +fi
  20 +
  21 +dart run \
  22 + ./bin/zipformer-transducer.dart \
  23 + --encoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.int8.onnx \
  24 + --decoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx \
  25 + --joiner ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.int8.onnx \
  26 + --tokens ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt \
  27 + --rule-fsts ./itn_zh_number.fst \
  28 + --input-wav ./itn-zh-number.wav
@@ -8,7 +8,7 @@ environment: @@ -8,7 +8,7 @@ environment:
8 8
9 # Add regular dependencies here. 9 # Add regular dependencies here.
10 dependencies: 10 dependencies:
11 - sherpa_onnx: ^1.9.30 11 + sherpa_onnx: ^1.10.0
12 path: ^1.9.0 12 path: ^1.9.0
13 args: ^2.5.0 13 args: ^2.5.0
14 14
@@ -9,7 +9,7 @@ environment: @@ -9,7 +9,7 @@ environment:
9 sdk: ^3.4.0 9 sdk: ^3.4.0
10 10
11 dependencies: 11 dependencies:
12 - sherpa_onnx: ^1.9.30 12 + sherpa_onnx: ^1.10.0
13 path: ^1.9.0 13 path: ^1.9.0
14 args: ^2.5.0 14 args: ^2.5.0
15 15
@@ -85,6 +85,10 @@ larger than this value. Used only when --enable-endpoint is true.")] @@ -85,6 +85,10 @@ larger than this value. Used only when --enable-endpoint is true.")]
85 [Option("hotwords-score", Required = false, Default = 1.5F, HelpText = "hotwords score")] 85 [Option("hotwords-score", Required = false, Default = 1.5F, HelpText = "hotwords score")]
86 public float HotwordsScore { get; set; } 86 public float HotwordsScore { get; set; }
87 87
  88 + [Option("rule-fsts", Required = false, Default = "",
  89 + HelpText = "If not empty, path to rule fst for inverse text normalization")]
  90 + public string RuleFsts { get; set; }
  91 +
88 92
89 [Option("files", Required = true, HelpText = "Audio files for decoding")] 93 [Option("files", Required = true, HelpText = "Audio files for decoding")]
90 public IEnumerable<string> Files { get; set; } 94 public IEnumerable<string> Files { get; set; }
@@ -189,6 +193,7 @@ to download pre-trained streaming models. @@ -189,6 +193,7 @@ to download pre-trained streaming models.
189 config.Rule3MinUtteranceLength = options.Rule3MinUtteranceLength; 193 config.Rule3MinUtteranceLength = options.Rule3MinUtteranceLength;
190 config.HotwordsFile = options.HotwordsFile; 194 config.HotwordsFile = options.HotwordsFile;
191 config.HotwordsScore = options.HotwordsScore; 195 config.HotwordsScore = options.HotwordsScore;
  196 + config.RuleFsts = options.RuleFsts;
192 197
193 OnlineRecognizer recognizer = new OnlineRecognizer(config); 198 OnlineRecognizer recognizer = new OnlineRecognizer(config);
194 199
  1 +#!/usr/bin/env bash
  2 +
  3 +# Please refer to
  4 +# https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-transducer/zipformer-transducer-models.html#csukuangfj-sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20-bilingual-chinese-english
  5 +# to download the model files
  6 +
  7 +set -ex
  8 +if [ ! -d ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20 ]; then
  9 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  10 + tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  11 + rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  12 +fi
  13 +
  14 +if [ ! -f ./itn-zh-number.wav ]; then
  15 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
  16 +fi
  17 +
  18 +if [ ! -f ./itn_zh_number.fst ]; then
  19 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  20 +fi
  21 +
  22 +dotnet run -c Release \
  23 + --tokens ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt \
  24 + --encoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.int8.onnx \
  25 + --decoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.int8.onnx \
  26 + --joiner ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.int8.onnx \
  27 + --decoding-method greedy_search \
  28 + --files ./itn-zh-number.wav
@@ -30,6 +30,8 @@ func main() { @@ -30,6 +30,8 @@ func main() {
30 flag.StringVar(&config.ModelConfig.Provider, "provider", "cpu", "Provider to use") 30 flag.StringVar(&config.ModelConfig.Provider, "provider", "cpu", "Provider to use")
31 flag.StringVar(&config.DecodingMethod, "decoding-method", "greedy_search", "Decoding method. Possible values: greedy_search, modified_beam_search") 31 flag.StringVar(&config.DecodingMethod, "decoding-method", "greedy_search", "Decoding method. Possible values: greedy_search, modified_beam_search")
32 flag.IntVar(&config.MaxActivePaths, "max-active-paths", 4, "Used only when --decoding-method is modified_beam_search") 32 flag.IntVar(&config.MaxActivePaths, "max-active-paths", 4, "Used only when --decoding-method is modified_beam_search")
  33 + flag.StringVar(&config.RuleFsts, "rule-fsts", "", "If not empty, path to rule fst for inverse text normalization")
  34 + flag.StringVar(&config.RuleFars, "rule-fars", "", "If not empty, path to rule fst archives for inverse text normalization")
33 35
34 flag.Parse() 36 flag.Parse()
35 37
  1 +#!/usr/bin/env bash
  2 +
  3 +set -ex
  4 +
  5 +if [ ! -f ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt ]; then
  6 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  7 + tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  8 + rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  9 +fi
  10 +
  11 +if [ ! -f ./itn-zh-number.wav ]; then
  12 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
  13 +fi
  14 +
  15 +if [ ! -f ./itn_zh_number.fst ]; then
  16 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  17 +fi
  18 +
  19 +go mod tidy
  20 +go build
  21 +
  22 +./streaming-decode-files \
  23 + --encoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.int8.onnx \
  24 + --decoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx \
  25 + --joiner ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.int8.onnx \
  26 + --tokens ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt \
  27 + --model-type zipformer \
  28 + --rule-fsts ./itn_zh_number.fst \
  29 + --debug 0 \
  30 + ./itn-zh-number.wav
  1 +// Copyright 2024 Xiaomi Corporation
  2 +
  3 +// This file shows how to use a streaming transducer
  4 +// to decode files with inverse text normalization.
  5 +import com.k2fsa.sherpa.onnx.*;
  6 +
  7 +public class InverseTextNormalizationStreamingTransducer {
  8 + public static void main(String[] args) {
  9 + // please refer to
  10 + // https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-transducer/zipformer-transducer-models.html#csukuangfj-sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20-bilingual-chinese-english
  11 + // to download model files
  12 + String encoder =
  13 + "./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.int8.onnx";
  14 + String decoder =
  15 + "./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx";
  16 + String joiner =
  17 + "./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx";
  18 + String tokens = "./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt";
  19 +
  20 + // https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
  21 + String waveFilename = "./itn-zh-number.wav";
  22 +
  23 + // https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  24 + String ruleFsts = "./itn_zh_number.fst";
  25 +
  26 + WaveReader reader = new WaveReader(waveFilename);
  27 +
  28 + OnlineTransducerModelConfig transducer =
  29 + OnlineTransducerModelConfig.builder()
  30 + .setEncoder(encoder)
  31 + .setDecoder(decoder)
  32 + .setJoiner(joiner)
  33 + .build();
  34 +
  35 + OnlineModelConfig modelConfig =
  36 + OnlineModelConfig.builder()
  37 + .setTransducer(transducer)
  38 + .setTokens(tokens)
  39 + .setNumThreads(1)
  40 + .setDebug(true)
  41 + .build();
  42 +
  43 + OnlineRecognizerConfig config =
  44 + OnlineRecognizerConfig.builder()
  45 + .setOnlineModelConfig(modelConfig)
  46 + .setDecodingMethod("greedy_search")
  47 + .setRuleFsts(ruleFsts)
  48 + .build();
  49 +
  50 + OnlineRecognizer recognizer = new OnlineRecognizer(config);
  51 + OnlineStream stream = recognizer.createStream();
  52 + stream.acceptWaveform(reader.getSamples(), reader.getSampleRate());
  53 +
  54 + float[] tailPaddings = new float[(int) (0.8 * reader.getSampleRate())];
  55 + stream.acceptWaveform(tailPaddings, reader.getSampleRate());
  56 +
  57 + while (recognizer.isReady(stream)) {
  58 + recognizer.decode(stream);
  59 + }
  60 +
  61 + String text = recognizer.getResult(stream).getText();
  62 +
  63 + System.out.printf("filename:%s\nresult:%s\n", waveFilename, text);
  64 +
  65 + stream.release();
  66 + recognizer.release();
  67 + }
  68 +}
  1 +#!/usr/bin/env bash
  2 +
  3 +set -ex
  4 +
  5 +if [[ ! -f ../build/lib/libsherpa-onnx-jni.dylib && ! -f ../build/lib/libsherpa-onnx-jni.so ]]; then
  6 + mkdir -p ../build
  7 + pushd ../build
  8 + cmake \
  9 + -DSHERPA_ONNX_ENABLE_PYTHON=OFF \
  10 + -DSHERPA_ONNX_ENABLE_TESTS=OFF \
  11 + -DSHERPA_ONNX_ENABLE_CHECK=OFF \
  12 + -DBUILD_SHARED_LIBS=ON \
  13 + -DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \
  14 + -DSHERPA_ONNX_ENABLE_JNI=ON \
  15 + ..
  16 +
  17 + make -j4
  18 + ls -lh lib
  19 + popd
  20 +fi
  21 +
  22 +if [ ! -f ../sherpa-onnx/java-api/build/sherpa-onnx.jar ]; then
  23 + pushd ../sherpa-onnx/java-api
  24 + make
  25 + popd
  26 +fi
  27 +
  28 +if [ ! -f ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt ]; then
  29 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  30 + tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  31 + rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  32 +fi
  33 +
  34 +if [ ! -f ./itn-zh-number.wav ]; then
  35 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
  36 +fi
  37 +
  38 +if [ ! -f ./itn_zh_number.fst ]; then
  39 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  40 +fi
  41 +
  42 +java \
  43 + -Djava.library.path=$PWD/../build/lib \
  44 + -cp ../sherpa-onnx/java-api/build/sherpa-onnx.jar \
  45 + InverseTextNormalizationStreamingTransducer.java
@@ -203,7 +203,7 @@ function testOfflineAsr() { @@ -203,7 +203,7 @@ function testOfflineAsr() {
203 java -Djava.library.path=../build/lib -jar $out_filename 203 java -Djava.library.path=../build/lib -jar $out_filename
204 } 204 }
205 205
206 -function testInverseTextNormalizationAsr() { 206 +function testInverseTextNormalizationOfflineAsr() {
207 if [ ! -f ./sherpa-onnx-paraformer-zh-2023-03-28/tokens.txt ]; then 207 if [ ! -f ./sherpa-onnx-paraformer-zh-2023-03-28/tokens.txt ]; then
208 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2 208 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
209 tar xvf sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2 209 tar xvf sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
@@ -218,9 +218,9 @@ function testInverseTextNormalizationAsr() { @@ -218,9 +218,9 @@ function testInverseTextNormalizationAsr() {
218 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst 218 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
219 fi 219 fi
220 220
221 - out_filename=test_offline_asr.jar 221 + out_filename=test_itn_offline_asr.jar
222 kotlinc-jvm -include-runtime -d $out_filename \ 222 kotlinc-jvm -include-runtime -d $out_filename \
223 - test_itn_asr.kt \ 223 + test_itn_offline_asr.kt \
224 FeatureConfig.kt \ 224 FeatureConfig.kt \
225 OfflineRecognizer.kt \ 225 OfflineRecognizer.kt \
226 OfflineStream.kt \ 226 OfflineStream.kt \
@@ -231,6 +231,34 @@ function testInverseTextNormalizationAsr() { @@ -231,6 +231,34 @@ function testInverseTextNormalizationAsr() {
231 java -Djava.library.path=../build/lib -jar $out_filename 231 java -Djava.library.path=../build/lib -jar $out_filename
232 } 232 }
233 233
  234 +function testInverseTextNormalizationOnlineAsr() {
  235 + if [ ! -f ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt ]; then
  236 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  237 + tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  238 + rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
  239 + fi
  240 +
  241 + if [ ! -f ./itn-zh-number.wav ]; then
  242 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
  243 + fi
  244 +
  245 + if [ ! -f ./itn_zh_number.fst ]; then
  246 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  247 + fi
  248 +
  249 + out_filename=test_itn_online_asr.jar
  250 + kotlinc-jvm -include-runtime -d $out_filename \
  251 + test_itn_online_asr.kt \
  252 + FeatureConfig.kt \
  253 + OnlineRecognizer.kt \
  254 + OnlineStream.kt \
  255 + WaveReader.kt \
  256 + faked-asset-manager.kt
  257 +
  258 + ls -lh $out_filename
  259 + java -Djava.library.path=../build/lib -jar $out_filename
  260 +}
  261 +
234 function testPunctuation() { 262 function testPunctuation() {
235 if [ ! -f ./sherpa-onnx-punct-ct-transformer-zh-en-vocab272727-2024-04-12/model.onnx ]; then 263 if [ ! -f ./sherpa-onnx-punct-ct-transformer-zh-en-vocab272727-2024-04-12/model.onnx ]; then
236 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/punctuation-models/sherpa-onnx-punct-ct-transformer-zh-en-vocab272727-2024-04-12.tar.bz2 264 curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/punctuation-models/sherpa-onnx-punct-ct-transformer-zh-en-vocab272727-2024-04-12.tar.bz2
@@ -257,4 +285,5 @@ testAudioTagging @@ -257,4 +285,5 @@ testAudioTagging
257 testSpokenLanguageIdentification 285 testSpokenLanguageIdentification
258 testOfflineAsr 286 testOfflineAsr
259 testPunctuation 287 testPunctuation
260 -testInverseTextNormalizationAsr 288 +testInverseTextNormalizationOfflineAsr
  289 +testInverseTextNormalizationOnlineAsr
  1 +package com.k2fsa.sherpa.onnx
  2 +
  3 +fun main() {
  4 + test()
  5 +}
  6 +
  7 +fun test() {
  8 + val recognizer = createOnlineRecognizer()
  9 + val waveFilename = "./itn-zh-number.wav";
  10 +
  11 + val objArray = WaveReader.readWaveFromFile(
  12 + filename = waveFilename,
  13 + )
  14 + val samples: FloatArray = objArray[0] as FloatArray
  15 + val sampleRate: Int = objArray[1] as Int
  16 +
  17 + val stream = recognizer.createStream()
  18 + stream.acceptWaveform(samples, sampleRate=sampleRate)
  19 + while (recognizer.isReady(stream)) {
  20 + recognizer.decode(stream)
  21 + }
  22 +
  23 + val result = recognizer.getResult(stream).text
  24 + println(result)
  25 +
  26 + stream.release()
  27 + recognizer.release()
  28 +}
  29 +
  30 +fun createOnlineRecognizer(): OnlineRecognizer {
  31 + val config = OnlineRecognizerConfig(
  32 + featConfig = getFeatureConfig(sampleRate = 16000, featureDim = 80),
  33 + modelConfig = getModelConfig(8)!!,
  34 + )
  35 +
  36 + config.ruleFsts = "./itn_zh_number.fst"
  37 + println(config)
  38 +
  39 + return OnlineRecognizer(config = config)
  40 +}
  41 +
1 { 1 {
2 "dependencies": { 2 "dependencies": {
3 - "sherpa-onnx-node": "^1.9.30" 3 + "sherpa-onnx-node": "^1.10.0"
4 } 4 }
5 } 5 }
  1 +// Copyright (c) 2024 Xiaomi Corporation
  2 +const sherpa_onnx = require('sherpa-onnx-node');
  3 +
  4 +// Please download test files from
  5 +// https://github.com/k2-fsa/sherpa-onnx/releases/tag/asr-models
  6 +const config = {
  7 + 'featConfig': {
  8 + 'sampleRate': 16000,
  9 + 'featureDim': 80,
  10 + },
  11 + 'modelConfig': {
  12 + 'transducer': {
  13 + 'encoder':
  14 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx',
  15 + 'decoder':
  16 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx',
  17 + 'joiner':
  18 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx',
  19 + },
  20 + 'tokens':
  21 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt',
  22 + 'numThreads': 2,
  23 + 'provider': 'cpu',
  24 + 'debug': 1,
  25 + },
  26 + // https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  27 + ruleFsts: './itn_zh_number.fst',
  28 +};
  29 +
  30 +// https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
  31 +const waveFilename = './itn-zh-number.wav';
  32 +
  33 +const recognizer = new sherpa_onnx.OnlineRecognizer(config);
  34 +console.log('Started')
  35 +let start = Date.now();
  36 +const stream = recognizer.createStream();
  37 +const wave = sherpa_onnx.readWave(waveFilename);
  38 +stream.acceptWaveform({sampleRate: wave.sampleRate, samples: wave.samples});
  39 +
  40 +const tailPadding = new Float32Array(wave.sampleRate * 0.4);
  41 +stream.acceptWaveform({samples: tailPadding, sampleRate: wave.sampleRate});
  42 +
  43 +while (recognizer.isReady(stream)) {
  44 + recognizer.decode(stream);
  45 +}
  46 +result = recognizer.getResult(stream)
  47 +let stop = Date.now();
  48 +console.log('Done')
  49 +
  50 +const elapsed_seconds = (stop - start) / 1000;
  51 +const duration = wave.samples.length / wave.sampleRate;
  52 +const real_time_factor = elapsed_seconds / duration;
  53 +console.log('Wave duration', duration.toFixed(3), 'secodns')
  54 +console.log('Elapsed', elapsed_seconds.toFixed(3), 'secodns')
  55 +console.log(
  56 + `RTF = ${elapsed_seconds.toFixed(3)}/${duration.toFixed(3)} =`,
  57 + real_time_factor.toFixed(3))
  58 +console.log(waveFilename)
  59 +console.log('result\n', result)
  1 +// Copyright (c) 2023-2024 Xiaomi Corporation (authors: Fangjun Kuang)
  2 +//
  3 +const portAudio = require('naudiodon2');
  4 +// console.log(portAudio.getDevices());
  5 +
  6 +const sherpa_onnx = require('sherpa-onnx-node');
  7 +
  8 +function createOnlineRecognizer() {
  9 + const config = {
  10 + 'featConfig': {
  11 + 'sampleRate': 16000,
  12 + 'featureDim': 80,
  13 + },
  14 + 'modelConfig': {
  15 + 'transducer': {
  16 + 'encoder':
  17 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx',
  18 + 'decoder':
  19 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx',
  20 + 'joiner':
  21 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx',
  22 + },
  23 + 'tokens':
  24 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt',
  25 + 'numThreads': 2,
  26 + 'provider': 'cpu',
  27 + 'debug': 1,
  28 + },
  29 + 'decodingMethod': 'greedy_search',
  30 + 'maxActivePaths': 4,
  31 + 'enableEndpoint': true,
  32 + 'rule1MinTrailingSilence': 2.4,
  33 + 'rule2MinTrailingSilence': 1.2,
  34 + 'rule3MinUtteranceLength': 20,
  35 + // https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  36 + ruleFsts: './itn_zh_number.fst',
  37 + };
  38 +
  39 + return new sherpa_onnx.OnlineRecognizer(config);
  40 +}
  41 +
  42 +const recognizer = createOnlineRecognizer();
  43 +const stream = recognizer.createStream();
  44 +
  45 +let lastText = '';
  46 +let segmentIndex = 0;
  47 +
  48 +const ai = new portAudio.AudioIO({
  49 + inOptions: {
  50 + channelCount: 1,
  51 + closeOnError: true, // Close the stream if an audio error is detected, if
  52 + // set false then just log the error
  53 + deviceId: -1, // Use -1 or omit the deviceId to select the default device
  54 + sampleFormat: portAudio.SampleFormatFloat32,
  55 + sampleRate: recognizer.config.featConfig.sampleRate
  56 + }
  57 +});
  58 +
  59 +const display = new sherpa_onnx.Display(50);
  60 +
  61 +ai.on('data', data => {
  62 + const samples = new Float32Array(data.buffer);
  63 +
  64 + stream.acceptWaveform(
  65 + {sampleRate: recognizer.config.featConfig.sampleRate, samples: samples});
  66 +
  67 + while (recognizer.isReady(stream)) {
  68 + recognizer.decode(stream);
  69 + }
  70 +
  71 + const isEndpoint = recognizer.isEndpoint(stream);
  72 + const text = recognizer.getResult(stream).text.toLowerCase();
  73 +
  74 + if (text.length > 0 && lastText != text) {
  75 + lastText = text;
  76 + display.print(segmentIndex, lastText);
  77 + }
  78 + if (isEndpoint) {
  79 + if (text.length > 0) {
  80 + lastText = text;
  81 + segmentIndex += 1;
  82 + }
  83 + recognizer.reset(stream)
  84 + }
  85 +});
  86 +
  87 +ai.start();
  88 +console.log('Started! Please speak')
  1 +// Copyright (c) 2023 Xiaomi Corporation (authors: Fangjun Kuang)
  2 +//
  3 +const fs = require('fs');
  4 +const {Readable} = require('stream');
  5 +const wav = require('wav');
  6 +
  7 +const sherpa_onnx = require('sherpa-onnx');
  8 +
  9 +function createOnlineRecognizer() {
  10 + let onlineTransducerModelConfig = {
  11 + encoder:
  12 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.int8.onnx',
  13 + decoder:
  14 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx',
  15 + joiner:
  16 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.int8.onnx',
  17 + };
  18 +
  19 + let onlineParaformerModelConfig = {
  20 + encoder: '',
  21 + decoder: '',
  22 + };
  23 +
  24 + let onlineZipformer2CtcModelConfig = {
  25 + model: '',
  26 + };
  27 +
  28 + let onlineModelConfig = {
  29 + transducer: onlineTransducerModelConfig,
  30 + paraformer: onlineParaformerModelConfig,
  31 + zipformer2Ctc: onlineZipformer2CtcModelConfig,
  32 + tokens:
  33 + './sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt',
  34 + numThreads: 1,
  35 + provider: 'cpu',
  36 + debug: 1,
  37 + modelType: 'zipformer',
  38 + };
  39 +
  40 + let featureConfig = {
  41 + sampleRate: 16000,
  42 + featureDim: 80,
  43 + };
  44 +
  45 + let recognizerConfig = {
  46 + featConfig: featureConfig,
  47 + modelConfig: onlineModelConfig,
  48 + decodingMethod: 'greedy_search',
  49 + maxActivePaths: 4,
  50 + enableEndpoint: 1,
  51 + rule1MinTrailingSilence: 2.4,
  52 + rule2MinTrailingSilence: 1.2,
  53 + rule3MinUtteranceLength: 20,
  54 + hotwordsFile: '',
  55 + hotwordsScore: 1.5,
  56 + ctcFstDecoderConfig: {
  57 + graph: '',
  58 + maxActive: 3000,
  59 + },
  60 + // https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  61 + ruleFsts: './itn_zh_number.fst',
  62 + };
  63 +
  64 + return sherpa_onnx.createOnlineRecognizer(recognizerConfig);
  65 +}
  66 +
  67 +const recognizer = createOnlineRecognizer();
  68 +const stream = recognizer.createStream();
  69 +
  70 +// https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
  71 +const waveFilename = './itn-zh-number.wav';
  72 +
  73 +const reader = new wav.Reader();
  74 +const readable = new Readable().wrap(reader);
  75 +
  76 +function decode(samples) {
  77 + stream.acceptWaveform(recognizer.config.featConfig.sampleRate, samples);
  78 +
  79 + while (recognizer.isReady(stream)) {
  80 + recognizer.decode(stream);
  81 + }
  82 + const text = recognizer.getResult(stream).text;
  83 + console.log(text);
  84 +}
  85 +
  86 +reader.on('format', ({audioFormat, bitDepth, channels, sampleRate}) => {
  87 + if (sampleRate != recognizer.config.featConfig.sampleRate) {
  88 + throw new Error(`Only support sampleRate ${
  89 + recognizer.config.featConfig.sampleRate}. Given ${sampleRate}`);
  90 + }
  91 +
  92 + if (audioFormat != 1) {
  93 + throw new Error(`Only support PCM format. Given ${audioFormat}`);
  94 + }
  95 +
  96 + if (channels != 1) {
  97 + throw new Error(`Only a single channel. Given ${channel}`);
  98 + }
  99 +
  100 + if (bitDepth != 16) {
  101 + throw new Error(`Only support 16-bit samples. Given ${bitDepth}`);
  102 + }
  103 +});
  104 +
  105 +fs.createReadStream(waveFilename, {'highWaterMark': 4096})
  106 + .pipe(reader)
  107 + .on('finish', function(err) {
  108 + // tail padding
  109 + const floatSamples =
  110 + new Float32Array(recognizer.config.featConfig.sampleRate * 0.5);
  111 + decode(floatSamples);
  112 + stream.free();
  113 + recognizer.free();
  114 + });
  115 +
  116 +readable.on('readable', function() {
  117 + let chunk;
  118 + while ((chunk = readable.read()) != null) {
  119 + const int16Samples = new Int16Array(
  120 + chunk.buffer, chunk.byteOffset,
  121 + chunk.length / Int16Array.BYTES_PER_ELEMENT);
  122 +
  123 + const floatSamples = new Float32Array(int16Samples.length);
  124 +
  125 + for (let i = 0; i < floatSamples.length; i++) {
  126 + floatSamples[i] = int16Samples[i] / 32768.0;
  127 + }
  128 +
  129 + decode(floatSamples);
  130 + }
  131 +});
@@ -71,6 +71,17 @@ git checkout . @@ -71,6 +71,17 @@ git checkout .
71 pushd android/SherpaOnnx2Pass/app/src/main/java/com/k2fsa/sherpa/onnx 71 pushd android/SherpaOnnx2Pass/app/src/main/java/com/k2fsa/sherpa/onnx
72 sed -i.bak s/"firstType = 9/firstType = $type1/" ./MainActivity.kt 72 sed -i.bak s/"firstType = 9/firstType = $type1/" ./MainActivity.kt
73 sed -i.bak s/"secondType = 0/secondType = $type2/" ./MainActivity.kt 73 sed -i.bak s/"secondType = 0/secondType = $type2/" ./MainActivity.kt
  74 +
  75 +{% if first.rule_fsts %}
  76 + rule_fsts={{ first.rule_fsts }}
  77 + sed -i.bak s%"firstRuleFsts = null"%"firstRuleFsts = \"$rule_fsts\""% ./MainActivity.kt
  78 +{% endif %}
  79 +
  80 +{% if second.rule_fsts %}
  81 + rule_fsts={{ second.rule_fsts }}
  82 + sed -i.bak s%"secondRuleFsts = null"%"secondRuleFsts = \"$rule_fsts\""% ./MainActivity.kt
  83 +{% endif %}
  84 +
74 git diff 85 git diff
75 popd 86 popd
76 87
@@ -54,6 +54,12 @@ popd @@ -54,6 +54,12 @@ popd
54 git checkout . 54 git checkout .
55 pushd android/SherpaOnnx/app/src/main/java/com/k2fsa/sherpa/onnx 55 pushd android/SherpaOnnx/app/src/main/java/com/k2fsa/sherpa/onnx
56 sed -i.bak s/"type = 0/type = $type/" ./MainActivity.kt 56 sed -i.bak s/"type = 0/type = $type/" ./MainActivity.kt
  57 +
  58 +{% if model.rule_fsts %}
  59 + rule_fsts={{ model.rule_fsts }}
  60 + sed -i.bak s%"ruleFsts = null"%"ruleFsts = \"$rule_fsts\""% ./MainActivity.kt
  61 +{% endif %}
  62 +
57 git diff 63 git diff
58 popd 64 popd
59 65
@@ -84,6 +90,7 @@ for arch in arm64-v8a armeabi-v7a x86_64 x86; do @@ -84,6 +90,7 @@ for arch in arm64-v8a armeabi-v7a x86_64 x86; do
84 done 90 done
85 91
86 rm -rf ./android/SherpaOnnx/app/src/main/assets/$model_name 92 rm -rf ./android/SherpaOnnx/app/src/main/assets/$model_name
  93 +rm -rf ./android/SherpaOnnx/app/src/main/assets/*.fst
87 {% endfor %} 94 {% endfor %}
88 95
89 git checkout . 96 git checkout .
@@ -56,6 +56,12 @@ popd @@ -56,6 +56,12 @@ popd
56 git checkout . 56 git checkout .
57 pushd android/SherpaOnnxVadAsr/app/src/main/java/com/k2fsa/sherpa/onnx 57 pushd android/SherpaOnnxVadAsr/app/src/main/java/com/k2fsa/sherpa/onnx
58 sed -i.bak s/"asrModelType = 0/asrModelType = $type/" ./MainActivity.kt 58 sed -i.bak s/"asrModelType = 0/asrModelType = $type/" ./MainActivity.kt
  59 +
  60 +{% if model.rule_fsts %}
  61 + rule_fsts={{ model.rule_fsts }}
  62 + sed -i.bak s%"asrRuleFsts = null"%"asrRuleFsts = \"$rule_fsts\""% ./MainActivity.kt
  63 +{% endif %}
  64 +
59 git diff 65 git diff
60 popd 66 popd
61 67
@@ -41,6 +41,7 @@ class Model: @@ -41,6 +41,7 @@ class Model:
41 41
42 # cmd is used to remove extra file from the model directory 42 # cmd is used to remove extra file from the model directory
43 cmd: str = "" 43 cmd: str = ""
  44 + rule_fsts: str = ""
44 45
45 46
46 def get_2nd_models(): 47 def get_2nd_models():
@@ -70,7 +71,11 @@ def get_2nd_models(): @@ -70,7 +71,11 @@ def get_2nd_models():
70 idx=0, 71 idx=0,
71 lang="zh", 72 lang="zh",
72 short_name="paraformer", 73 short_name="paraformer",
  74 + rule_fsts="itn_zh_number.fst",
73 cmd=""" 75 cmd="""
  76 + if [ ! -f itn_zh_number.fst ]; then
  77 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  78 + fi
74 pushd $model_name 79 pushd $model_name
75 80
76 rm -fv README.md 81 rm -fv README.md
@@ -87,7 +92,11 @@ def get_2nd_models(): @@ -87,7 +92,11 @@ def get_2nd_models():
87 idx=4, 92 idx=4,
88 lang="zh", 93 lang="zh",
89 short_name="zipformer", 94 short_name="zipformer",
  95 + rule_fsts="itn_zh_number.fst",
90 cmd=""" 96 cmd="""
  97 + if [ ! -f itn_zh_number.fst ]; then
  98 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  99 + fi
91 pushd $model_name 100 pushd $model_name
92 101
93 rm -rfv test_wavs 102 rm -rfv test_wavs
@@ -117,7 +126,11 @@ def get_1st_models(): @@ -117,7 +126,11 @@ def get_1st_models():
117 idx=8, 126 idx=8,
118 lang="bilingual_zh_en", 127 lang="bilingual_zh_en",
119 short_name="zipformer", 128 short_name="zipformer",
  129 + rule_fsts="itn_zh_number.fst",
120 cmd=""" 130 cmd="""
  131 + if [ ! -f itn_zh_number.fst ]; then
  132 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  133 + fi
121 pushd $model_name 134 pushd $model_name
122 rm -fv decoder-epoch-99-avg-1.int8.onnx 135 rm -fv decoder-epoch-99-avg-1.int8.onnx
123 rm -fv encoder-epoch-99-avg-1.onnx 136 rm -fv encoder-epoch-99-avg-1.onnx
@@ -160,7 +173,11 @@ def get_1st_models(): @@ -160,7 +173,11 @@ def get_1st_models():
160 idx=3, 173 idx=3,
161 lang="zh", 174 lang="zh",
162 short_name="zipformer2", 175 short_name="zipformer2",
  176 + rule_fsts="itn_zh_number.fst",
163 cmd=""" 177 cmd="""
  178 + if [ ! -f itn_zh_number.fst ]; then
  179 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  180 + fi
164 pushd $model_name 181 pushd $model_name
165 rm -fv exp/encoder-epoch-12-avg-4-chunk-16-left-128.onnx 182 rm -fv exp/encoder-epoch-12-avg-4-chunk-16-left-128.onnx
166 rm -fv exp/decoder-epoch-12-avg-4-chunk-16-left-128.int8.onnx 183 rm -fv exp/decoder-epoch-12-avg-4-chunk-16-left-128.int8.onnx
@@ -202,7 +219,11 @@ def get_1st_models(): @@ -202,7 +219,11 @@ def get_1st_models():
202 idx=9, 219 idx=9,
203 lang="zh", 220 lang="zh",
204 short_name="small_zipformer", 221 short_name="small_zipformer",
  222 + rule_fsts="itn_zh_number.fst",
205 cmd=""" 223 cmd="""
  224 + if [ ! -f itn_zh_number.fst ]; then
  225 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  226 + fi
206 pushd $model_name 227 pushd $model_name
207 rm -fv encoder-epoch-99-avg-1.onnx 228 rm -fv encoder-epoch-99-avg-1.onnx
208 rm -fv decoder-epoch-99-avg-1.int8.onnx 229 rm -fv decoder-epoch-99-avg-1.int8.onnx
@@ -42,6 +42,8 @@ class Model: @@ -42,6 +42,8 @@ class Model:
42 # cmd is used to remove extra file from the model directory 42 # cmd is used to remove extra file from the model directory
43 cmd: str = "" 43 cmd: str = ""
44 44
  45 + rule_fsts: str = ""
  46 +
45 47
46 def get_models(): 48 def get_models():
47 models = [ 49 models = [
@@ -50,7 +52,11 @@ def get_models(): @@ -50,7 +52,11 @@ def get_models():
50 idx=8, 52 idx=8,
51 lang="bilingual_zh_en", 53 lang="bilingual_zh_en",
52 short_name="zipformer", 54 short_name="zipformer",
  55 + rule_fsts="itn_zh_number.fst",
53 cmd=""" 56 cmd="""
  57 + if [ ! -f itn_zh_number.fst ]; then
  58 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  59 + fi
54 pushd $model_name 60 pushd $model_name
55 rm -fv decoder-epoch-99-avg-1.int8.onnx 61 rm -fv decoder-epoch-99-avg-1.int8.onnx
56 rm -fv encoder-epoch-99-avg-1.onnx 62 rm -fv encoder-epoch-99-avg-1.onnx
@@ -93,7 +99,11 @@ def get_models(): @@ -93,7 +99,11 @@ def get_models():
93 idx=3, 99 idx=3,
94 lang="zh", 100 lang="zh",
95 short_name="zipformer2", 101 short_name="zipformer2",
  102 + rule_fsts="itn_zh_number.fst",
96 cmd=""" 103 cmd="""
  104 + if [ ! -f itn_zh_number.fst ]; then
  105 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  106 + fi
97 pushd $model_name 107 pushd $model_name
98 rm -fv exp/encoder-epoch-12-avg-4-chunk-16-left-128.onnx 108 rm -fv exp/encoder-epoch-12-avg-4-chunk-16-left-128.onnx
99 rm -fv exp/decoder-epoch-12-avg-4-chunk-16-left-128.int8.onnx 109 rm -fv exp/decoder-epoch-12-avg-4-chunk-16-left-128.int8.onnx
@@ -135,7 +145,11 @@ def get_models(): @@ -135,7 +145,11 @@ def get_models():
135 idx=9, 145 idx=9,
136 lang="zh", 146 lang="zh",
137 short_name="small_zipformer", 147 short_name="small_zipformer",
  148 + rule_fsts="itn_zh_number.fst",
138 cmd=""" 149 cmd="""
  150 + if [ ! -f itn_zh_number.fst ]; then
  151 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  152 + fi
139 pushd $model_name 153 pushd $model_name
140 rm -fv encoder-epoch-99-avg-1.onnx 154 rm -fv encoder-epoch-99-avg-1.onnx
141 rm -fv decoder-epoch-99-avg-1.int8.onnx 155 rm -fv decoder-epoch-99-avg-1.int8.onnx
@@ -42,6 +42,8 @@ class Model: @@ -42,6 +42,8 @@ class Model:
42 # cmd is used to remove extra file from the model directory 42 # cmd is used to remove extra file from the model directory
43 cmd: str = "" 43 cmd: str = ""
44 44
  45 + rule_fsts: str = ""
  46 +
45 47
46 # See get_2nd_models() in ./generate-asr-2pass-apk-script.py 48 # See get_2nd_models() in ./generate-asr-2pass-apk-script.py
47 def get_models(): 49 def get_models():
@@ -71,7 +73,11 @@ def get_models(): @@ -71,7 +73,11 @@ def get_models():
71 idx=0, 73 idx=0,
72 lang="zh", 74 lang="zh",
73 short_name="paraformer", 75 short_name="paraformer",
  76 + rule_fsts="itn_zh_number.fst",
74 cmd=""" 77 cmd="""
  78 + if [ ! -f itn_zh_number.fst ]; then
  79 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  80 + fi
75 pushd $model_name 81 pushd $model_name
76 82
77 rm -v README.md 83 rm -v README.md
@@ -88,7 +94,11 @@ def get_models(): @@ -88,7 +94,11 @@ def get_models():
88 idx=4, 94 idx=4,
89 lang="zh", 95 lang="zh",
90 short_name="zipformer", 96 short_name="zipformer",
  97 + rule_fsts="itn_zh_number.fst",
91 cmd=""" 98 cmd="""
  99 + if [ ! -f itn_zh_number.fst ]; then
  100 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  101 + fi
92 pushd $model_name 102 pushd $model_name
93 103
94 rm -rfv test_wavs 104 rm -rfv test_wavs
@@ -171,7 +181,11 @@ def get_models(): @@ -171,7 +181,11 @@ def get_models():
171 idx=11, 181 idx=11,
172 lang="zh", 182 lang="zh",
173 short_name="telespeech", 183 short_name="telespeech",
  184 + rule_fsts="itn_zh_number.fst",
174 cmd=""" 185 cmd="""
  186 + if [ ! -f itn_zh_number.fst ]; then
  187 + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
  188 + fi
175 pushd $model_name 189 pushd $model_name
176 190
177 rm -rfv test_wavs 191 rm -rfv test_wavs
@@ -26,6 +26,8 @@ namespace SherpaOnnx @@ -26,6 +26,8 @@ namespace SherpaOnnx
26 HotwordsFile = ""; 26 HotwordsFile = "";
27 HotwordsScore = 1.5F; 27 HotwordsScore = 1.5F;
28 CtcFstDecoderConfig = new OnlineCtcFstDecoderConfig(); 28 CtcFstDecoderConfig = new OnlineCtcFstDecoderConfig();
  29 + RuleFsts = "";
  30 + RuleFars = "";
29 } 31 }
30 public FeatureConfig FeatConfig; 32 public FeatureConfig FeatConfig;
31 public OnlineModelConfig ModelConfig; 33 public OnlineModelConfig ModelConfig;
@@ -64,5 +66,11 @@ namespace SherpaOnnx @@ -64,5 +66,11 @@ namespace SherpaOnnx
64 public float HotwordsScore; 66 public float HotwordsScore;
65 67
66 public OnlineCtcFstDecoderConfig CtcFstDecoderConfig; 68 public OnlineCtcFstDecoderConfig CtcFstDecoderConfig;
  69 +
  70 + [MarshalAs(UnmanagedType.LPStr)]
  71 + public string RuleFsts;
  72 +
  73 + [MarshalAs(UnmanagedType.LPStr)]
  74 + public string RuleFars;
67 } 75 }
68 } 76 }
  1 +../../../../go-api-examples/streaming-decode-files/run-transducer-itn.sh
@@ -79,8 +79,8 @@ function osx() { @@ -79,8 +79,8 @@ function osx() {
79 79
80 mkdir t 80 mkdir t
81 cd t 81 cd t
82 - wget -q https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_11_0_x86_64.whl  
83 - unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_11_0_x86_64.whl 82 + wget -q https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp39-cp39-macosx_11_0_x86_64.whl
  83 + unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp39-cp39-macosx_11_0_x86_64.whl
84 84
85 cp -v sherpa_onnx/lib/*.dylib $dst/ 85 cp -v sherpa_onnx/lib/*.dylib $dst/
86 86
@@ -93,8 +93,8 @@ function osx() { @@ -93,8 +93,8 @@ function osx() {
93 93
94 mkdir t 94 mkdir t
95 cd t 95 cd t
96 - wget -q https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_11_0_arm64.whl  
97 - unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_11_0_arm64.whl 96 + wget -q https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp39-cp39-macosx_11_0_arm64.whl
  97 + unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp39-cp39-macosx_11_0_arm64.whl
98 98
99 cp -v sherpa_onnx/lib/*.dylib $dst/ 99 cp -v sherpa_onnx/lib/*.dylib $dst/
100 100
@@ -126,7 +126,6 @@ function windows() { @@ -126,7 +126,6 @@ function windows() {
126 unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win_amd64.whl 126 unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win_amd64.whl
127 127
128 cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.dll $dst 128 cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.dll $dst
129 - cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.lib $dst  
130 129
131 cd .. 130 cd ..
132 rm -rf t 131 rm -rf t
@@ -139,7 +138,6 @@ function windows() { @@ -139,7 +138,6 @@ function windows() {
139 unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win32.whl 138 unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win32.whl
140 139
141 cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.dll $dst 140 cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.dll $dst
142 - cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.lib $dst  
143 141
144 cd .. 142 cd ..
145 rm -rf t 143 rm -rf t
@@ -127,7 +127,11 @@ type OnlineRecognizerConfig struct { @@ -127,7 +127,11 @@ type OnlineRecognizerConfig struct {
127 Rule1MinTrailingSilence float32 127 Rule1MinTrailingSilence float32
128 Rule2MinTrailingSilence float32 128 Rule2MinTrailingSilence float32
129 Rule3MinUtteranceLength float32 129 Rule3MinUtteranceLength float32
  130 + HotwordsFile string
  131 + HotwordsScore float32
130 CtcFstDecoderConfig OnlineCtcFstDecoderConfig 132 CtcFstDecoderConfig OnlineCtcFstDecoderConfig
  133 + RuleFsts string
  134 + RuleFars string
131 } 135 }
132 136
133 // It contains the recognition result for a online stream. 137 // It contains the recognition result for a online stream.
@@ -204,6 +208,17 @@ func NewOnlineRecognizer(config *OnlineRecognizerConfig) *OnlineRecognizer { @@ -204,6 +208,17 @@ func NewOnlineRecognizer(config *OnlineRecognizerConfig) *OnlineRecognizer {
204 c.rule2_min_trailing_silence = C.float(config.Rule2MinTrailingSilence) 208 c.rule2_min_trailing_silence = C.float(config.Rule2MinTrailingSilence)
205 c.rule3_min_utterance_length = C.float(config.Rule3MinUtteranceLength) 209 c.rule3_min_utterance_length = C.float(config.Rule3MinUtteranceLength)
206 210
  211 + c.hotwords_file = C.CString(config.HotwordsFile)
  212 + defer C.free(unsafe.Pointer(c.hotwords_file))
  213 +
  214 + c.hotwords_score = C.float(config.HotwordsScore)
  215 +
  216 + c.rule_fsts = C.CString(config.RuleFsts)
  217 + defer C.free(unsafe.Pointer(c.rule_fsts))
  218 +
  219 + c.rule_fars = C.CString(config.RuleFars)
  220 + defer C.free(unsafe.Pointer(c.rule_fars))
  221 +
207 c.ctc_fst_decoder_config.graph = C.CString(config.CtcFstDecoderConfig.Graph) 222 c.ctc_fst_decoder_config.graph = C.CString(config.CtcFstDecoderConfig.Graph)
208 defer C.free(unsafe.Pointer(c.ctc_fst_decoder_config.graph)) 223 defer C.free(unsafe.Pointer(c.ctc_fst_decoder_config.graph))
209 c.ctc_fst_decoder_config.max_active = C.int(config.CtcFstDecoderConfig.MaxActive) 224 c.ctc_fst_decoder_config.max_active = C.int(config.CtcFstDecoderConfig.MaxActive)
@@ -189,6 +189,8 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( @@ -189,6 +189,8 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper(
189 rule3MinUtteranceLength); 189 rule3MinUtteranceLength);
190 SHERPA_ONNX_ASSIGN_ATTR_STR(hotwords_file, hotwordsFile); 190 SHERPA_ONNX_ASSIGN_ATTR_STR(hotwords_file, hotwordsFile);
191 SHERPA_ONNX_ASSIGN_ATTR_FLOAT(hotwords_score, hotwordsScore); 191 SHERPA_ONNX_ASSIGN_ATTR_FLOAT(hotwords_score, hotwordsScore);
  192 + SHERPA_ONNX_ASSIGN_ATTR_STR(rule_fsts, ruleFsts);
  193 + SHERPA_ONNX_ASSIGN_ATTR_STR(rule_fars, ruleFars);
192 194
193 c.ctc_fst_decoder_config = GetCtcFstDecoderConfig(o); 195 c.ctc_fst_decoder_config = GetCtcFstDecoderConfig(o);
194 196
@@ -246,6 +248,14 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( @@ -246,6 +248,14 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper(
246 delete[] c.hotwords_file; 248 delete[] c.hotwords_file;
247 } 249 }
248 250
  251 + if (c.rule_fsts) {
  252 + delete[] c.rule_fsts;
  253 + }
  254 +
  255 + if (c.rule_fars) {
  256 + delete[] c.rule_fars;
  257 + }
  258 +
249 if (c.ctc_fst_decoder_config.graph) { 259 if (c.ctc_fst_decoder_config.graph) {
250 delete[] c.ctc_fst_decoder_config.graph; 260 delete[] c.ctc_fst_decoder_config.graph;
251 } 261 }
@@ -110,6 +110,9 @@ SherpaOnnxOnlineRecognizer *CreateOnlineRecognizer( @@ -110,6 +110,9 @@ SherpaOnnxOnlineRecognizer *CreateOnlineRecognizer(
110 recognizer_config.ctc_fst_decoder_config.max_active = 110 recognizer_config.ctc_fst_decoder_config.max_active =
111 SHERPA_ONNX_OR(config->ctc_fst_decoder_config.max_active, 3000); 111 SHERPA_ONNX_OR(config->ctc_fst_decoder_config.max_active, 3000);
112 112
  113 + recognizer_config.rule_fsts = SHERPA_ONNX_OR(config->rule_fsts, "");
  114 + recognizer_config.rule_fars = SHERPA_ONNX_OR(config->rule_fars, "");
  115 +
113 if (config->model_config.debug) { 116 if (config->model_config.debug) {
114 SHERPA_ONNX_LOGE("%s\n", recognizer_config.ToString().c_str()); 117 SHERPA_ONNX_LOGE("%s\n", recognizer_config.ToString().c_str());
115 } 118 }
@@ -144,6 +144,8 @@ SHERPA_ONNX_API typedef struct SherpaOnnxOnlineRecognizerConfig { @@ -144,6 +144,8 @@ SHERPA_ONNX_API typedef struct SherpaOnnxOnlineRecognizerConfig {
144 float hotwords_score; 144 float hotwords_score;
145 145
146 SherpaOnnxOnlineCtcFstDecoderConfig ctc_fst_decoder_config; 146 SherpaOnnxOnlineCtcFstDecoderConfig ctc_fst_decoder_config;
  147 + const char *rule_fsts;
  148 + const char *rule_fars;
147 } SherpaOnnxOnlineRecognizerConfig; 149 } SherpaOnnxOnlineRecognizerConfig;
148 150
149 SHERPA_ONNX_API typedef struct SherpaOnnxOnlineRecognizerResult { 151 SHERPA_ONNX_API typedef struct SherpaOnnxOnlineRecognizerResult {
@@ -190,9 +190,10 @@ if(NOT BUILD_SHARED_LIBS AND APPLE) @@ -190,9 +190,10 @@ if(NOT BUILD_SHARED_LIBS AND APPLE)
190 target_link_libraries(sherpa-onnx-core "-framework Foundation") 190 target_link_libraries(sherpa-onnx-core "-framework Foundation")
191 endif() 191 endif()
192 192
  193 +target_link_libraries(sherpa-onnx-core fstfar fst)
  194 +
193 if(SHERPA_ONNX_ENABLE_TTS) 195 if(SHERPA_ONNX_ENABLE_TTS)
194 target_link_libraries(sherpa-onnx-core piper_phonemize) 196 target_link_libraries(sherpa-onnx-core piper_phonemize)
195 - target_link_libraries(sherpa-onnx-core fstfar fst)  
196 target_link_libraries(sherpa-onnx-core cppjieba) 197 target_link_libraries(sherpa-onnx-core cppjieba)
197 endif() 198 endif()
198 199
@@ -425,9 +425,6 @@ std::string OfflineRecognizerImpl::ApplyInverseTextNormalization( @@ -425,9 +425,6 @@ std::string OfflineRecognizerImpl::ApplyInverseTextNormalization(
425 if (!itn_list_.empty()) { 425 if (!itn_list_.empty()) {
426 for (const auto &tn : itn_list_) { 426 for (const auto &tn : itn_list_) {
427 text = tn->Normalize(text); 427 text = tn->Normalize(text);
428 - if (config_.model_config.debug) {  
429 - SHERPA_ONNX_LOGE("After inverse text normalization: %s", text.c_str());  
430 - }  
431 } 428 }
432 } 429 }
433 430
@@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
4 4
5 #include "sherpa-onnx/csrc/online-recognizer-impl.h" 5 #include "sherpa-onnx/csrc/online-recognizer-impl.h"
6 6
  7 +#include <utility>
  8 +
7 #if __ANDROID_API__ >= 9 9 #if __ANDROID_API__ >= 9
8 #include <strstream> 10 #include <strstream>
9 11
@@ -186,9 +188,6 @@ std::string OnlineRecognizerImpl::ApplyInverseTextNormalization( @@ -186,9 +188,6 @@ std::string OnlineRecognizerImpl::ApplyInverseTextNormalization(
186 if (!itn_list_.empty()) { 188 if (!itn_list_.empty()) {
187 for (const auto &tn : itn_list_) { 189 for (const auto &tn : itn_list_) {
188 text = tn->Normalize(text); 190 text = tn->Normalize(text);
189 - if (config_.model_config.debug) {  
190 - SHERPA_ONNX_LOGE("After inverse text normalization: %s", text.c_str());  
191 - }  
192 } 191 }
193 } 192 }
194 193
  1 +## 1.10.0
  2 +
  3 +* Add inverse text normalization
  4 +
1 ## 1.9.30 5 ## 1.9.30
2 6
3 * Add TTS 7 * Add TTS
@@ -111,11 +111,13 @@ class OnlineRecognizerConfig { @@ -111,11 +111,13 @@ class OnlineRecognizerConfig {
111 this.hotwordsFile = '', 111 this.hotwordsFile = '',
112 this.hotwordsScore = 1.5, 112 this.hotwordsScore = 1.5,
113 this.ctcFstDecoderConfig = const OnlineCtcFstDecoderConfig(), 113 this.ctcFstDecoderConfig = const OnlineCtcFstDecoderConfig(),
  114 + this.ruleFsts = '',
  115 + this.ruleFars = '',
114 }); 116 });
115 117
116 @override 118 @override
117 String toString() { 119 String toString() {
118 - return 'OnlineRecognizerConfig(feat: $feat, model: $model, decodingMethod: $decodingMethod, maxActivePaths: $maxActivePaths, enableEndpoint: $enableEndpoint, rule1MinTrailingSilence: $rule1MinTrailingSilence, rule2MinTrailingSilence: $rule2MinTrailingSilence, rule3MinUtteranceLength: $rule3MinUtteranceLength, hotwordsFile: $hotwordsFile, hotwordsScore: $hotwordsScore, ctcFstDecoderConfig: $ctcFstDecoderConfig)'; 120 + return 'OnlineRecognizerConfig(feat: $feat, model: $model, decodingMethod: $decodingMethod, maxActivePaths: $maxActivePaths, enableEndpoint: $enableEndpoint, rule1MinTrailingSilence: $rule1MinTrailingSilence, rule2MinTrailingSilence: $rule2MinTrailingSilence, rule3MinUtteranceLength: $rule3MinUtteranceLength, hotwordsFile: $hotwordsFile, hotwordsScore: $hotwordsScore, ctcFstDecoderConfig: $ctcFstDecoderConfig, ruleFsts: $ruleFsts, ruleFars: $ruleFars)';
119 } 121 }
120 122
121 final FeatureConfig feat; 123 final FeatureConfig feat;
@@ -137,6 +139,8 @@ class OnlineRecognizerConfig { @@ -137,6 +139,8 @@ class OnlineRecognizerConfig {
137 final double hotwordsScore; 139 final double hotwordsScore;
138 140
139 final OnlineCtcFstDecoderConfig ctcFstDecoderConfig; 141 final OnlineCtcFstDecoderConfig ctcFstDecoderConfig;
  142 + final String ruleFsts;
  143 + final String ruleFars;
140 } 144 }
141 145
142 class OnlineRecognizerResult { 146 class OnlineRecognizerResult {
@@ -201,9 +205,13 @@ class OnlineRecognizer { @@ -201,9 +205,13 @@ class OnlineRecognizer {
201 c.ref.ctcFstDecoderConfig.graph = 205 c.ref.ctcFstDecoderConfig.graph =
202 config.ctcFstDecoderConfig.graph.toNativeUtf8(); 206 config.ctcFstDecoderConfig.graph.toNativeUtf8();
203 c.ref.ctcFstDecoderConfig.maxActive = config.ctcFstDecoderConfig.maxActive; 207 c.ref.ctcFstDecoderConfig.maxActive = config.ctcFstDecoderConfig.maxActive;
  208 + c.ref.ruleFsts = config.ruleFsts.toNativeUtf8();
  209 + c.ref.ruleFars = config.ruleFars.toNativeUtf8();
204 210
205 final ptr = SherpaOnnxBindings.createOnlineRecognizer?.call(c) ?? nullptr; 211 final ptr = SherpaOnnxBindings.createOnlineRecognizer?.call(c) ?? nullptr;
206 212
  213 + calloc.free(c.ref.ruleFars);
  214 + calloc.free(c.ref.ruleFsts);
207 calloc.free(c.ref.ctcFstDecoderConfig.graph); 215 calloc.free(c.ref.ctcFstDecoderConfig.graph);
208 calloc.free(c.ref.hotwordsFile); 216 calloc.free(c.ref.hotwordsFile);
209 calloc.free(c.ref.decodingMethod); 217 calloc.free(c.ref.decodingMethod);
@@ -205,6 +205,9 @@ final class SherpaOnnxOnlineRecognizerConfig extends Struct { @@ -205,6 +205,9 @@ final class SherpaOnnxOnlineRecognizerConfig extends Struct {
205 external double hotwordsScore; 205 external double hotwordsScore;
206 206
207 external SherpaOnnxOnlineCtcFstDecoderConfig ctcFstDecoderConfig; 207 external SherpaOnnxOnlineCtcFstDecoderConfig ctcFstDecoderConfig;
  208 +
  209 + external Pointer<Utf8> ruleFsts;
  210 + external Pointer<Utf8> ruleFars;
208 } 211 }
209 212
210 final class SherpaOnnxSileroVadModelConfig extends Struct { 213 final class SherpaOnnxSileroVadModelConfig extends Struct {
@@ -15,6 +15,8 @@ public class OnlineRecognizerConfig { @@ -15,6 +15,8 @@ public class OnlineRecognizerConfig {
15 private final int maxActivePaths; 15 private final int maxActivePaths;
16 private final String hotwordsFile; 16 private final String hotwordsFile;
17 private final float hotwordsScore; 17 private final float hotwordsScore;
  18 + private final String ruleFsts;
  19 + private final String ruleFars;
18 20
19 private OnlineRecognizerConfig(Builder builder) { 21 private OnlineRecognizerConfig(Builder builder) {
20 this.featConfig = builder.featConfig; 22 this.featConfig = builder.featConfig;
@@ -27,6 +29,8 @@ public class OnlineRecognizerConfig { @@ -27,6 +29,8 @@ public class OnlineRecognizerConfig {
27 this.maxActivePaths = builder.maxActivePaths; 29 this.maxActivePaths = builder.maxActivePaths;
28 this.hotwordsFile = builder.hotwordsFile; 30 this.hotwordsFile = builder.hotwordsFile;
29 this.hotwordsScore = builder.hotwordsScore; 31 this.hotwordsScore = builder.hotwordsScore;
  32 + this.ruleFsts = builder.ruleFsts;
  33 + this.ruleFars = builder.ruleFars;
30 } 34 }
31 35
32 public static Builder builder() { 36 public static Builder builder() {
@@ -48,6 +52,8 @@ public class OnlineRecognizerConfig { @@ -48,6 +52,8 @@ public class OnlineRecognizerConfig {
48 private int maxActivePaths = 4; 52 private int maxActivePaths = 4;
49 private String hotwordsFile = ""; 53 private String hotwordsFile = "";
50 private float hotwordsScore = 1.5f; 54 private float hotwordsScore = 1.5f;
  55 + private String ruleFsts = "";
  56 + private String ruleFars = "";
51 57
52 public OnlineRecognizerConfig build() { 58 public OnlineRecognizerConfig build() {
53 return new OnlineRecognizerConfig(this); 59 return new OnlineRecognizerConfig(this);
@@ -102,5 +108,15 @@ public class OnlineRecognizerConfig { @@ -102,5 +108,15 @@ public class OnlineRecognizerConfig {
102 this.hotwordsScore = hotwordsScore; 108 this.hotwordsScore = hotwordsScore;
103 return this; 109 return this;
104 } 110 }
  111 +
  112 + public Builder setRuleFsts(String ruleFsts) {
  113 + this.ruleFsts = ruleFsts;
  114 + return this;
  115 + }
  116 +
  117 + public Builder setRuleFars(String ruleFars) {
  118 + this.ruleFars = ruleFars;
  119 + return this;
  120 + }
105 } 121 }
106 } 122 }
@@ -37,6 +37,18 @@ static OnlineRecognizerConfig GetConfig(JNIEnv *env, jobject config) { @@ -37,6 +37,18 @@ static OnlineRecognizerConfig GetConfig(JNIEnv *env, jobject config) {
37 fid = env->GetFieldID(cls, "hotwordsScore", "F"); 37 fid = env->GetFieldID(cls, "hotwordsScore", "F");
38 ans.hotwords_score = env->GetFloatField(config, fid); 38 ans.hotwords_score = env->GetFloatField(config, fid);
39 39
  40 + fid = env->GetFieldID(cls, "ruleFsts", "Ljava/lang/String;");
  41 + s = (jstring)env->GetObjectField(config, fid);
  42 + p = env->GetStringUTFChars(s, nullptr);
  43 + ans.rule_fsts = p;
  44 + env->ReleaseStringUTFChars(s, p);
  45 +
  46 + fid = env->GetFieldID(cls, "ruleFars", "Ljava/lang/String;");
  47 + s = (jstring)env->GetObjectField(config, fid);
  48 + p = env->GetStringUTFChars(s, nullptr);
  49 + ans.rule_fars = p;
  50 + env->ReleaseStringUTFChars(s, p);
  51 +
40 //---------- feat config ---------- 52 //---------- feat config ----------
41 fid = env->GetFieldID(cls, "featConfig", 53 fid = env->GetFieldID(cls, "featConfig",
42 "Lcom/k2fsa/sherpa/onnx/FeatureConfig;"); 54 "Lcom/k2fsa/sherpa/onnx/FeatureConfig;");
@@ -69,6 +69,8 @@ data class OnlineRecognizerConfig( @@ -69,6 +69,8 @@ data class OnlineRecognizerConfig(
69 var maxActivePaths: Int = 4, 69 var maxActivePaths: Int = 4,
70 var hotwordsFile: String = "", 70 var hotwordsFile: String = "",
71 var hotwordsScore: Float = 1.5f, 71 var hotwordsScore: Float = 1.5f,
  72 + var ruleFsts: String = "",
  73 + var ruleFars: String = "",
72 ) 74 )
73 75
74 data class OnlineRecognizerResult( 76 data class OnlineRecognizerResult(
@@ -135,7 +135,9 @@ func sherpaOnnxOnlineRecognizerConfig( @@ -135,7 +135,9 @@ func sherpaOnnxOnlineRecognizerConfig(
135 maxActivePaths: Int = 4, 135 maxActivePaths: Int = 4,
136 hotwordsFile: String = "", 136 hotwordsFile: String = "",
137 hotwordsScore: Float = 1.5, 137 hotwordsScore: Float = 1.5,
138 - ctcFstDecoderConfig: SherpaOnnxOnlineCtcFstDecoderConfig = sherpaOnnxOnlineCtcFstDecoderConfig() 138 + ctcFstDecoderConfig: SherpaOnnxOnlineCtcFstDecoderConfig = sherpaOnnxOnlineCtcFstDecoderConfig(),
  139 + ruleFsts: String = "",
  140 + ruleFars: String = ""
139 ) -> SherpaOnnxOnlineRecognizerConfig { 141 ) -> SherpaOnnxOnlineRecognizerConfig {
140 return SherpaOnnxOnlineRecognizerConfig( 142 return SherpaOnnxOnlineRecognizerConfig(
141 feat_config: featConfig, 143 feat_config: featConfig,
@@ -148,7 +150,9 @@ func sherpaOnnxOnlineRecognizerConfig( @@ -148,7 +150,9 @@ func sherpaOnnxOnlineRecognizerConfig(
148 rule3_min_utterance_length: rule3MinUtteranceLength, 150 rule3_min_utterance_length: rule3MinUtteranceLength,
149 hotwords_file: toCPointer(hotwordsFile), 151 hotwords_file: toCPointer(hotwordsFile),
150 hotwords_score: hotwordsScore, 152 hotwords_score: hotwordsScore,
151 - ctc_fst_decoder_config: ctcFstDecoderConfig 153 + ctc_fst_decoder_config: ctcFstDecoderConfig,
  154 + rule_fsts: toCPointer(ruleFsts),
  155 + rule_fars: toCPointer(ruleFars)
152 ) 156 )
153 } 157 }
154 158
@@ -40,6 +40,8 @@ string(APPEND MY_FLAGS " -sEXPORTED_FUNCTIONS=[_CopyHeap,_malloc,_free,${all_exp @@ -40,6 +40,8 @@ string(APPEND MY_FLAGS " -sEXPORTED_FUNCTIONS=[_CopyHeap,_malloc,_free,${all_exp
40 string(APPEND MY_FLAGS "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@. ") 40 string(APPEND MY_FLAGS "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@. ")
41 string(APPEND MY_FLAGS " -sEXPORTED_RUNTIME_METHODS=['ccall','stringToUTF8','setValue','getValue','lengthBytesUTF8','UTF8ToString'] ") 41 string(APPEND MY_FLAGS " -sEXPORTED_RUNTIME_METHODS=['ccall','stringToUTF8','setValue','getValue','lengthBytesUTF8','UTF8ToString'] ")
42 42
  43 +message(STATUS "MY_FLAGS: ${MY_FLAGS}")
  44 +
43 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_FLAGS}") 45 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_FLAGS}")
44 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_FLAGS}") 46 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_FLAGS}")
45 set(CMAKE_EXECUTBLE_LINKER_FLAGS "${CMAKE_EXECUTBLE_LINKER_FLAGS} ${MY_FLAGS}") 47 set(CMAKE_EXECUTBLE_LINKER_FLAGS "${CMAKE_EXECUTBLE_LINKER_FLAGS} ${MY_FLAGS}")
@@ -239,7 +239,7 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) { @@ -239,7 +239,7 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
239 const ctcFstDecoder = initSherpaOnnxOnlineCtcFstDecoderConfig( 239 const ctcFstDecoder = initSherpaOnnxOnlineCtcFstDecoderConfig(
240 config.ctcFstDecoderConfig, Module) 240 config.ctcFstDecoderConfig, Module)
241 241
242 - const len = feat.len + model.len + 8 * 4 + ctcFstDecoder.len; 242 + const len = feat.len + model.len + 8 * 4 + ctcFstDecoder.len + 2 * 4;
243 const ptr = Module._malloc(len); 243 const ptr = Module._malloc(len);
244 244
245 let offset = 0; 245 let offset = 0;
@@ -251,7 +251,10 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) { @@ -251,7 +251,10 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
251 251
252 const decodingMethodLen = Module.lengthBytesUTF8(config.decodingMethod) + 1; 252 const decodingMethodLen = Module.lengthBytesUTF8(config.decodingMethod) + 1;
253 const hotwordsFileLen = Module.lengthBytesUTF8(config.hotwordsFile) + 1; 253 const hotwordsFileLen = Module.lengthBytesUTF8(config.hotwordsFile) + 1;
254 - const bufferLen = decodingMethodLen + hotwordsFileLen; 254 + const ruleFstsFileLen = Module.lengthBytesUTF8(config.ruleFsts || '') + 1;
  255 + const ruleFarsFileLen = Module.lengthBytesUTF8(config.ruleFars || '') + 1;
  256 + const bufferLen =
  257 + decodingMethodLen + hotwordsFileLen + ruleFstsFileLen + ruleFarsFileLen;
255 const buffer = Module._malloc(bufferLen); 258 const buffer = Module._malloc(bufferLen);
256 259
257 offset = 0; 260 offset = 0;
@@ -259,6 +262,13 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) { @@ -259,6 +262,13 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
259 offset += decodingMethodLen; 262 offset += decodingMethodLen;
260 263
261 Module.stringToUTF8(config.hotwordsFile, buffer + offset, hotwordsFileLen); 264 Module.stringToUTF8(config.hotwordsFile, buffer + offset, hotwordsFileLen);
  265 + offset += hotwordsFileLen;
  266 +
  267 + Module.stringToUTF8(config.ruleFsts || '', buffer + offset, ruleFstsFileLen);
  268 + offset += ruleFstsFileLen;
  269 +
  270 + Module.stringToUTF8(config.ruleFars || '', buffer + offset, ruleFarsFileLen);
  271 + offset += ruleFarsFileLen;
262 272
263 offset = feat.len + model.len; 273 offset = feat.len + model.len;
264 Module.setValue(ptr + offset, buffer, 'i8*'); // decoding method 274 Module.setValue(ptr + offset, buffer, 'i8*'); // decoding method
@@ -286,6 +296,16 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) { @@ -286,6 +296,16 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
286 offset += 4; 296 offset += 4;
287 297
288 Module._CopyHeap(ctcFstDecoder.ptr, ctcFstDecoder.len, ptr + offset); 298 Module._CopyHeap(ctcFstDecoder.ptr, ctcFstDecoder.len, ptr + offset);
  299 + offset += ctcFstDecoder.len;
  300 +
  301 + Module.setValue(
  302 + ptr + offset, buffer + decodingMethodLen + hotwordsFileLen, 'i8*');
  303 + offset += 4;
  304 +
  305 + Module.setValue(
  306 + ptr + offset,
  307 + buffer + decodingMethodLen + hotwordsFileLen + ruleFstsFileLen, 'i8*');
  308 + offset += 4;
289 309
290 return { 310 return {
291 buffer: buffer, ptr: ptr, len: len, feat: feat, model: model, 311 buffer: buffer, ptr: ptr, len: len, feat: feat, model: model,
@@ -363,7 +383,9 @@ function createOnlineRecognizer(Module, myConfig) { @@ -363,7 +383,9 @@ function createOnlineRecognizer(Module, myConfig) {
363 ctcFstDecoderConfig: { 383 ctcFstDecoderConfig: {
364 graph: '', 384 graph: '',
365 maxActive: 3000, 385 maxActive: 3000,
366 - } 386 + },
  387 + ruleFsts: '',
  388 + ruleFars: '',
367 }; 389 };
368 if (myConfig) { 390 if (myConfig) {
369 recognizerConfig = myConfig; 391 recognizerConfig = myConfig;
@@ -26,7 +26,7 @@ static_assert(sizeof(SherpaOnnxOnlineCtcFstDecoderConfig) == 2 * 4, ""); @@ -26,7 +26,7 @@ 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), 29 + sizeof(SherpaOnnxOnlineCtcFstDecoderConfig) + 2 * 4,
30 ""); 30 "");
31 31
32 void MyPrint(SherpaOnnxOnlineRecognizerConfig *config) { 32 void MyPrint(SherpaOnnxOnlineRecognizerConfig *config) {
@@ -71,6 +71,8 @@ void MyPrint(SherpaOnnxOnlineRecognizerConfig *config) { @@ -71,6 +71,8 @@ void MyPrint(SherpaOnnxOnlineRecognizerConfig *config) {
71 config->rule3_min_utterance_length); 71 config->rule3_min_utterance_length);
72 fprintf(stdout, "hotwords_file: %s\n", config->hotwords_file); 72 fprintf(stdout, "hotwords_file: %s\n", config->hotwords_file);
73 fprintf(stdout, "hotwords_score: %.2f\n", config->hotwords_score); 73 fprintf(stdout, "hotwords_score: %.2f\n", config->hotwords_score);
  74 + fprintf(stdout, "rule_fsts: %s\n", config->rule_fsts);
  75 + fprintf(stdout, "rule_fars: %s\n", config->rule_fars);
74 76
75 fprintf(stdout, "----------ctc fst decoder config----------\n"); 77 fprintf(stdout, "----------ctc fst decoder config----------\n");
76 fprintf(stdout, "graph: %s\n", config->ctc_fst_decoder_config.graph); 78 fprintf(stdout, "graph: %s\n", config->ctc_fst_decoder_config.graph);
@@ -31,6 +31,7 @@ string(APPEND MY_FLAGS " -sSTACK_SIZE=10485760 ") @@ -31,6 +31,7 @@ string(APPEND MY_FLAGS " -sSTACK_SIZE=10485760 ")
31 string(APPEND MY_FLAGS " -sEXPORTED_FUNCTIONS=[_CopyHeap,_malloc,_free,${all_exported_functions}] ") 31 string(APPEND MY_FLAGS " -sEXPORTED_FUNCTIONS=[_CopyHeap,_malloc,_free,${all_exported_functions}] ")
32 string(APPEND MY_FLAGS "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@. ") 32 string(APPEND MY_FLAGS "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@. ")
33 string(APPEND MY_FLAGS " -sEXPORTED_RUNTIME_METHODS=['ccall','stringToUTF8','setValue','getValue','lengthBytesUTF8','UTF8ToString'] ") 33 string(APPEND MY_FLAGS " -sEXPORTED_RUNTIME_METHODS=['ccall','stringToUTF8','setValue','getValue','lengthBytesUTF8','UTF8ToString'] ")
  34 +
34 message(STATUS "MY_FLAGS: ${MY_FLAGS}") 35 message(STATUS "MY_FLAGS: ${MY_FLAGS}")
35 36
36 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_FLAGS}") 37 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_FLAGS}")
@@ -31,6 +31,8 @@ string(APPEND MY_FLAGS " -sEXPORTED_FUNCTIONS=[_CopyHeap,_malloc,_free,${all_exp @@ -31,6 +31,8 @@ string(APPEND MY_FLAGS " -sEXPORTED_FUNCTIONS=[_CopyHeap,_malloc,_free,${all_exp
31 string(APPEND MY_FLAGS "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@. ") 31 string(APPEND MY_FLAGS "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@. ")
32 string(APPEND MY_FLAGS " -sEXPORTED_RUNTIME_METHODS=['ccall','stringToUTF8','setValue','getValue','lengthBytesUTF8','UTF8ToString'] ") 32 string(APPEND MY_FLAGS " -sEXPORTED_RUNTIME_METHODS=['ccall','stringToUTF8','setValue','getValue','lengthBytesUTF8','UTF8ToString'] ")
33 33
  34 +message(STATUS "MY_FLAGS: ${MY_FLAGS}")
  35 +
34 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_FLAGS}") 36 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_FLAGS}")
35 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_FLAGS}") 37 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_FLAGS}")
36 set(CMAKE_EXECUTBLE_LINKER_FLAGS "${CMAKE_EXECUTBLE_LINKER_FLAGS} ${MY_FLAGS}") 38 set(CMAKE_EXECUTBLE_LINKER_FLAGS "${CMAKE_EXECUTBLE_LINKER_FLAGS} ${MY_FLAGS}")