Skip to content

Refactor Pascal API - #3160

Merged
csukuangfj merged 2 commits into
k2-fsa:masterfrom
csukuangfj:refactor-pascal
Feb 9, 2026
Merged

csukuangfj merged 2 commits into
k2-fsa:masterfrom
csukuangfj:refactor-pascal

Conversation

@csukuangfj

@csukuangfj csukuangfj commented Feb 9, 2026 •

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Refactor
    • Public API signatures refined for safer immutable audio inputs, improving consistency across streaming, VAD, denoising, diarization, resampling and TTS paths.
    • Optimized audio-sample handling with bulk memory transfers and added zero-length / nil guards for more robust processing.
    • Improved performance and reduced unnecessary copying across audio pipelines.

@csukuangfj
csukuangfj requested a review from Copilot February 9, 2026 06:56
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Feb 9, 2026
@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 focuses on refining the Pascal API for Sherpa-Onnx by introducing const parameters for array inputs and optimizing array data handling. These changes aim to improve the efficiency and robustness of the API, particularly in functions that process audio samples or generate output arrays, by reducing memory overhead and adding defensive programming checks.

Highlights

  • Parameter Optimization: Many functions and procedures that accept array of Single parameters have been updated to use const Samples: array of Single. This change passes arrays by constant reference, which can enhance performance by preventing unnecessary data copying and ensures the original array remains unmodified.
  • Performance Improvement for Array Copying: The logic for copying array data in several functions (e.g., SherpaOnnxReadWave, TSherpaOnnxCircularBuffer.Get, TSherpaOnnxVoiceActivityDetector.Front, TSherpaOnnxOfflineTts.Generate, TSherpaOnnxLinearResampler.Resample) has been optimized. Element-by-element loops have been replaced with direct memory Move operations, significantly speeding up array assignments.
  • Increased Robustness: Null checks have been added in functions that receive pointers (e.g., TSherpaOnnxCircularBuffer.Get, TSherpaOnnxOfflineTts.Generate, TSherpaOnnxOfflineSpeechDenoiser.Run) to handle cases where the pointer might be nil, preventing potential runtime errors.
  • Code Clean-up: Unused local variables, such as loop counters (I: Integer) and temporary pointers (PFilename: PAnsiChar), have been removed from various functions, improving code readability and reducing clutter.
Changelog
  • sherpa-onnx/pascal-api/sherpa_onnx.pas
    • Modified TSherpaOnnxLinearResampler.Resample to accept const Samples: array of Single and optimized array copying with Move.
    • Updated TSherpaOnnxOnlineStream.AcceptWaveform to use const Samples: array of Single.
    • Changed TSherpaOnnxOfflineStream.AcceptWaveform to accept const Samples: array of Single.
    • Modified TSherpaOnnxVoiceActivityDetector.AcceptWaveform overloads to use const Samples: array of Single.
    • Updated TSherpaOnnxOfflineSpeakerDiarization.Process overloads to accept const Samples: array of Single.
    • Changed TSherpaOnnxOfflineSpeechDenoiser.Run to accept const Samples: array of Single and optimized array copying with Move.
    • Modified SherpaOnnxWriteWave to accept const Samples: array of Single.
    • Refactored SherpaOnnxReadWave to remove unused variables, reorder assignments, and use Move for efficient array copying, including a check for NumSamples > 0.
    • Optimized TSherpaOnnxCircularBuffer.Get by adding null/size checks and replacing loop-based copying with Move.
    • Improved TSherpaOnnxVoiceActivityDetector.Front by using Move for array copying and removing an unused loop variable.
    • Enhanced TSherpaOnnxOfflineTts.Generate overloads by adding null checks for generated audio, removing unused loop variables, and using Move for efficient array copying.
Activity
  • The author, csukuangfj, created this pull request to refactor the Pascal API.
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. ↩

@coderabbitai

coderabbitai Bot commented Feb 9, 2026 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Added const qualifiers to several public array parameters and replaced element-wise sample copies with Move-based memory transfers; added nil/zero-length guards and minor input validation across resampling, waveform acceptance, denoising, diarization, TTS, and read/write wave helpers. Public API names remain unchanged.

Changes

Cohort / File(s) Summary
Pascal API file
sherpa-onnx/pascal-api/sherpa_onnx.pas
Single-file patch: updated multiple public method signatures to use const Samples: array of Single; replaced per-element array copies with Move(...); added nil/zero-length guards and some offset/length validation across stream, resampler, VAD, denoiser, diarization, TTS, and read/write wave helpers.
Stream & VAD methods
TSherpaOnnxOnlineStream, TSherpaOnnxOfflineStream, TSherpaOnnxVoiceActivityDetector (in same file)
Changed AcceptWaveform overloads to accept const Samples; added boundary checks and switched front/queue copies to Move.
Resampler & Buffer
TSherpaOnnxLinearResampler, TSherpaOnnxCircularBuffer (in same file)
Resample and Get functions now guard nil/zero and use Move for bulk copy instead of element loops.
Denoiser / Diarization / TTS
TSherpaOnnxOfflineSpeechDenoiser, TSherpaOnnxOfflineSpeakerDiarization, TSherpaOnnxOfflineTts (in same file)
Run/Process/generation paths accept const Samples; results populated via Move with nil/length guards and fewer intermediate copies.
I/O helpers
SherpaOnnxWriteWave, SherpaOnnxReadWave (in same file)
WriteWave now takes const Samples; ReadWave uses PAnsiChar(Filename) directly and copies samples via Move when non-zero.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • Refactor Pascal API #3160 — Makes identical const-correctness changes and replaces element-wise copies with Move-based transfers in the same Pascal API file.

