Add C API for source separation - #3404
Conversation
Summary of ChangesHello, 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 expands 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. Footnotes
|
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR introduces offline source separation capabilities to Sherpa-ONNX's C API, supporting both Spleeter and UVR models. New C API functions handle multi-channel audio I/O, source separation configuration, engine creation/destruction, and processing. Two example C programs demonstrate end-to-end usage with each model. Build system, CI workflows, and symbol exports are updated accordingly. Changes
Sequence Diagram(s)sequenceDiagram
participant Example as Example Program
participant CAPI as C API Layer
participant Engine as Source Separation<br/>Engine
participant WaveIO as Wave I/O
Example->>WaveIO: SherpaOnnxReadWaveMultiChannel(input.wav)
WaveIO-->>Example: Multi-channel wave data
Example->>CAPI: SherpaOnnxCreateOfflineSourceSeparation(config)
CAPI->>Engine: Initialize with model path
Engine-->>CAPI: Engine instance
CAPI-->>Example: Engine handle
Example->>CAPI: SherpaOnnxOfflineSourceSeparationProcess(engine, samples)
CAPI->>Engine: Process multi-channel input
Engine-->>CAPI: Separation output (stems)
CAPI-->>Example: Output structure with stems
Example->>WaveIO: SherpaOnnxWriteWaveMultiChannel(stem[0], output.wav)
WaveIO-->>Example: File written
Example->>WaveIO: SherpaOnnxWriteWaveMultiChannel(stem[1], output.wav)
WaveIO-->>Example: File written
Example->>CAPI: SherpaOnnxDestroySourceSeparationOutput(output)
CAPI-->>Example: Resources freed
Example->>CAPI: SherpaOnnxDestroyOfflineSourceSeparation(engine)
CAPI->>Engine: Cleanup
Engine-->>CAPI: Engine destroyed
CAPI-->>Example: Cleanup complete
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Code Review
This pull request introduces C API examples for source separation using Spleeter and UVR models. It includes new C API functions for reading and writing multi-channel wave files, managing the source separation engine, and processing audio. The changes also include updates to CMakeLists.txt to build these examples and improvements to wave file writing with std::clamp. The review comments suggest improving maintainability in the example files by replacing magic numbers with sizeof calculations for array sizes.
|
|
||
| // Write each stem to a separate multi-channel wave file. | ||
| const char *stem_names[] = {"vocals", "accompaniment"}; | ||
| for (int32_t s = 0; s < output->num_stems && s < 2; ++s) { |
There was a problem hiding this comment.
To improve maintainability and avoid using a magic number (2), it's better to calculate the number of stem names directly from the stem_names array using sizeof.
| for (int32_t s = 0; s < output->num_stems && s < 2; ++s) { | |
| for (int32_t s = 0; s < output->num_stems && s < sizeof(stem_names) / sizeof(stem_names[0]); ++s) { |
|
|
||
| // Write each stem to a separate multi-channel wave file. | ||
| const char *stem_names[] = {"uvr-vocals", "uvr-non-vocals"}; | ||
| for (int32_t s = 0; s < output->num_stems && s < 2; ++s) { |
There was a problem hiding this comment.
To improve maintainability and avoid using a magic number (2), it's better to calculate the number of stem names directly from the stem_names array using sizeof.
| for (int32_t s = 0; s < output->num_stems && s < 2; ++s) { | |
| for (int32_t s = 0; s < output->num_stems && s < sizeof(stem_names) / sizeof(stem_names[0]); ++s) { |
Summary by CodeRabbit
New Features
Tests