Fangjun Kuang
Committed by GitHub

C api (#60)

@@ -69,3 +69,11 @@ jobs: @@ -69,3 +69,11 @@ jobs:
69 export EXE=sherpa-onnx 69 export EXE=sherpa-onnx
70 70
71 .github/scripts/test-online-transducer.sh 71 .github/scripts/test-online-transducer.sh
  72 +
  73 + - name: Test online transducer (C API)
  74 + shell: bash
  75 + run: |
  76 + export PATH=$PWD/build/bin:$PATH
  77 + export EXE=decode-file-c-api
  78 +
  79 + .github/scripts/test-online-transducer.sh
@@ -71,3 +71,11 @@ jobs: @@ -71,3 +71,11 @@ jobs:
71 export EXE=sherpa-onnx 71 export EXE=sherpa-onnx
72 72
73 .github/scripts/test-online-transducer.sh 73 .github/scripts/test-online-transducer.sh
  74 +
  75 + - name: Test online transducer (C API)
  76 + shell: bash
  77 + run: |
  78 + export PATH=$PWD/build/bin:$PATH
  79 + export EXE=decode-file-c-api
  80 +
  81 + .github/scripts/test-online-transducer.sh
@@ -78,3 +78,11 @@ jobs: @@ -78,3 +78,11 @@ jobs:
78 export EXE=sherpa-onnx.exe 78 export EXE=sherpa-onnx.exe
79 79
80 .github/scripts/test-online-transducer.sh 80 .github/scripts/test-online-transducer.sh
  81 +
  82 + - name: Test online transducer (C API)
  83 + shell: bash
  84 + run: |
  85 + export PATH=$PWD/build/bin/Release:$PATH
  86 + export EXE=decode-file-c-api.exe
  87 +
  88 + .github/scripts/test-online-transducer.sh
@@ -18,3 +18,5 @@ a.txt @@ -18,3 +18,5 @@ a.txt
18 run-bilingual*.sh 18 run-bilingual*.sh
19 run-*-zipformer.sh 19 run-*-zipformer.sh
20 run-zh.sh 20 run-zh.sh
  21 +decode-file-c-api
  22 +run-decode-file-c-api.sh
@@ -17,6 +17,7 @@ option(SHERPA_ONNX_ENABLE_CHECK "Whether to build with assert" ON) @@ -17,6 +17,7 @@ option(SHERPA_ONNX_ENABLE_CHECK "Whether to build with assert" ON)
17 option(BUILD_SHARED_LIBS "Whether to build shared libraries" OFF) 17 option(BUILD_SHARED_LIBS "Whether to build shared libraries" OFF)
18 option(SHERPA_ONNX_ENABLE_PORTAUDIO "Whether to build with portaudio" ON) 18 option(SHERPA_ONNX_ENABLE_PORTAUDIO "Whether to build with portaudio" ON)
19 option(SHERPA_ONNX_ENABLE_JNI "Whether to build JNI internface" OFF) 19 option(SHERPA_ONNX_ENABLE_JNI "Whether to build JNI internface" OFF)
  20 +option(SHERPA_ONNX_ENABLE_C_API "Whether to build C API" ON)
20 21
21 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") 22 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
22 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") 23 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
@@ -91,3 +92,7 @@ if(SHERPA_ONNX_ENABLE_TESTS) @@ -91,3 +92,7 @@ if(SHERPA_ONNX_ENABLE_TESTS)
91 endif() 92 endif()
92 93
93 add_subdirectory(sherpa-onnx) 94 add_subdirectory(sherpa-onnx)
  95 +
  96 +if(SHERPA_ONNX_ENABLE_C_API)
  97 + add_subdirectory(c-api-examples)
  98 +endif()
  1 +include_directories(${CMAKE_SOURCE_DIR})
  2 +add_executable(decode-file-c-api decode-file-c-api.c)
  3 +target_link_libraries(decode-file-c-api sherpa-onnx-c-api)
  1 +
  2 +CFLAGS := -I ../
  3 +LDFLAGS := -L ../build/lib
  4 +LDFLAGS += -L ../build/_deps/onnxruntime-src/lib
  5 +LDFLAGS += -lsherpa-onnx-c-api -lsherpa-onnx-core -lonnxruntime -lkaldi-native-fbank-core
  6 +LDFLAGS += -Wl,-rpath,../build/lib
  7 +LDFLAGS += -Wl,-rpath,../build/_deps/onnxruntime-src/lib
  8 +
  9 +decode-file-c-api: decode-file-c-api.c
  10 + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
  1 +// c-api-examples/decode-file-c-api.cc
  2 +//
  3 +// Copyright (c) 2023 Xiaomi Corporation
  4 +
  5 +#include <stdio.h>
  6 +#include <stdlib.h>
  7 +#include <string.h>
  8 +
  9 +#include "sherpa-onnx/c-api/c-api.h"
  10 +
  11 +const char *kUsage =
  12 + "\n"
  13 + "Usage:\n "
  14 + " ./bin/decode-file-c-api \\\n"
  15 + " /path/to/tokens.txt \\\n"
  16 + " /path/to/encoder.onnx \\\n"
  17 + " /path/to/decoder.onnx \\\n"
  18 + " /path/to/joiner.onnx \\\n"
  19 + " /path/to/foo.wav [num_threads]\n"
  20 + "\n\n"
  21 + "Please refer to \n"
  22 + "https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html\n"
  23 + "for a list of pre-trained models to download.\n";
  24 +
  25 +int32_t main(int32_t argc, char *argv[]) {
  26 + if (argc < 6 || argc > 7) {
  27 + fprintf(stderr, "%s\n", kUsage);
  28 + return -1;
  29 + }
  30 + SherpaOnnxOnlineRecognizerConfig config;
  31 + config.model_config.tokens = argv[1];
  32 + config.model_config.encoder = argv[2];
  33 + config.model_config.decoder = argv[3];
  34 + config.model_config.joiner = argv[4];
  35 +
  36 + int32_t num_threads = 4;
  37 + if (argc == 7 && atoi(argv[6]) > 0) {
  38 + num_threads = atoi(argv[6]);
  39 + }
  40 + config.model_config.num_threads = num_threads;
  41 + config.model_config.debug = 0;
  42 +
  43 + config.feat_config.sample_rate = 16000;
  44 + config.feat_config.feature_dim = 80;
  45 +
  46 + config.enable_endpoint = 1;
  47 + config.rule1_min_trailing_silence = 2.4;
  48 + config.rule2_min_trailing_silence = 1.2;
  49 + config.rule3_min_utterance_length = 300;
  50 +
  51 + SherpaOnnxOnlineRecognizer *recognizer = CreateOnlineRecognizer(&config);
  52 + SherpaOnnxOnlineStream *stream = CreateOnlineStream(recognizer);
  53 +
  54 + const char *wav_filename = argv[5];
  55 + FILE *fp = fopen(wav_filename, "rb");
  56 + if (!fp) {
  57 + fprintf(stderr, "Failed to open %s\n", wav_filename);
  58 + return -1;
  59 + }
  60 +
  61 + // Assume the wave header occupies 44 bytes.
  62 + fseek(fp, 44, SEEK_SET);
  63 +
  64 + // simulate streaming
  65 +
  66 +#define N 3200 // 0.2 s. Sample rate is fixed to 16 kHz
  67 +
  68 + int16_t buffer[N];
  69 + float samples[N];
  70 +
  71 + while (!feof(fp)) {
  72 + size_t n = fread((void *)buffer, sizeof(int16_t), N, fp);
  73 + if (n > 0) {
  74 + for (size_t i = 0; i != n; ++i) {
  75 + samples[i] = buffer[i] / 32768.;
  76 + }
  77 + AcceptWaveform(stream, 16000, samples, n);
  78 + while (IsOnlineStreamReady(recognizer, stream)) {
  79 + DecodeOnlineStream(recognizer, stream);
  80 + }
  81 +
  82 + SherpaOnnxOnlineRecognizerResult *r =
  83 + GetOnlineStreamResult(recognizer, stream);
  84 + if (strlen(r->text)) {
  85 + fprintf(stderr, "%s\n", r->text);
  86 + }
  87 + DestroyOnlineRecognizerResult(r);
  88 + }
  89 + }
  90 + fclose(fp);
  91 +
  92 + // add some tail padding
  93 + float tail_paddings[4800] = {0}; // 0.3 seconds at 16 kHz sample rate
  94 + AcceptWaveform(stream, 16000, tail_paddings, 4800);
  95 +
  96 + InputFinished(stream);
  97 + while (IsOnlineStreamReady(recognizer, stream)) {
  98 + DecodeOnlineStream(recognizer, stream);
  99 + }
  100 +
  101 + SherpaOnnxOnlineRecognizerResult *r =
  102 + GetOnlineStreamResult(recognizer, stream);
  103 + if (strlen(r->text)) {
  104 + fprintf(stderr, "%s\n", r->text);
  105 + }
  106 +
  107 + DestroyOnlineRecognizerResult(r);
  108 +
  109 + DestoryOnlineStream(stream);
  110 + DestroyOnlineRecognizer(recognizer);
  111 +
  112 + return 0;
  113 +}
@@ -6,3 +6,7 @@ endif() @@ -6,3 +6,7 @@ endif()
6 if(SHERPA_ONNX_ENABLE_JNI) 6 if(SHERPA_ONNX_ENABLE_JNI)
7 add_subdirectory(jni) 7 add_subdirectory(jni)
8 endif() 8 endif()
  9 +
  10 +if(SHERPA_ONNX_ENABLE_C_API)
  11 + add_subdirectory(c-api)
  12 +endif()
  1 +include_directories(${CMAKE_SOURCE_DIR})
  2 +add_library(sherpa-onnx-c-api c-api.cc)
  3 +target_link_libraries(sherpa-onnx-c-api sherpa-onnx-core)
  4 +
  5 +install(TARGETS sherpa-onnx-c-api DESTINATION lib)
  6 +
  7 +install(FILES c-api.h
  8 + DESTINATION include/sherpa-onnx/c-api
  9 +)
  10 +
  1 +// sherpa-onnx/c-api/c-api.cc
  2 +//
  3 +// Copyright (c) 2023 Xiaomi Corporation
  4 +
  5 +#include "sherpa-onnx/c-api/c-api.h"
  6 +
  7 +#include <algorithm>
  8 +#include <memory>
  9 +#include <utility>
  10 +#include <vector>
  11 +
  12 +#include "sherpa-onnx/csrc/online-recognizer.h"
  13 +
  14 +struct SherpaOnnxOnlineRecognizer {
  15 + sherpa_onnx::OnlineRecognizer *impl;
  16 +};
  17 +
  18 +struct SherpaOnnxOnlineStream {
  19 + std::unique_ptr<sherpa_onnx::OnlineStream> impl;
  20 + explicit SherpaOnnxOnlineStream(std::unique_ptr<sherpa_onnx::OnlineStream> p)
  21 + : impl(std::move(p)) {}
  22 +};
  23 +
  24 +SherpaOnnxOnlineRecognizer *CreateOnlineRecognizer(
  25 + const SherpaOnnxOnlineRecognizerConfig *config) {
  26 + sherpa_onnx::OnlineRecognizerConfig recognizer_config;
  27 +
  28 + recognizer_config.feat_config.sampling_rate = config->feat_config.sample_rate;
  29 + recognizer_config.feat_config.feature_dim = config->feat_config.feature_dim;
  30 +
  31 + recognizer_config.model_config.encoder_filename =
  32 + config->model_config.encoder;
  33 + recognizer_config.model_config.decoder_filename =
  34 + config->model_config.decoder;
  35 + recognizer_config.model_config.joiner_filename = config->model_config.joiner;
  36 + recognizer_config.model_config.tokens = config->model_config.tokens;
  37 + recognizer_config.model_config.num_threads = config->model_config.num_threads;
  38 + recognizer_config.model_config.debug = config->model_config.debug;
  39 +
  40 + recognizer_config.enable_endpoint = config->enable_endpoint;
  41 +
  42 + recognizer_config.endpoint_config.rule1.min_trailing_silence =
  43 + config->rule1_min_trailing_silence;
  44 +
  45 + recognizer_config.endpoint_config.rule2.min_trailing_silence =
  46 + config->rule2_min_trailing_silence;
  47 +
  48 + recognizer_config.endpoint_config.rule3.min_utterance_length =
  49 + config->rule3_min_utterance_length;
  50 +
  51 + SherpaOnnxOnlineRecognizer *recognizer = new SherpaOnnxOnlineRecognizer;
  52 + recognizer->impl = new sherpa_onnx::OnlineRecognizer(recognizer_config);
  53 +
  54 + return recognizer;
  55 +}
  56 +
  57 +void DestroyOnlineRecognizer(SherpaOnnxOnlineRecognizer *recognizer) {
  58 + delete recognizer->impl;
  59 + delete recognizer;
  60 +}
  61 +
  62 +SherpaOnnxOnlineStream *CreateOnlineStream(
  63 + const SherpaOnnxOnlineRecognizer *recognizer) {
  64 + SherpaOnnxOnlineStream *stream =
  65 + new SherpaOnnxOnlineStream(recognizer->impl->CreateStream());
  66 + return stream;
  67 +}
  68 +
  69 +void DestoryOnlineStream(SherpaOnnxOnlineStream *stream) { delete stream; }
  70 +
  71 +void AcceptWaveform(SherpaOnnxOnlineStream *stream, float sample_rate,
  72 + const float *samples, int32_t n) {
  73 + stream->impl->AcceptWaveform(sample_rate, samples, n);
  74 +}
  75 +
  76 +int32_t IsOnlineStreamReady(SherpaOnnxOnlineRecognizer *recognizer,
  77 + SherpaOnnxOnlineStream *stream) {
  78 + return recognizer->impl->IsReady(stream->impl.get());
  79 +}
  80 +
  81 +void DecodeOnlineStream(SherpaOnnxOnlineRecognizer *recognizer,
  82 + SherpaOnnxOnlineStream *stream) {
  83 + recognizer->impl->DecodeStream(stream->impl.get());
  84 +}
  85 +
  86 +void DecodeMultipleOnlineStreams(SherpaOnnxOnlineRecognizer *recognizer,
  87 + SherpaOnnxOnlineStream **streams, int32_t n) {
  88 + std::vector<sherpa_onnx::OnlineStream *> ss(n);
  89 + for (int32_t i = 0; i != n; ++n) {
  90 + ss[i] = streams[i]->impl.get();
  91 + }
  92 + recognizer->impl->DecodeStreams(ss.data(), n);
  93 +}
  94 +
  95 +SherpaOnnxOnlineRecognizerResult *GetOnlineStreamResult(
  96 + SherpaOnnxOnlineRecognizer *recognizer, SherpaOnnxOnlineStream *stream) {
  97 + sherpa_onnx::OnlineRecognizerResult result =
  98 + recognizer->impl->GetResult(stream->impl.get());
  99 + const auto &text = result.text;
  100 +
  101 + auto r = new SherpaOnnxOnlineRecognizerResult;
  102 + r->text = new char[text.size() + 1];
  103 + std::copy(text.begin(), text.end(), const_cast<char *>(r->text));
  104 + const_cast<char *>(r->text)[text.size()] = 0;
  105 +
  106 + return r;
  107 +}
  108 +
  109 +void DestroyOnlineRecognizerResult(const SherpaOnnxOnlineRecognizerResult *r) {
  110 + delete[] r->text;
  111 + delete r;
  112 +}
  113 +
  114 +void Reset(SherpaOnnxOnlineRecognizer *recognizer,
  115 + SherpaOnnxOnlineStream *stream) {
  116 + recognizer->impl->Reset(stream->impl.get());
  117 +}
  118 +
  119 +void InputFinished(SherpaOnnxOnlineStream *stream) {
  120 + stream->impl->InputFinished();
  121 +}
  122 +
  123 +int32_t IsEndpoint(SherpaOnnxOnlineRecognizer *recognizer,
  124 + SherpaOnnxOnlineStream *stream) {
  125 + return recognizer->impl->IsEndpoint(stream->impl.get());
  126 +}
  1 +// sherpa-onnx/c-api/c-api.h
  2 +//
  3 +// Copyright (c) 2023 Xiaomi Corporation
  4 +
  5 +// C API for sherpa-onnx
  6 +//
  7 +// Please refer to
  8 +// https://github.com/k2-fsa/sherpa-onnx/blob/master/c-api-examples/decode-file-c-api.c
  9 +// for usages.
  10 +//
  11 +
  12 +#ifndef SHERPA_ONNX_C_API_C_API_H_
  13 +#define SHERPA_ONNX_C_API_C_API_H_
  14 +
  15 +#include <stdint.h>
  16 +
  17 +#ifdef __cplusplus
  18 +extern "C" {
  19 +#endif
  20 +
  21 +/// Please refer to
  22 +/// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
  23 +/// to download pre-trained models. That is, you can find encoder-xxx.onnx
  24 +/// decoder-xxx.onnx, joiner-xxx.onnx, and tokens.txt for this struct
  25 +/// from there.
  26 +typedef struct SherpaOnnxOnlineTransducerModelConfig {
  27 + const char *encoder;
  28 + const char *decoder;
  29 + const char *joiner;
  30 + const char *tokens;
  31 + int32_t num_threads;
  32 + int32_t debug; // true to print debug information of the model
  33 +} SherpaOnnxOnlineTransducerModelConfig;
  34 +
  35 +/// It expects 16 kHz 16-bit single channel wave format.
  36 +typedef struct SherpaOnnxFeatureConfig {
  37 + /// Sample rate of the input data. MUST match the one expected
  38 + /// by the model. For instance, it should be 16000 for models provided
  39 + /// by us.
  40 + int32_t sample_rate;
  41 +
  42 + /// Feature dimension of the model.
  43 + /// For instance, it should be 80 for models provided by us.
  44 + int32_t feature_dim;
  45 +} SherpaOnnxFeatureConfig;
  46 +
  47 +typedef struct SherpaOnnxOnlineRecognizerConfig {
  48 + SherpaOnnxFeatureConfig feat_config;
  49 + SherpaOnnxOnlineTransducerModelConfig model_config;
  50 +
  51 + /// 0 to disable endpoint detection.
  52 + /// A non-zero value to enable endpoint detection.
  53 + int32_t enable_endpoint;
  54 +
  55 + /// An endpoint is detected if trailing silence in seconds is larger than
  56 + /// this value even if nothing has been decoded.
  57 + /// Used only when enable_endpoint is not 0.
  58 + float rule1_min_trailing_silence;
  59 +
  60 + /// An endpoint is detected if trailing silence in seconds is larger than
  61 + /// this value after something that is not blank has been decoded.
  62 + /// Used only when enable_endpoint is not 0.
  63 + float rule2_min_trailing_silence;
  64 +
  65 + /// An endpoint is detected if the utterance in seconds is larger than
  66 + /// this value.
  67 + /// Used only when enable_endpoint is not 0.
  68 + float rule3_min_utterance_length;
  69 +} SherpaOnnxOnlineRecognizerConfig;
  70 +
  71 +typedef struct SherpaOnnxOnlineRecognizerResult {
  72 + const char *text;
  73 + // TODO(fangjun): Add more fields
  74 +} SherpaOnnxOnlineRecognizerResult;
  75 +
  76 +/// Note: OnlineRecognizer here means StreamingRecognizer.
  77 +/// It does not need to access the Internet during recognition.
  78 +/// Everything is run locally.
  79 +typedef struct SherpaOnnxOnlineRecognizer SherpaOnnxOnlineRecognizer;
  80 +typedef struct SherpaOnnxOnlineStream SherpaOnnxOnlineStream;
  81 +
  82 +/// @param config Config for the recongizer.
  83 +/// @return Return a pointer to the recognizer. The user has to invoke
  84 +// DestroyOnlineRecognizer() to free it to avoid memory leak.
  85 +SherpaOnnxOnlineRecognizer *CreateOnlineRecognizer(
  86 + const SherpaOnnxOnlineRecognizerConfig *config);
  87 +
  88 +/// Free a pointer returned by CreateOnlineRecognizer()
  89 +///
  90 +/// @param p A pointer returned by CreateOnlineRecognizer()
  91 +void DestroyOnlineRecognizer(SherpaOnnxOnlineRecognizer *recognizer);
  92 +
  93 +/// Create an online stream for accepting wave samples.
  94 +///
  95 +/// @param recognizer A pointer returned by CreateOnlineRecognizer()
  96 +/// @return Return a pointer to an OnlineStream. The user has to invoke
  97 +/// DestoryOnlineStream() to free it to avoid memory leak.
  98 +SherpaOnnxOnlineStream *CreateOnlineStream(
  99 + const SherpaOnnxOnlineRecognizer *recognizer);
  100 +
  101 +/// Destory an online stream.
  102 +///
  103 +/// @param stream A pointer returned by CreateOnlineStream()
  104 +void DestoryOnlineStream(SherpaOnnxOnlineStream *stream);
  105 +
  106 +/// Accept input audio samples and compute the features.
  107 +/// The user has to invoke DecodeOnlineStream() to run the neural network and
  108 +/// decoding.
  109 +///
  110 +/// @param stream A pointer returned by CreateOnlineStream().
  111 +/// @param sample_rate Sampler rate of the input samples. It has to be 16 kHz
  112 +/// for models from icefall.
  113 +/// @param samples A pointer to a 1-D array containing audio samples.
  114 +/// The range of samples has to be normalized to [-1, 1].
  115 +/// @param n Number of elements in the samples array.
  116 +void AcceptWaveform(SherpaOnnxOnlineStream *stream, float sample_rate,
  117 + const float *samples, int32_t n);
  118 +
  119 +/// Return 1 if there are enough number of feature frames for decoding.
  120 +/// Return 0 otherwise.
  121 +///
  122 +/// @param recognizer A pointer returned by CreateOnlineRecognizer
  123 +/// @param stream A pointer returned by CreateOnlineStream
  124 +int32_t IsOnlineStreamReady(SherpaOnnxOnlineRecognizer *recognizer,
  125 + SherpaOnnxOnlineStream *stream);
  126 +
  127 +/// Call this function to run the neural network model and decoding.
  128 +//
  129 +/// Precondition for this function: IsOnlineStreamReady() MUST return 1.
  130 +///
  131 +/// Usage example:
  132 +///
  133 +/// while (IsOnlineStreamReady(recognizer, stream)) {
  134 +/// DecodeOnlineStream(recognizer, stream);
  135 +/// }
  136 +///
  137 +void DecodeOnlineStream(SherpaOnnxOnlineRecognizer *recognizer,
  138 + SherpaOnnxOnlineStream *stream);
  139 +
  140 +/// This function is similar to DecodeOnlineStream(). It decodes multiple
  141 +/// OnlineStream in parallel.
  142 +///
  143 +/// Caution: The caller has to ensure each OnlineStream is ready, i.e.,
  144 +/// IsOnlineStreamReady() for that stream should return 1.
  145 +///
  146 +/// @param recognizer A pointer returned by CreateOnlineRecognizer()
  147 +/// @param streams A pointer array containing pointers returned by
  148 +/// CreateOnlineRecognizer()
  149 +/// @param n Number of elements in the given streams array.
  150 +void DecodeMultipleOnlineStreams(SherpaOnnxOnlineRecognizer *recognizer,
  151 + SherpaOnnxOnlineStream **streams, int32_t n);
  152 +
  153 +/// Get the decoding results so far for an OnlineStream.
  154 +///
  155 +/// @param recognizer A pointer returned by CreateOnlineRecognizer().
  156 +/// @param stream A pointer returned by CreateOnlineStream().
  157 +/// @return A pointer containing the result. The user has to invoke
  158 +/// DestroyOnlineRecognizerResult() to free the returned pointer to
  159 +/// avoid memory leak.
  160 +SherpaOnnxOnlineRecognizerResult *GetOnlineStreamResult(
  161 + SherpaOnnxOnlineRecognizer *recognizer, SherpaOnnxOnlineStream *stream);
  162 +
  163 +/// Destroy the pointer returned by GetOnlineStreamResult().
  164 +///
  165 +/// @param r A pointer returned by GetOnlineStreamResult()
  166 +void DestroyOnlineRecognizerResult(const SherpaOnnxOnlineRecognizerResult *r);
  167 +
  168 +/// Reset an OnlineStream , which clears the neural network model state
  169 +/// and the state for decoding.
  170 +///
  171 +/// @param recognizer A pointer returned by CreateOnlineRecognizer().
  172 +/// @param stream A pointer returned by CreateOnlineStream
  173 +void Reset(SherpaOnnxOnlineRecognizer *recognizer,
  174 + SherpaOnnxOnlineStream *stream);
  175 +
  176 +/// Signal that no more audio samples would be available.
  177 +/// After this call, you cannot call AcceptWaveform() any more.
  178 +///
  179 +/// @param stream A pointer returned by CreateOnlineStream()
  180 +void InputFinished(SherpaOnnxOnlineStream *stream);
  181 +
  182 +/// Return 1 if an endpoint has been detected.
  183 +///
  184 +/// @param recognizer A pointer returned by CreateOnlineRecognizer()
  185 +/// @param stream A pointer returned by CreateOnlineStream()
  186 +/// @return Return 1 if an endpoint is detected. Return 0 otherwise.
  187 +int32_t IsEndpoint(SherpaOnnxOnlineRecognizer *recognizer,
  188 + SherpaOnnxOnlineStream *stream);
  189 +
  190 +#ifdef __cplusplus
  191 +} /* extern "C" */
  192 +#endif
  193 +
  194 +#endif // SHERPA_ONNX_C_API_C_API_H_