Suggested reviewers

  • Copilot

Poem

🐇 I hopped through bytes with nimble paws,
Const arrays stitched without a pause,
Move swept copies, light and spry,
No loops to slow the audio sky,
A rabbit cheers: the build runs wise! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Refactor Pascal API' is vague and generic, using non-descriptive language that doesn't convey meaningful information about the specific changes made (const-correctness, Move-based optimizations, input validation). Use a more specific title that highlights the main changes, such as 'Add const-correctness and optimize data transfers in Pascal API' or 'Improve const-qualification and performance in sherpa-onnx.pas'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 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 provides a nice refactoring of the Pascal API. The changes to use const for array parameters and replace manual copy loops with Move are great for performance. The added nil checks for pointers returned from the C-API improve the robustness of the code. I've found a couple of places where nil checks are still missing and could lead to runtime errors. Please see my detailed comments.

Comment on lines 2471 to 2472
P := SherpaOnnxVoiceActivityDetectorFront(Self.Handle);
Result.Start := P^.Start;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

The pointer P returned from SherpaOnnxVoiceActivityDetectorFront can be nil, for example, if the VAD buffer is empty. Dereferencing it on the next line without a nil check will lead to an access violation. Please add a check for nil before using P.

  P := SherpaOnnxVoiceActivityDetectorFront(Self.Handle);
  if P = nil then
  begin
    Result := Default(TSherpaOnnxSpeechSegment);
    Exit;
  end;
  Result.Start := P^.Start;

Comment on lines 2862 to 2863
P := SherpaOnnxLinearResamplerResample(Self.Handle, Samples, N, Ord(Flush));
SetLength(Result, P^.N);

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

The pointer P returned from SherpaOnnxLinearResamplerResample might be nil on error. While the current C++ implementation seems to always return a valid pointer, it's safer and more consistent with other C-API wrappers in this file to add a nil check before dereferencing P.

  P := SherpaOnnxLinearResamplerResample(Self.Handle, Samples, N, Ord(Flush));
  if P = nil then
    Exit;
  SetLength(Result, P^.N);

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
sherpa-onnx/pascal-api/sherpa_onnx.pas (2)

856-869: ⚠️ Potential issue | 🟡 Minor

Missing nil check on P, inconsistent with other methods in this PR.

All other methods refactored in this PR (Generate, Run, ReadWave) now guard against a nil return from the C API before dereferencing. This Resample overload dereferences P on line 863 without checking, and would crash if SherpaOnnxLinearResamplerResample ever returns nil.

Proposed fix for consistency
   Result := Default(TSherpaOnnxSamplesArray);
   P := SherpaOnnxLinearResamplerResample(Self.Handle, Samples, N, Ord(Flush));
+
+  if P = nil then
+    Exit;
+
   SetLength(Result, P^.N);
 
   if P^.N > 0 then

2433-2445: ⚠️ Potential issue | 🟠 Major

Bounds validation does not reject negative Offset or N, allowing out-of-bounds memory access.

The check on line 2435 only validates the upper bound. A negative Offset (e.g., Offset = -1, N = 1) satisfies Offset + N <= Length(Samples) but causes pcfloat(Samples) + Offset to point before the array buffer. Similarly, a negative N passes the check and is forwarded to the C function.

Proposed fix
 procedure TSherpaOnnxVoiceActivityDetector.AcceptWaveform(const Samples: array of Single; Offset: Integer; N: Integer);
 begin
-  if Offset + N > Length(Samples) then
+  if (Offset < 0) or (N < 0) or (Offset + N > Length(Samples)) then
     begin
       WriteLn(Format('Invalid arguments!. Array length: %d, Offset: %d, N: %d',
         [Length(Samples), Offset, N]

@csukuangfj
csukuangfj merged commit 38f908e into k2-fsa:master Feb 9, 2026
1 check was pending
@csukuangfj
csukuangfj deleted the refactor-pascal branch February 9, 2026 07:03

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 refactors the Pascal API surface in sherpa_onnx.pas to reduce unnecessary array copying and to speed up sample transfers between C pointers and Pascal dynamic arrays.

Changes:

  • Marked several open-array array of Single parameters as const to avoid implicit copying for waveform/sample inputs.
  • Replaced element-by-element sample copying loops with Move(...) for faster bulk copies.
  • Added a few small guard checks (e.g., N <= 0, nil results) before copying.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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