Repository navigation
Add C API for Omnilingual ASR CTC models - #2773
Conversation
WalkthroughA new omnilingual ASR CTC feature has been added to the Sherpa-ONNX C API. Changes include new header structs for omnilingual model configuration, implementation updates to initialize recognizer configs, a C example demonstrating the full workflow, CMake build target definition, and a CI workflow test step validating the end-to-end functionality. Changes
Sequence DiagramsequenceDiagram
participant User
participant Example as omnilingual-asr-ctc-c-api
participant C_API as Sherpa-ONNX C API
participant Model as Omnilingual Model
participant Audio as Audio WAV
User->>Example: Execute binary
Example->>Audio: Read WAV file
Audio-->>Example: Audio samples
Example->>C_API: Initialize config structs<br/>(omnilingual model path)
Example->>C_API: Create offline recognizer
C_API->>Model: Load omnilingual CTC model
Model-->>C_API: Model loaded
C_API-->>Example: Recognizer created
Example->>C_API: Create stream
C_API-->>Example: Stream ready
Example->>C_API: Feed audio samples
C_API->>Model: Process with CTC decoder<br/>(greedy search)
Model-->>C_API: Decoded result
Example->>C_API: Get result text
C_API-->>Example: Recognition text
Example->>User: Print decoded text
Example->>C_API: Cleanup resources
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (5)
🧰 Additional context used🧬 Code graph analysis (1)c-api-examples/omnilingual-asr-ctc-c-api.c (1)
🔇 Additional comments (5)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @csukuangfj, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Highlights
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces C API support for Omnilingual ASR CTC models. The changes include new configuration structures in the C API header, corresponding handling in the C++ implementation, and a new example file demonstrating the usage. The implementation is straightforward and consistent with the existing codebase. My review focuses on the new C example, providing suggestions to improve code quality by using modern C features for struct initialization and enhancing error handling for better robustness.
| const SherpaOnnxOfflineStream *stream = | ||
| SherpaOnnxCreateOfflineStream(recognizer); |
There was a problem hiding this comment.
It's good practice to check the return value of SherpaOnnxCreateOfflineStream for NULL to handle potential allocation failures gracefully. While it might not fail in typical scenarios, adding this check improves the robustness of the example code. You could add the following check after creating the stream:
if (stream == NULL) {
fprintf(stderr, "Failed to create offline stream\n");
SherpaOnnxDestroyOfflineRecognizer(recognizer);
SherpaOnnxFreeWave(wave);
return -1;
}| SherpaOnnxOfflineOmnilingualAsrCtcModelConfig omnilingual; | ||
| memset(&omnilingual, 0, sizeof(omnilingual)); | ||
| omnilingual.model = model_filename; |
There was a problem hiding this comment.
Using memset to zero-initialize structs is a C-style pattern. For better readability and type safety, it's recommended to use C99 designated initializers. This makes the code cleaner and less prone to errors if the struct definition changes.
| SherpaOnnxOfflineOmnilingualAsrCtcModelConfig omnilingual; | |
| memset(&omnilingual, 0, sizeof(omnilingual)); | |
| omnilingual.model = model_filename; | |
| SherpaOnnxOfflineOmnilingualAsrCtcModelConfig omnilingual = {.model = model_filename}; |
| 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; |
There was a problem hiding this comment.
For better readability and safety, consider using C99 designated initializers instead of memset followed by member assignments. This approach ensures that all other members are correctly zero-initialized and makes the initialization code more concise.
| 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; | |
| SherpaOnnxOfflineModelConfig offline_model_config = { | |
| .debug = 1, | |
| .num_threads = 1, | |
| .provider = provider, | |
| .tokens = tokens_filename, | |
| .omnilingual = omnilingual, | |
| }; |
| SherpaOnnxOfflineRecognizerConfig recognizer_config; | ||
| memset(&recognizer_config, 0, sizeof(recognizer_config)); | ||
| recognizer_config.decoding_method = "greedy_search"; | ||
| recognizer_config.model_config = offline_model_config; |
There was a problem hiding this comment.
Similar to previous comments, using C99 designated initializers here would make the code more modern, readable, and safe.
| SherpaOnnxOfflineRecognizerConfig recognizer_config; | |
| memset(&recognizer_config, 0, sizeof(recognizer_config)); | |
| recognizer_config.decoding_method = "greedy_search"; | |
| recognizer_config.model_config = offline_model_config; | |
| SherpaOnnxOfflineRecognizerConfig recognizer_config = { | |
| .decoding_method = "greedy_search", | |
| .model_config = offline_model_config, | |
| }; |
There was a problem hiding this comment.
Pull Request Overview
This PR adds C API support for Omnilingual ASR CTC models by extending the existing offline recognizer infrastructure. The changes enable developers to use the 1600-language Omnilingual ASR model through the C API.
Key Changes:
- Added new configuration struct for Omnilingual ASR CTC models
- Integrated Omnilingual model configuration into the offline model config
- Created example C program demonstrating usage with test audio files
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| sherpa-onnx/c-api/c-api.h | Defines new SherpaOnnxOfflineOmnilingualAsrCtcModelConfig struct and adds it to the offline model config |
| sherpa-onnx/c-api/c-api.cc | Implements configuration mapping for the omnilingual model field |
| c-api-examples/omnilingual-asr-ctc-c-api.c | Provides complete example demonstrating how to use the Omnilingual ASR model via C API |
| c-api-examples/CMakeLists.txt | Adds build target for the new omnilingual example |
| .github/workflows/c-api.yaml | Adds CI test workflow for the Omnilingual ASR CTC example |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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"; |
There was a problem hiding this comment.
The directory path sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12 is 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.
| 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"; | |
| const char *model_dir = "./sherpa-onnx-omnilingual-asr-1600-languages-300M-ctc-int8-2025-11-12"; | |
| char wav_filename[512]; | |
| char model_filename[512]; | |
| char tokens_filename[512]; | |
| snprintf(wav_filename, sizeof(wav_filename), "%s/test_wavs/en.wav", model_dir); | |
| snprintf(model_filename, sizeof(model_filename), "%s/model.int8.onnx", model_dir); | |
| snprintf(tokens_filename, sizeof(tokens_filename), "%s/tokens.txt", model_dir); |
Summary by CodeRabbit
Release Notes
New Features
Tests