Committed by
GitHub
Add more C API examples (#1255)
C API examples for zipformer, paraformer, and TeleSpeech-ASR CTC models.
正在显示
8 个修改的文件
包含
689 行增加
和
1 行删除
| @@ -163,3 +163,163 @@ jobs: | @@ -163,3 +163,163 @@ jobs: | ||
| 163 | ./whisper-c-api | 163 | ./whisper-c-api |
| 164 | 164 | ||
| 165 | rm -rf sherpa-onnx-whisper-* | 165 | rm -rf sherpa-onnx-whisper-* |
| 166 | + | ||
| 167 | + - name: Test non-streaming zipformer | ||
| 168 | + shell: bash | ||
| 169 | + run: | | ||
| 170 | + gcc -o zipformer-c-api ./c-api-examples/zipformer-c-api.c \ | ||
| 171 | + -I ./build/install/include \ | ||
| 172 | + -L ./build/install/lib/ \ | ||
| 173 | + -l sherpa-onnx-c-api \ | ||
| 174 | + -l onnxruntime | ||
| 175 | + | ||
| 176 | + ls -lh zipformer-c-api | ||
| 177 | + | ||
| 178 | + if [[ ${{ matrix.os }} == ubuntu-latest ]]; then | ||
| 179 | + ldd ./zipformer-c-api | ||
| 180 | + echo "----" | ||
| 181 | + readelf -d ./zipformer-c-api | ||
| 182 | + fi | ||
| 183 | + | ||
| 184 | + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-zipformer-small-en-2023-06-26.tar.bz2 | ||
| 185 | + tar xvf sherpa-onnx-zipformer-small-en-2023-06-26.tar.bz2 | ||
| 186 | + rm sherpa-onnx-zipformer-small-en-2023-06-26.tar.bz2 | ||
| 187 | + | ||
| 188 | + ls -lh sherpa-onnx-zipformer-small-en-2023-06-26 | ||
| 189 | + echo "---" | ||
| 190 | + ls -lh sherpa-onnx-zipformer-small-en-2023-06-26/test_wavs | ||
| 191 | + | ||
| 192 | + export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH | ||
| 193 | + export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH | ||
| 194 | + | ||
| 195 | + ./zipformer-c-api | ||
| 196 | + | ||
| 197 | + rm -rf sherpa-onnx-zipformer-* | ||
| 198 | + | ||
| 199 | + - name: Test streaming zipformer | ||
| 200 | + shell: bash | ||
| 201 | + run: | | ||
| 202 | + gcc -o streaming-zipformer-c-api ./c-api-examples/streaming-zipformer-c-api.c \ | ||
| 203 | + -I ./build/install/include \ | ||
| 204 | + -L ./build/install/lib/ \ | ||
| 205 | + -l sherpa-onnx-c-api \ | ||
| 206 | + -l onnxruntime | ||
| 207 | + | ||
| 208 | + ls -lh streaming-zipformer-c-api | ||
| 209 | + | ||
| 210 | + if [[ ${{ matrix.os }} == ubuntu-latest ]]; then | ||
| 211 | + ldd ./streaming-zipformer-c-api | ||
| 212 | + echo "----" | ||
| 213 | + readelf -d ./streaming-zipformer-c-api | ||
| 214 | + fi | ||
| 215 | + | ||
| 216 | + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-en-20M-2023-02-17.tar.bz2 | ||
| 217 | + tar xvf sherpa-onnx-streaming-zipformer-en-20M-2023-02-17.tar.bz2 | ||
| 218 | + rm sherpa-onnx-streaming-zipformer-en-20M-2023-02-17.tar.bz2 | ||
| 219 | + | ||
| 220 | + ls -lh sherpa-onnx-streaming-zipformer-en-20M-2023-02-17 | ||
| 221 | + echo "---" | ||
| 222 | + ls -lh sherpa-onnx-streaming-zipformer-en-20M-2023-02-17/test_wavs | ||
| 223 | + | ||
| 224 | + export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH | ||
| 225 | + export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH | ||
| 226 | + | ||
| 227 | + ./streaming-zipformer-c-api | ||
| 228 | + | ||
| 229 | + rm -rf sherpa-onnx-streaming-zipformer-* | ||
| 230 | + | ||
| 231 | + - name: Test non-streaming paraformer | ||
| 232 | + shell: bash | ||
| 233 | + run: | | ||
| 234 | + gcc -o paraformer-c-api ./c-api-examples/paraformer-c-api.c \ | ||
| 235 | + -I ./build/install/include \ | ||
| 236 | + -L ./build/install/lib/ \ | ||
| 237 | + -l sherpa-onnx-c-api \ | ||
| 238 | + -l onnxruntime | ||
| 239 | + | ||
| 240 | + ls -lh paraformer-c-api | ||
| 241 | + | ||
| 242 | + if [[ ${{ matrix.os }} == ubuntu-latest ]]; then | ||
| 243 | + ldd ./paraformer-c-api | ||
| 244 | + echo "----" | ||
| 245 | + readelf -d ./paraformer-c-api | ||
| 246 | + fi | ||
| 247 | + | ||
| 248 | + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-paraformer-zh-small-2024-03-09.tar.bz2 | ||
| 249 | + tar xvf sherpa-onnx-paraformer-zh-small-2024-03-09.tar.bz2 | ||
| 250 | + rm sherpa-onnx-paraformer-zh-small-2024-03-09.tar.bz2 | ||
| 251 | + | ||
| 252 | + ls -lh sherpa-onnx-paraformer-zh-small-2024-03-09 | ||
| 253 | + echo "---" | ||
| 254 | + ls -lh sherpa-onnx-paraformer-zh-small-2024-03-09/test_wavs | ||
| 255 | + | ||
| 256 | + export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH | ||
| 257 | + export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH | ||
| 258 | + | ||
| 259 | + ./paraformer-c-api | ||
| 260 | + | ||
| 261 | + rm -rf sherpa-onnx-paraformer-* | ||
| 262 | + | ||
| 263 | + - name: Test streaming paraformer | ||
| 264 | + shell: bash | ||
| 265 | + run: | | ||
| 266 | + gcc -o streaming-paraformer-c-api ./c-api-examples/streaming-paraformer-c-api.c \ | ||
| 267 | + -I ./build/install/include \ | ||
| 268 | + -L ./build/install/lib/ \ | ||
| 269 | + -l sherpa-onnx-c-api \ | ||
| 270 | + -l onnxruntime | ||
| 271 | + | ||
| 272 | + ls -lh streaming-paraformer-c-api | ||
| 273 | + | ||
| 274 | + if [[ ${{ matrix.os }} == ubuntu-latest ]]; then | ||
| 275 | + ldd ./streaming-paraformer-c-api | ||
| 276 | + echo "----" | ||
| 277 | + readelf -d ./streaming-paraformer-c-api | ||
| 278 | + fi | ||
| 279 | + | ||
| 280 | + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-paraformer-bilingual-zh-en.tar.bz2 | ||
| 281 | + tar xvf sherpa-onnx-streaming-paraformer-bilingual-zh-en.tar.bz2 | ||
| 282 | + rm sherpa-onnx-streaming-paraformer-bilingual-zh-en.tar.bz2 | ||
| 283 | + | ||
| 284 | + ls -lh sherpa-onnx-streaming-paraformer-bilingual-zh-en | ||
| 285 | + echo "---" | ||
| 286 | + ls -lh sherpa-onnx-streaming-paraformer-bilingual-zh-en/test_wavs | ||
| 287 | + | ||
| 288 | + export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH | ||
| 289 | + export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH | ||
| 290 | + | ||
| 291 | + ./streaming-paraformer-c-api | ||
| 292 | + | ||
| 293 | + rm -rf sherpa-onnx-streaming-paraformer-* | ||
| 294 | + | ||
| 295 | + - name: Test telespeech | ||
| 296 | + shell: bash | ||
| 297 | + run: | | ||
| 298 | + gcc -o telespeech-c-api ./c-api-examples/telespeech-c-api.c \ | ||
| 299 | + -I ./build/install/include \ | ||
| 300 | + -L ./build/install/lib/ \ | ||
| 301 | + -l sherpa-onnx-c-api \ | ||
| 302 | + -l onnxruntime | ||
| 303 | + | ||
| 304 | + ls -lh telespeech-c-api | ||
| 305 | + | ||
| 306 | + if [[ ${{ matrix.os }} == ubuntu-latest ]]; then | ||
| 307 | + ldd ./telespeech-c-api | ||
| 308 | + echo "----" | ||
| 309 | + readelf -d ./telespeech-c-api | ||
| 310 | + fi | ||
| 311 | + | ||
| 312 | + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04.tar.bz2 | ||
| 313 | + tar xvf sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04.tar.bz2 | ||
| 314 | + rm sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04.tar.bz2 | ||
| 315 | + | ||
| 316 | + ls -lh sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04 | ||
| 317 | + echo "---" | ||
| 318 | + ls -lh sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04/test_wavs | ||
| 319 | + | ||
| 320 | + export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH | ||
| 321 | + export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH | ||
| 322 | + | ||
| 323 | + ./telespeech-c-api | ||
| 324 | + | ||
| 325 | + rm -rf sherpa-onnx-telespeech-* |
| @@ -30,6 +30,21 @@ target_link_libraries(whisper-c-api sherpa-onnx-c-api) | @@ -30,6 +30,21 @@ target_link_libraries(whisper-c-api sherpa-onnx-c-api) | ||
| 30 | add_executable(sense-voice-c-api sense-voice-c-api.c) | 30 | add_executable(sense-voice-c-api sense-voice-c-api.c) |
| 31 | target_link_libraries(sense-voice-c-api sherpa-onnx-c-api) | 31 | target_link_libraries(sense-voice-c-api sherpa-onnx-c-api) |
| 32 | 32 | ||
| 33 | +add_executable(zipformer-c-api zipformer-c-api.c) | ||
| 34 | +target_link_libraries(zipformer-c-api sherpa-onnx-c-api) | ||
| 35 | + | ||
| 36 | +add_executable(streaming-zipformer-c-api streaming-zipformer-c-api.c) | ||
| 37 | +target_link_libraries(streaming-zipformer-c-api sherpa-onnx-c-api) | ||
| 38 | + | ||
| 39 | +add_executable(paraformer-c-api paraformer-c-api.c) | ||
| 40 | +target_link_libraries(paraformer-c-api sherpa-onnx-c-api) | ||
| 41 | + | ||
| 42 | +add_executable(streaming-paraformer-c-api streaming-paraformer-c-api.c) | ||
| 43 | +target_link_libraries(streaming-paraformer-c-api sherpa-onnx-c-api) | ||
| 44 | + | ||
| 45 | +add_executable(telespeech-c-api telespeech-c-api.c) | ||
| 46 | +target_link_libraries(telespeech-c-api sherpa-onnx-c-api) | ||
| 47 | + | ||
| 33 | if(SHERPA_ONNX_HAS_ALSA) | 48 | if(SHERPA_ONNX_HAS_ALSA) |
| 34 | add_subdirectory(./asr-microphone-example) | 49 | add_subdirectory(./asr-microphone-example) |
| 35 | elseif((UNIX AND NOT APPLE) OR LINUX) | 50 | elseif((UNIX AND NOT APPLE) OR LINUX) |
c-api-examples/paraformer-c-api.c
0 → 100644
| 1 | +// c-api-examples/paraformer-c-api.c | ||
| 2 | +// | ||
| 3 | +// Copyright (c) 2024 Xiaomi Corporation | ||
| 4 | + | ||
| 5 | +// | ||
| 6 | +// This file demonstrates how to use non-streaming Paraformer with sherpa-onnx's C API. | ||
| 7 | +// clang-format off | ||
| 8 | +// | ||
| 9 | +// wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-paraformer-zh-small-2024-03-09.tar.bz2 | ||
| 10 | +// tar xvf sherpa-onnx-paraformer-zh-small-2024-03-09.tar.bz2 | ||
| 11 | +// rm sherpa-onnx-paraformer-zh-small-2024-03-09.tar.bz2 | ||
| 12 | +// | ||
| 13 | +// clang-format on | ||
| 14 | + | ||
| 15 | +#include <stdio.h> | ||
| 16 | +#include <stdlib.h> | ||
| 17 | +#include <string.h> | ||
| 18 | + | ||
| 19 | +#include "sherpa-onnx/c-api/c-api.h" | ||
| 20 | + | ||
| 21 | +int32_t main() { | ||
| 22 | + | ||
| 23 | + const char *wav_filename = "sherpa-onnx-paraformer-zh-small-2024-03-09/test_wavs/0.wav"; | ||
| 24 | + const char *model_filename = "sherpa-onnx-paraformer-zh-small-2024-03-09/model.int8.onnx"; | ||
| 25 | + const char *tokens_filename = "sherpa-onnx-paraformer-zh-small-2024-03-09/tokens.txt"; | ||
| 26 | + const char *provider = "cpu"; | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename); | ||
| 30 | + if (wave == NULL) { | ||
| 31 | + fprintf(stderr, "Failed to read %s\n", wav_filename); | ||
| 32 | + return -1; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + // Paraformer config | ||
| 36 | + SherpaOnnxOfflineParaformerModelConfig paraformer_config; | ||
| 37 | + memset(¶former_config, 0, sizeof(paraformer_config)); | ||
| 38 | + paraformer_config.model = model_filename; | ||
| 39 | + | ||
| 40 | + // Offline model config | ||
| 41 | + SherpaOnnxOfflineModelConfig offline_model_config; | ||
| 42 | + memset(&offline_model_config, 0, sizeof(offline_model_config)); | ||
| 43 | + offline_model_config.debug = 1; | ||
| 44 | + offline_model_config.num_threads = 1; | ||
| 45 | + offline_model_config.provider = provider; | ||
| 46 | + offline_model_config.tokens = tokens_filename; | ||
| 47 | + offline_model_config.paraformer = paraformer_config; | ||
| 48 | + | ||
| 49 | + // Recognizer config | ||
| 50 | + SherpaOnnxOfflineRecognizerConfig recognizer_config; | ||
| 51 | + memset(&recognizer_config, 0, sizeof(recognizer_config)); | ||
| 52 | + recognizer_config.decoding_method = "greedy_search"; | ||
| 53 | + recognizer_config.model_config = offline_model_config; | ||
| 54 | + | ||
| 55 | + SherpaOnnxOfflineRecognizer *recognizer = | ||
| 56 | + SherpaOnnxCreateOfflineRecognizer(&recognizer_config); | ||
| 57 | + | ||
| 58 | + if (recognizer == NULL) { | ||
| 59 | + fprintf(stderr, "Please check your config!\n"); | ||
| 60 | + SherpaOnnxFreeWave(wave); | ||
| 61 | + return -1; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + SherpaOnnxOfflineStream *stream = SherpaOnnxCreateOfflineStream(recognizer); | ||
| 65 | + | ||
| 66 | + SherpaOnnxAcceptWaveformOffline(stream, wave->sample_rate, wave->samples, | ||
| 67 | + wave->num_samples); | ||
| 68 | + SherpaOnnxDecodeOfflineStream(recognizer, stream); | ||
| 69 | + const SherpaOnnxOfflineRecognizerResult *result = | ||
| 70 | + SherpaOnnxGetOfflineStreamResult(stream); | ||
| 71 | + | ||
| 72 | + fprintf(stderr, "Decoded text: %s\n", result->text); | ||
| 73 | + | ||
| 74 | + SherpaOnnxDestroyOfflineRecognizerResult(result); | ||
| 75 | + SherpaOnnxDestroyOfflineStream(stream); | ||
| 76 | + SherpaOnnxDestroyOfflineRecognizer(recognizer); | ||
| 77 | + SherpaOnnxFreeWave(wave); | ||
| 78 | + | ||
| 79 | + return 0; | ||
| 80 | +} |
c-api-examples/streaming-paraformer-c-api.c
0 → 100644
| 1 | +// c-api-examples/streaming-paraformer-c-api.c | ||
| 2 | +// | ||
| 3 | +// Copyright (c) 2024 Xiaomi Corporation | ||
| 4 | + | ||
| 5 | +// | ||
| 6 | +// This file demonstrates how to use streaming Paraformer with sherpa-onnx's C API. | ||
| 7 | +// clang-format off | ||
| 8 | +// | ||
| 9 | +// wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-paraformer-bilingual-zh-en.tar.bz2 | ||
| 10 | +// tar xvf sherpa-onnx-streaming-paraformer-bilingual-zh-en.tar.bz2 | ||
| 11 | +// rm sherpa-onnx-streaming-paraformer-bilingual-zh-en.tar.bz2 | ||
| 12 | +// | ||
| 13 | +// clang-format on | ||
| 14 | + | ||
| 15 | +#include <stdio.h> | ||
| 16 | +#include <stdlib.h> | ||
| 17 | +#include <string.h> | ||
| 18 | + | ||
| 19 | +#include "sherpa-onnx/c-api/c-api.h" | ||
| 20 | + | ||
| 21 | +int32_t main() { | ||
| 22 | + | ||
| 23 | + const char *wav_filename = "sherpa-onnx-streaming-paraformer-bilingual-zh-en/test_wavs/0.wav"; | ||
| 24 | + const char *encoder_filename = "sherpa-onnx-streaming-paraformer-bilingual-zh-en/encoder.int8.onnx"; | ||
| 25 | + const char *decoder_filename = "sherpa-onnx-streaming-paraformer-bilingual-zh-en/decoder.int8.onnx"; | ||
| 26 | + const char *tokens_filename = "sherpa-onnx-streaming-paraformer-bilingual-zh-en/tokens.txt"; | ||
| 27 | + const char *provider = "cpu"; | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename); | ||
| 31 | + if (wave == NULL) { | ||
| 32 | + fprintf(stderr, "Failed to read %s\n", wav_filename); | ||
| 33 | + return -1; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + // Paraformer config | ||
| 37 | + SherpaOnnxOnlineParaformerModelConfig paraformer_config; | ||
| 38 | + memset(¶former_config, 0, sizeof(paraformer_config)); | ||
| 39 | + paraformer_config.encoder = encoder_filename; | ||
| 40 | + paraformer_config.decoder = decoder_filename; | ||
| 41 | + | ||
| 42 | + | ||
| 43 | + // Online model config | ||
| 44 | + SherpaOnnxOnlineModelConfig online_model_config; | ||
| 45 | + memset(&online_model_config, 0, sizeof(online_model_config)); | ||
| 46 | + online_model_config.debug = 1; | ||
| 47 | + online_model_config.num_threads = 1; | ||
| 48 | + online_model_config.provider = provider; | ||
| 49 | + online_model_config.tokens = tokens_filename; | ||
| 50 | + online_model_config.paraformer = paraformer_config; | ||
| 51 | + | ||
| 52 | + // Recognizer config | ||
| 53 | + SherpaOnnxOnlineRecognizerConfig recognizer_config; | ||
| 54 | + memset(&recognizer_config, 0, sizeof(recognizer_config)); | ||
| 55 | + recognizer_config.decoding_method = "greedy_search"; | ||
| 56 | + recognizer_config.model_config = online_model_config; | ||
| 57 | + | ||
| 58 | + SherpaOnnxOnlineRecognizer *recognizer = | ||
| 59 | + SherpaOnnxCreateOnlineRecognizer(&recognizer_config); | ||
| 60 | + | ||
| 61 | + if (recognizer == NULL) { | ||
| 62 | + fprintf(stderr, "Please check your config!\n"); | ||
| 63 | + SherpaOnnxFreeWave(wave); | ||
| 64 | + return -1; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + SherpaOnnxOnlineStream *stream = SherpaOnnxCreateOnlineStream(recognizer); | ||
| 68 | + | ||
| 69 | + const SherpaOnnxDisplay *display = SherpaOnnxCreateDisplay(50); | ||
| 70 | + int32_t segment_id = 0; | ||
| 71 | + | ||
| 72 | +// simulate streaming. You can choose an arbitrary N | ||
| 73 | +#define N 3200 | ||
| 74 | + | ||
| 75 | + fprintf(stderr, "sample rate: %d, num samples: %d, duration: %.2f s\n", | ||
| 76 | + wave->sample_rate, wave->num_samples, | ||
| 77 | + (float)wave->num_samples / wave->sample_rate); | ||
| 78 | + | ||
| 79 | + int32_t k = 0; | ||
| 80 | + while (k < wave->num_samples) { | ||
| 81 | + int32_t start = k; | ||
| 82 | + int32_t end = | ||
| 83 | + (start + N > wave->num_samples) ? wave->num_samples : (start + N); | ||
| 84 | + k += N; | ||
| 85 | + | ||
| 86 | + SherpaOnnxOnlineStreamAcceptWaveform(stream, wave->sample_rate, | ||
| 87 | + wave->samples + start, end - start); | ||
| 88 | + while (SherpaOnnxIsOnlineStreamReady(recognizer, stream)) { | ||
| 89 | + SherpaOnnxDecodeOnlineStream(recognizer, stream); | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + const SherpaOnnxOnlineRecognizerResult *r = | ||
| 93 | + SherpaOnnxGetOnlineStreamResult(recognizer, stream); | ||
| 94 | + | ||
| 95 | + if (strlen(r->text)) { | ||
| 96 | + SherpaOnnxPrint(display, segment_id, r->text); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + if (SherpaOnnxOnlineStreamIsEndpoint(recognizer, stream)) { | ||
| 100 | + if (strlen(r->text)) { | ||
| 101 | + ++segment_id; | ||
| 102 | + } | ||
| 103 | + SherpaOnnxOnlineStreamReset(recognizer, stream); | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + SherpaOnnxDestroyOnlineRecognizerResult(r); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + // add some tail padding | ||
| 110 | + float tail_paddings[4800] = {0}; // 0.3 seconds at 16 kHz sample rate | ||
| 111 | + SherpaOnnxOnlineStreamAcceptWaveform(stream, wave->sample_rate, tail_paddings, | ||
| 112 | + 4800); | ||
| 113 | + | ||
| 114 | + SherpaOnnxFreeWave(wave); | ||
| 115 | + | ||
| 116 | + SherpaOnnxOnlineStreamInputFinished(stream); | ||
| 117 | + while (SherpaOnnxIsOnlineStreamReady(recognizer, stream)) { | ||
| 118 | + SherpaOnnxDecodeOnlineStream(recognizer, stream); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + const SherpaOnnxOnlineRecognizerResult *r = | ||
| 122 | + SherpaOnnxGetOnlineStreamResult(recognizer, stream); | ||
| 123 | + | ||
| 124 | + if (strlen(r->text)) { | ||
| 125 | + SherpaOnnxPrint(display, segment_id, r->text); | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + SherpaOnnxDestroyOnlineRecognizerResult(r); | ||
| 129 | + | ||
| 130 | + SherpaOnnxDestroyDisplay(display); | ||
| 131 | + SherpaOnnxDestroyOnlineStream(stream); | ||
| 132 | + SherpaOnnxDestroyOnlineRecognizer(recognizer); | ||
| 133 | + fprintf(stderr, "\n"); | ||
| 134 | + | ||
| 135 | + return 0; | ||
| 136 | +} |
c-api-examples/streaming-zipformer-c-api.c
0 → 100644
| 1 | +// c-api-examples/streaming-zipformer-c-api.c | ||
| 2 | +// | ||
| 3 | +// Copyright (c) 2024 Xiaomi Corporation | ||
| 4 | + | ||
| 5 | +// | ||
| 6 | +// This file demonstrates how to use streaming Zipformer with sherpa-onnx's C API. | ||
| 7 | +// clang-format off | ||
| 8 | +// | ||
| 9 | +// wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-en-20M-2023-02-17.tar.bz2 | ||
| 10 | +// tar xvf sherpa-onnx-streaming-zipformer-en-20M-2023-02-17.tar.bz2 | ||
| 11 | +// rm sherpa-onnx-streaming-zipformer-en-20M-2023-02-17.tar.bz2 | ||
| 12 | +// | ||
| 13 | +// clang-format on | ||
| 14 | + | ||
| 15 | +#include <stdio.h> | ||
| 16 | +#include <stdlib.h> | ||
| 17 | +#include <string.h> | ||
| 18 | + | ||
| 19 | +#include "sherpa-onnx/c-api/c-api.h" | ||
| 20 | + | ||
| 21 | +int32_t main() { | ||
| 22 | + | ||
| 23 | + const char *wav_filename = "sherpa-onnx-streaming-zipformer-en-20M-2023-02-17/test_wavs/0.wav"; | ||
| 24 | + const char *encoder_filename = "sherpa-onnx-streaming-zipformer-en-20M-2023-02-17/encoder-epoch-99-avg-1.onnx"; | ||
| 25 | + const char *decoder_filename = "sherpa-onnx-streaming-zipformer-en-20M-2023-02-17/decoder-epoch-99-avg-1.onnx"; | ||
| 26 | + const char *joiner_filename = "sherpa-onnx-streaming-zipformer-en-20M-2023-02-17/joiner-epoch-99-avg-1.onnx"; | ||
| 27 | + const char *tokens_filename = "sherpa-onnx-streaming-zipformer-en-20M-2023-02-17/tokens.txt"; | ||
| 28 | + const char *provider = "cpu"; | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename); | ||
| 32 | + if (wave == NULL) { | ||
| 33 | + fprintf(stderr, "Failed to read %s\n", wav_filename); | ||
| 34 | + return -1; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + // Zipformer config | ||
| 38 | + SherpaOnnxOnlineTransducerModelConfig zipformer_config; | ||
| 39 | + memset(&zipformer_config, 0, sizeof(zipformer_config)); | ||
| 40 | + zipformer_config.encoder = encoder_filename; | ||
| 41 | + zipformer_config.decoder = decoder_filename; | ||
| 42 | + zipformer_config.joiner = joiner_filename; | ||
| 43 | + | ||
| 44 | + | ||
| 45 | + // Online model config | ||
| 46 | + SherpaOnnxOnlineModelConfig online_model_config; | ||
| 47 | + memset(&online_model_config, 0, sizeof(online_model_config)); | ||
| 48 | + online_model_config.debug = 1; | ||
| 49 | + online_model_config.num_threads = 1; | ||
| 50 | + online_model_config.provider = provider; | ||
| 51 | + online_model_config.tokens = tokens_filename; | ||
| 52 | + online_model_config.transducer = zipformer_config; | ||
| 53 | + | ||
| 54 | + // Recognizer config | ||
| 55 | + SherpaOnnxOnlineRecognizerConfig recognizer_config; | ||
| 56 | + memset(&recognizer_config, 0, sizeof(recognizer_config)); | ||
| 57 | + recognizer_config.decoding_method = "greedy_search"; | ||
| 58 | + recognizer_config.model_config = online_model_config; | ||
| 59 | + | ||
| 60 | + SherpaOnnxOnlineRecognizer *recognizer = | ||
| 61 | + SherpaOnnxCreateOnlineRecognizer(&recognizer_config); | ||
| 62 | + | ||
| 63 | + if (recognizer == NULL) { | ||
| 64 | + fprintf(stderr, "Please check your config!\n"); | ||
| 65 | + SherpaOnnxFreeWave(wave); | ||
| 66 | + return -1; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + SherpaOnnxOnlineStream *stream = SherpaOnnxCreateOnlineStream(recognizer); | ||
| 70 | + | ||
| 71 | + const SherpaOnnxDisplay *display = SherpaOnnxCreateDisplay(50); | ||
| 72 | + int32_t segment_id = 0; | ||
| 73 | + | ||
| 74 | +// simulate streaming. You can choose an arbitrary N | ||
| 75 | +#define N 3200 | ||
| 76 | + | ||
| 77 | + fprintf(stderr, "sample rate: %d, num samples: %d, duration: %.2f s\n", | ||
| 78 | + wave->sample_rate, wave->num_samples, | ||
| 79 | + (float)wave->num_samples / wave->sample_rate); | ||
| 80 | + | ||
| 81 | + int32_t k = 0; | ||
| 82 | + while (k < wave->num_samples) { | ||
| 83 | + int32_t start = k; | ||
| 84 | + int32_t end = | ||
| 85 | + (start + N > wave->num_samples) ? wave->num_samples : (start + N); | ||
| 86 | + k += N; | ||
| 87 | + | ||
| 88 | + SherpaOnnxOnlineStreamAcceptWaveform(stream, wave->sample_rate, | ||
| 89 | + wave->samples + start, end - start); | ||
| 90 | + while (SherpaOnnxIsOnlineStreamReady(recognizer, stream)) { | ||
| 91 | + SherpaOnnxDecodeOnlineStream(recognizer, stream); | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + const SherpaOnnxOnlineRecognizerResult *r = | ||
| 95 | + SherpaOnnxGetOnlineStreamResult(recognizer, stream); | ||
| 96 | + | ||
| 97 | + if (strlen(r->text)) { | ||
| 98 | + SherpaOnnxPrint(display, segment_id, r->text); | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + if (SherpaOnnxOnlineStreamIsEndpoint(recognizer, stream)) { | ||
| 102 | + if (strlen(r->text)) { | ||
| 103 | + ++segment_id; | ||
| 104 | + } | ||
| 105 | + SherpaOnnxOnlineStreamReset(recognizer, stream); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + SherpaOnnxDestroyOnlineRecognizerResult(r); | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + // add some tail padding | ||
| 112 | + float tail_paddings[4800] = {0}; // 0.3 seconds at 16 kHz sample rate | ||
| 113 | + SherpaOnnxOnlineStreamAcceptWaveform(stream, wave->sample_rate, tail_paddings, | ||
| 114 | + 4800); | ||
| 115 | + | ||
| 116 | + SherpaOnnxFreeWave(wave); | ||
| 117 | + | ||
| 118 | + SherpaOnnxOnlineStreamInputFinished(stream); | ||
| 119 | + while (SherpaOnnxIsOnlineStreamReady(recognizer, stream)) { | ||
| 120 | + SherpaOnnxDecodeOnlineStream(recognizer, stream); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + const SherpaOnnxOnlineRecognizerResult *r = | ||
| 124 | + SherpaOnnxGetOnlineStreamResult(recognizer, stream); | ||
| 125 | + | ||
| 126 | + if (strlen(r->text)) { | ||
| 127 | + SherpaOnnxPrint(display, segment_id, r->text); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + SherpaOnnxDestroyOnlineRecognizerResult(r); | ||
| 131 | + | ||
| 132 | + SherpaOnnxDestroyDisplay(display); | ||
| 133 | + SherpaOnnxDestroyOnlineStream(stream); | ||
| 134 | + SherpaOnnxDestroyOnlineRecognizer(recognizer); | ||
| 135 | + fprintf(stderr, "\n"); | ||
| 136 | + | ||
| 137 | + return 0; | ||
| 138 | +} |
c-api-examples/telespeech-c-api.c
0 → 100644
| 1 | +// c-api-examples/telespeech-c-api.c | ||
| 2 | +// | ||
| 3 | +// Copyright (c) 2024 Xiaomi Corporation | ||
| 4 | + | ||
| 5 | +// | ||
| 6 | +// This file demonstrates how to use TeleSpeech-ASR CTC model with sherpa-onnx's C API. | ||
| 7 | +// clang-format off | ||
| 8 | +// | ||
| 9 | +// wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04.tar.bz2 | ||
| 10 | +// tar xvf sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04.tar.bz2 | ||
| 11 | +// rm sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04.tar.bz2 | ||
| 12 | +// | ||
| 13 | +// clang-format on | ||
| 14 | + | ||
| 15 | +#include <stdio.h> | ||
| 16 | +#include <stdlib.h> | ||
| 17 | +#include <string.h> | ||
| 18 | + | ||
| 19 | +#include "sherpa-onnx/c-api/c-api.h" | ||
| 20 | + | ||
| 21 | +int32_t main() { | ||
| 22 | + | ||
| 23 | + const char *wav_filename = "sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04/test_wavs/3-sichuan.wav"; | ||
| 24 | + const char *model_filename = "sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04/model.int8.onnx"; | ||
| 25 | + const char *tokens_filename = "sherpa-onnx-telespeech-ctc-int8-zh-2024-06-04/tokens.txt"; | ||
| 26 | + const char *provider = "cpu"; | ||
| 27 | + | ||
| 28 | + const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename); | ||
| 29 | + if (wave == NULL) { | ||
| 30 | + fprintf(stderr, "Failed to read %s\n", wav_filename); | ||
| 31 | + return -1; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + // Offline model config | ||
| 35 | + SherpaOnnxOfflineModelConfig offline_model_config; | ||
| 36 | + memset(&offline_model_config, 0, sizeof(offline_model_config)); | ||
| 37 | + offline_model_config.debug = 1; | ||
| 38 | + offline_model_config.num_threads = 1; | ||
| 39 | + offline_model_config.provider = provider; | ||
| 40 | + offline_model_config.tokens = tokens_filename; | ||
| 41 | + offline_model_config.telespeech_ctc = model_filename; | ||
| 42 | + | ||
| 43 | + // Recognizer config | ||
| 44 | + SherpaOnnxOfflineRecognizerConfig recognizer_config; | ||
| 45 | + memset(&recognizer_config, 0, sizeof(recognizer_config)); | ||
| 46 | + recognizer_config.decoding_method = "greedy_search"; | ||
| 47 | + recognizer_config.model_config = offline_model_config; | ||
| 48 | + | ||
| 49 | + SherpaOnnxOfflineRecognizer *recognizer = | ||
| 50 | + SherpaOnnxCreateOfflineRecognizer(&recognizer_config); | ||
| 51 | + | ||
| 52 | + if (recognizer == NULL) { | ||
| 53 | + fprintf(stderr, "Please check your config!\n"); | ||
| 54 | + SherpaOnnxFreeWave(wave); | ||
| 55 | + return -1; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + SherpaOnnxOfflineStream *stream = SherpaOnnxCreateOfflineStream(recognizer); | ||
| 59 | + | ||
| 60 | + SherpaOnnxAcceptWaveformOffline(stream, wave->sample_rate, wave->samples, | ||
| 61 | + wave->num_samples); | ||
| 62 | + SherpaOnnxDecodeOfflineStream(recognizer, stream); | ||
| 63 | + const SherpaOnnxOfflineRecognizerResult *result = | ||
| 64 | + SherpaOnnxGetOfflineStreamResult(stream); | ||
| 65 | + | ||
| 66 | + fprintf(stderr, "Decoded text: %s\n", result->text); | ||
| 67 | + | ||
| 68 | + SherpaOnnxDestroyOfflineRecognizerResult(result); | ||
| 69 | + SherpaOnnxDestroyOfflineStream(stream); | ||
| 70 | + SherpaOnnxDestroyOfflineRecognizer(recognizer); | ||
| 71 | + SherpaOnnxFreeWave(wave); | ||
| 72 | + | ||
| 73 | + return 0; | ||
| 74 | +} |
c-api-examples/zipformer-c-api.c
0 → 100644
| 1 | +// c-api-examples/zipformer-c-api.c | ||
| 2 | +// | ||
| 3 | +// Copyright (c) 2024 Xiaomi Corporation | ||
| 4 | + | ||
| 5 | +// | ||
| 6 | +// This file demonstrates how to use non-streaming Zipformer with sherpa-onnx's C API. | ||
| 7 | +// clang-format off | ||
| 8 | +// | ||
| 9 | +// wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-zipformer-small-en-2023-06-26.tar.bz2 | ||
| 10 | +// tar xvf sherpa-onnx-zipformer-small-en-2023-06-26.tar.bz2 | ||
| 11 | +// rm sherpa-onnx-zipformer-small-en-2023-06-26.tar.bz2 | ||
| 12 | +// | ||
| 13 | +// clang-format on | ||
| 14 | + | ||
| 15 | +#include <stdio.h> | ||
| 16 | +#include <stdlib.h> | ||
| 17 | +#include <string.h> | ||
| 18 | + | ||
| 19 | +#include "sherpa-onnx/c-api/c-api.h" | ||
| 20 | + | ||
| 21 | +int32_t main() { | ||
| 22 | + | ||
| 23 | + const char *wav_filename = "sherpa-onnx-zipformer-small-en-2023-06-26/test_wavs/0.wav"; | ||
| 24 | + const char *encoder_filename = "sherpa-onnx-zipformer-small-en-2023-06-26/encoder-epoch-99-avg-1.onnx"; | ||
| 25 | + const char *decoder_filename = "sherpa-onnx-zipformer-small-en-2023-06-26/decoder-epoch-99-avg-1.onnx"; | ||
| 26 | + const char *joiner_filename = "sherpa-onnx-zipformer-small-en-2023-06-26/joiner-epoch-99-avg-1.onnx"; | ||
| 27 | + const char *tokens_filename = "sherpa-onnx-zipformer-small-en-2023-06-26/tokens.txt"; | ||
| 28 | + const char *provider = "cpu"; | ||
| 29 | + | ||
| 30 | + | ||
| 31 | + const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename); | ||
| 32 | + if (wave == NULL) { | ||
| 33 | + fprintf(stderr, "Failed to read %s\n", wav_filename); | ||
| 34 | + return -1; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + // Zipformer config | ||
| 38 | + SherpaOnnxOfflineTransducerModelConfig zipformer_config; | ||
| 39 | + memset(&zipformer_config, 0, sizeof(zipformer_config)); | ||
| 40 | + zipformer_config.encoder = encoder_filename; | ||
| 41 | + zipformer_config.decoder = decoder_filename; | ||
| 42 | + zipformer_config.joiner = joiner_filename; | ||
| 43 | + | ||
| 44 | + | ||
| 45 | + // Offline model config | ||
| 46 | + SherpaOnnxOfflineModelConfig offline_model_config; | ||
| 47 | + memset(&offline_model_config, 0, sizeof(offline_model_config)); | ||
| 48 | + offline_model_config.debug = 1; | ||
| 49 | + offline_model_config.num_threads = 1; | ||
| 50 | + offline_model_config.provider = provider; | ||
| 51 | + offline_model_config.tokens = tokens_filename; | ||
| 52 | + offline_model_config.transducer = zipformer_config; | ||
| 53 | + | ||
| 54 | + // Recognizer config | ||
| 55 | + SherpaOnnxOfflineRecognizerConfig recognizer_config; | ||
| 56 | + memset(&recognizer_config, 0, sizeof(recognizer_config)); | ||
| 57 | + recognizer_config.decoding_method = "greedy_search"; | ||
| 58 | + recognizer_config.model_config = offline_model_config; | ||
| 59 | + | ||
| 60 | + SherpaOnnxOfflineRecognizer *recognizer = | ||
| 61 | + SherpaOnnxCreateOfflineRecognizer(&recognizer_config); | ||
| 62 | + | ||
| 63 | + if (recognizer == NULL) { | ||
| 64 | + fprintf(stderr, "Please check your config!\n"); | ||
| 65 | + SherpaOnnxFreeWave(wave); | ||
| 66 | + return -1; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + SherpaOnnxOfflineStream *stream = SherpaOnnxCreateOfflineStream(recognizer); | ||
| 70 | + | ||
| 71 | + SherpaOnnxAcceptWaveformOffline(stream, wave->sample_rate, wave->samples, | ||
| 72 | + wave->num_samples); | ||
| 73 | + SherpaOnnxDecodeOfflineStream(recognizer, stream); | ||
| 74 | + const SherpaOnnxOfflineRecognizerResult *result = | ||
| 75 | + SherpaOnnxGetOfflineStreamResult(stream); | ||
| 76 | + | ||
| 77 | + fprintf(stderr, "Decoded text: %s\n", result->text); | ||
| 78 | + | ||
| 79 | + SherpaOnnxDestroyOfflineRecognizerResult(result); | ||
| 80 | + SherpaOnnxDestroyOfflineStream(stream); | ||
| 81 | + SherpaOnnxDestroyOfflineRecognizer(recognizer); | ||
| 82 | + SherpaOnnxFreeWave(wave); | ||
| 83 | + | ||
| 84 | + return 0; | ||
| 85 | +} |
-
请 注册 或 登录 后发表评论