Repository navigation
Add C API for Omnilingual ASR CTC models #2773
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,82 @@ | ||||||||||||||||||||||||||||||
| // c-api-examples/omnilingual-asr-ctc-c-api.c | ||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||
| // Copyright (c) 2025 Xiaomi Corporation | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||
| // This file demonstrates how to use Omnilingual ASR with sherpa-onnx's C API. | ||||||||||||||||||||||||||||||
| // clang-format off | ||||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||||
| wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2 | ||||||||||||||||||||||||||||||
| tar xvf sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2 | ||||||||||||||||||||||||||||||
| rm sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12.tar.bz2 | ||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||
| // clang-format on | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #include <stdio.h> | ||||||||||||||||||||||||||||||
| #include <stdlib.h> | ||||||||||||||||||||||||||||||
| #include <string.h> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #include "sherpa-onnx/c-api/c-api.h" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| int32_t main() { | ||||||||||||||||||||||||||||||
| // clang-format off | ||||||||||||||||||||||||||||||
| const char *wav_filename = "./sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12/test_wavs/en.wav"; | ||||||||||||||||||||||||||||||
| const char *model_filename = "./sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12/model.int8.onnx"; | ||||||||||||||||||||||||||||||
| const char *tokens_filename = "./sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12/tokens.txt"; | ||||||||||||||||||||||||||||||
| // clang-format on | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const char *provider = "cpu"; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename); | ||||||||||||||||||||||||||||||
| if (wave == NULL) { | ||||||||||||||||||||||||||||||
| fprintf(stderr, "Failed to read %s\n", wav_filename); | ||||||||||||||||||||||||||||||
| return -1; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| SherpaOnnxOfflineOmnilingualAsrCtcModelConfig omnilingual; | ||||||||||||||||||||||||||||||
| memset(&omnilingual, 0, sizeof(omnilingual)); | ||||||||||||||||||||||||||||||
| omnilingual.model = model_filename; | ||||||||||||||||||||||||||||||
|
Comment on lines
+37
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using
Suggested change
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Offline model config | ||||||||||||||||||||||||||||||
| SherpaOnnxOfflineModelConfig offline_model_config; | ||||||||||||||||||||||||||||||
| memset(&offline_model_config, 0, sizeof(offline_model_config)); | ||||||||||||||||||||||||||||||
| offline_model_config.debug = 1; | ||||||||||||||||||||||||||||||
| offline_model_config.num_threads = 1; | ||||||||||||||||||||||||||||||
| offline_model_config.provider = provider; | ||||||||||||||||||||||||||||||
| offline_model_config.tokens = tokens_filename; | ||||||||||||||||||||||||||||||
| offline_model_config.omnilingual = omnilingual; | ||||||||||||||||||||||||||||||
|
Comment on lines
+42
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For better readability and safety, consider using C99 designated initializers instead of
Suggested change
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| // Recognizer config | ||||||||||||||||||||||||||||||
| SherpaOnnxOfflineRecognizerConfig recognizer_config; | ||||||||||||||||||||||||||||||
| memset(&recognizer_config, 0, sizeof(recognizer_config)); | ||||||||||||||||||||||||||||||
| recognizer_config.decoding_method = "greedy_search"; | ||||||||||||||||||||||||||||||
| recognizer_config.model_config = offline_model_config; | ||||||||||||||||||||||||||||||
|
Comment on lines
+51
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to previous comments, using C99 designated initializers here would make the code more modern, readable, and safe.
Suggested change
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const SherpaOnnxOfflineRecognizer *recognizer = | ||||||||||||||||||||||||||||||
| SherpaOnnxCreateOfflineRecognizer(&recognizer_config); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (recognizer == NULL) { | ||||||||||||||||||||||||||||||
| fprintf(stderr, "Please check your config!\n"); | ||||||||||||||||||||||||||||||
| SherpaOnnxFreeWave(wave); | ||||||||||||||||||||||||||||||
| return -1; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const SherpaOnnxOfflineStream *stream = | ||||||||||||||||||||||||||||||
| SherpaOnnxCreateOfflineStream(recognizer); | ||||||||||||||||||||||||||||||
|
Comment on lines
+65
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's good practice to check the return value of if (stream == NULL) {
fprintf(stderr, "Failed to create offline stream\n");
SherpaOnnxDestroyOfflineRecognizer(recognizer);
SherpaOnnxFreeWave(wave);
return -1;
} |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| SherpaOnnxAcceptWaveformOffline(stream, wave->sample_rate, wave->samples, | ||||||||||||||||||||||||||||||
| wave->num_samples); | ||||||||||||||||||||||||||||||
| SherpaOnnxDecodeOfflineStream(recognizer, stream); | ||||||||||||||||||||||||||||||
| const SherpaOnnxOfflineRecognizerResult *result = | ||||||||||||||||||||||||||||||
| SherpaOnnxGetOfflineStreamResult(stream); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| fprintf(stderr, "Decoded text: %s\n", result->text); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| SherpaOnnxDestroyOfflineRecognizerResult(result); | ||||||||||||||||||||||||||||||
| SherpaOnnxDestroyOfflineStream(stream); | ||||||||||||||||||||||||||||||
| SherpaOnnxDestroyOfflineRecognizer(recognizer); | ||||||||||||||||||||||||||||||
| SherpaOnnxFreeWave(wave); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| return 0; | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The directory path
sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12is repeated three times. Consider extracting this as a constant to improve maintainability and reduce the chance of inconsistencies if the path needs to be updated.