Skip to content

Add C API for Omnilingual ASR CTC models - #2773

Merged
csukuangfj merged 1 commit into
k2-fsa:masterfrom
csukuangfj:c-api-omnilingual
Nov 13, 2025
Merged

csukuangfj merged 1 commit into
k2-fsa:masterfrom
csukuangfj:c-api-omnilingual

Conversation

@csukuangfj

@csukuangfj csukuangfj commented Nov 13, 2025 •

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for omnilingual Automatic Speech Recognition (ASR) models with CTC-based decoding in the C API.
    • Introduced a C API example demonstrating omnilingual ASR functionality with audio file processing.
  • Tests

    • Added end-to-end testing for omnilingual ASR capabilities in the CI pipeline.

@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Nov 13, 2025
@coderabbitai

coderabbitai Bot commented Nov 13, 2025 •

Copy link
Copy Markdown

Walkthrough

A 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

Cohort / File(s) Summary
C API Headers
sherpa-onnx/c-api/c-api.h
Added new struct SherpaOnnxOfflineOmnilingualAsrCtcModelConfig with model field; extended SherpaOnnxOfflineModelConfig with omnilingual field
C API Implementation
sherpa-onnx/c-api/c-api.cc
Initialized recognizer config omnilingual model field from incoming config using existing SHERPA_ONNX_OR pattern
C API Example & Build
c-api-examples/omnilingual-asr-ctc-c-api.c, c-api-examples/CMakeLists.txt
Added new example executable demonstrating omnilingual ASR CTC workflow (read WAV, configure model, create recognizer, decode audio); linked against sherpa-onnx-c-api
CI Workflow
.github/workflows/c-api.yaml
Added new test step "Test Omnilingual ASR CTC" that builds example, downloads omnilingual model, executes binary, and cleans up artifacts

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Area of focus: c-api-examples/omnilingual-asr-ctc-c-api.c — New example contains full implementation with error handling, resource cleanup, and model initialization logic that requires verification for correctness
  • Secondary focus: sherpa-onnx/c-api/c-api.h — New struct definitions and field extensions should be verified against existing patterns and memory layout expectations
  • Verification points: Config initialization flow in c-api.cc, correct field population in recognizer setup, proper resource allocation/deallocation in example

Poem

🐰 Languages whisper through the wire,
Omnilingual dreams now reach up higher,
CTC magic in the C API,
A fresh example for all to spy,
The ASR rabbit hops with glee! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding C API support for omnilingual ASR CTC models, which is reflected across all modified files including new structs, configurations, examples, and CI tests.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 36ef8d1 and 26556f9.

