Han Zhu
Committed by GitHub

Add more C API examples (#1255)

C API examples for zipformer, paraformer, and TeleSpeech-ASR CTC models.
@@ -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)
  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(&paraformer_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 +}
  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(&paraformer_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 +}
  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 +}
  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 +}
1 -// c-api-examples/offline-stt-c-api.c 1 +// c-api-examples/whisper-c-api.c
2 // 2 //
3 // Copyright (c) 2024 Xiaomi Corporation 3 // Copyright (c) 2024 Xiaomi Corporation
4 4
  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 +}