📒 Files selected for processing (5)
  • .github/workflows/c-api.yaml (1 hunks)
  • c-api-examples/CMakeLists.txt (1 hunks)
  • c-api-examples/omnilingual-asr-ctc-c-api.c (1 hunks)
  • sherpa-onnx/c-api/c-api.cc (1 hunks)
  • sherpa-onnx/c-api/c-api.h (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
c-api-examples/omnilingual-asr-ctc-c-api.c (1)
sherpa-onnx/c-api/c-api.cc (20)
  • SherpaOnnxReadWave (1497-1514)
  • SherpaOnnxReadWave (1497-1497)
  • SherpaOnnxCreateOfflineRecognizer (556-572)
  • SherpaOnnxCreateOfflineRecognizer (556-557)
  • SherpaOnnxFreeWave (1538-1543)
  • SherpaOnnxFreeWave (1538-1538)
  • SherpaOnnxCreateOfflineStream (587-592)
  • SherpaOnnxCreateOfflineStream (587-588)
  • SherpaOnnxAcceptWaveformOffline (605-609)
  • SherpaOnnxAcceptWaveformOffline (605-607)
  • SherpaOnnxDecodeOfflineStream (611-615)
  • SherpaOnnxDecodeOfflineStream (611-613)
  • SherpaOnnxGetOfflineStreamResult (627-715)
  • SherpaOnnxGetOfflineStreamResult (627-628)
  • SherpaOnnxDestroyOfflineRecognizerResult (717-731)
  • SherpaOnnxDestroyOfflineRecognizerResult (717-718)
  • SherpaOnnxDestroyOfflineStream (601-603)
  • SherpaOnnxDestroyOfflineStream (601-601)
  • SherpaOnnxDestroyOfflineRecognizer (582-585)
  • SherpaOnnxDestroyOfflineRecognizer (582-583)
🔇 Additional comments (5)
sherpa-onnx/c-api/c-api.cc (1)

511-512: Omnilingual config wired correctly

The new SHERPA_ONNX_OR assignment mirrors the existing CTC wiring and keeps defaults intact. Looks good.

c-api-examples/CMakeLists.txt (1)

86-87: CMake target addition looks good

Target name and linkage are consistent with the other C API examples.

.github/workflows/c-api.yaml (1)

78-107: End-to-end CI step matches existing pattern

The compile/run flow, dependency fetching, and cleanup follow the proven pattern from other C API tests.

sherpa-onnx/c-api/c-api.h (1)

483-514: Header surface area in sync

Adding SherpaOnnxOfflineOmnilingualAsrCtcModelConfig and threading it into SherpaOnnxOfflineModelConfig matches the implementation change.

c-api-examples/omnilingual-asr-ctc-c-api.c (1)

22-81: Sample program initializes and cleans up properly

Config structs are zeroed before assignment, required fields are populated, and all resources are freed. Nice addition.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @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 sherpa-onnx C API by adding comprehensive support for Omnilingual ASR CTC models. The changes include the necessary C API structures for model configuration and a practical example application, making it easier for users to leverage these advanced speech recognition models within their C-based projects. This expansion broadens the utility of the C API for diverse ASR tasks.

Highlights

  • New C API Support: Introduced C API support for Omnilingual ASR CTC models, allowing developers to integrate these models into C applications.
  • Configuration Structures: Added a new C struct, SherpaOnnxOfflineOmnilingualAsrCtcModelConfig, and integrated it into SherpaOnnxOfflineModelConfig to enable proper configuration of Omnilingual ASR CTC models.
  • Example Application: Provided a new C example, omnilingual-asr-ctc-c-api.c, demonstrating how to use the Omnilingual ASR CTC models with the sherpa-onnx C API for offline speech recognition.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/c-api.yaml
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@csukuangfj
csukuangfj requested a review from Copilot November 13, 2025 04:41

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +65 to +66
const SherpaOnnxOfflineStream *stream =
SherpaOnnxCreateOfflineStream(recognizer);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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;
}

Comment on lines +37 to +39
SherpaOnnxOfflineOmnilingualAsrCtcModelConfig omnilingual;
memset(&omnilingual, 0, sizeof(omnilingual));
omnilingual.model = model_filename;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Suggested change
SherpaOnnxOfflineOmnilingualAsrCtcModelConfig omnilingual;
memset(&omnilingual, 0, sizeof(omnilingual));
omnilingual.model = model_filename;
SherpaOnnxOfflineOmnilingualAsrCtcModelConfig omnilingual = {.model = model_filename};

Comment on lines +42 to +48
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;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Suggested change
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,
};

Comment on lines +51 to +54
SherpaOnnxOfflineRecognizerConfig recognizer_config;
memset(&recognizer_config, 0, sizeof(recognizer_config));
recognizer_config.decoding_method = "greedy_search";
recognizer_config.model_config = offline_model_config;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to previous comments, using C99 designated initializers here would make the code more modern, readable, and safe.

Suggested change
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,
};

@csukuangfj
csukuangfj merged commit 867d044 into k2-fsa:master Nov 13, 2025
17 of 40 checks passed
@csukuangfj
csukuangfj deleted the c-api-omnilingual branch November 13, 2025 04:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +24 to +26
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";

Copilot AI Nov 13, 2025

Copy link

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-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.

Suggested change
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);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants