Skip to content

Comments

Bolt: Optimize incremental mel processing#27

Closed
ysdede wants to merge 1 commit intomasterfrom
bolt/optimize-incremental-mel-16657204577315940198
Closed

Bolt: Optimize incremental mel processing#27
ysdede wants to merge 1 commit intomasterfrom
bolt/optimize-incremental-mel-16657204577315940198

Conversation

@ysdede
Copy link
Owner

@ysdede ysdede commented Feb 8, 2026

⚡ Bolt: Optimized IncrementalMelProcessor to skip redundant STFT computations

💡 What:
Modified JsPreprocessor.computeRawMel to accept a startFrame parameter.
Updated IncrementalMelProcessor.process to pass the number of safe cached frames as startFrame, avoiding re-computation of the STFT for the overlapping prefix.

🎯 Why:
The previous implementation re-computed the STFT for the entire audio buffer even when ~70% of it was already cached and would be overwritten anyway. This was a significant bottleneck in streaming applications.

📊 Impact:

  • Reduces processing time for 5s audio with 3.5s overlap from ~79ms to ~27ms.
  • ~2.9x speedup in the incremental path.

🔬 Measurement:
Run tests/mel.test.mjs and observe the "should process incrementally faster than full" benchmark output, or run a dedicated benchmark script. Existing tests ensure no regression in accuracy.


PR created automatically by Jules for task 16657204577315940198 started by @ysdede

Summary by CodeRabbit

  • Performance

    • Enhanced audio preprocessing efficiency through optimized caching that enables better reuse of computed results. The system now reduces redundant calculations by more strategically managing which audio frames need recomputation, resulting in faster processing.
  • Refactor

    • Improved audio frame computation logic to support more efficient incremental processing through enhanced caching and selective computation strategies.

Implements a `startFrame` parameter in `JsPreprocessor.computeRawMel` to allow skipping
computation of frames that are already cached.
Updates `IncrementalMelProcessor` to leverage this, skipping STFT and mel filterbank
operations for the cached prefix of the audio.

Performance benchmark (5s audio, 3.5s overlap):
- Before: ~79ms
- After: ~27ms (~2.9x speedup)

Tests:
- Verified correctness with existing test suite (70 tests passed).
- Confirmed bit-exact output matches full computation.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 8, 2026

📝 Walkthrough

Walkthrough

The JsPreprocessor.computeRawMel() method in src/mel.js is updated to accept an optional startFrame parameter, enabling partial recomputation of mel frames. The IncrementalMelProcessor now passes this parameter to skip recomputing cached frames, optimizing performance through frame caching and reuse.

Changes

Cohort / File(s) Summary
Mel Processing Optimization
src/mel.js
Added optional startFrame parameter to computeRawMel() method signature and updated JSDoc documentation. Modified computation logic to begin processing from startFrame rather than frame 0, enabling cached prefix frame reuse. Updated IncrementalMelProcessor flow to pass safeFrames as the start point, with clarifying comments on cached frame handling.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A hop, skip, and cache away—
Frames reused, no more delay!
Mel preprocessing takes the lead,
Skipping work it doesn't need. ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: optimizing incremental mel processing by adding a startFrame parameter to skip redundant STFT computations for cached frames.
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 docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bolt/optimize-incremental-mel-16657204577315940198

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
src/mel.js (2)

532-548: Double mel computation on cold-start path.

When canReuse is false, process(audio) computes the full STFT+mel+normalize pipeline, and then computeRawMel(audio) recomputes STFT+mel again just to populate the cache. You could instead call computeRawMel once and then normalizeFeatures to avoid the redundant work.

♻️ Suggested refactor
     if (!canReuse) {
-      // Full computation (no cache or cache invalid)
-      const result = this.preprocessor.process(audio);
-      // Cache raw mel for next call
       const { rawMel, nFrames, featuresLen } =
         this.preprocessor.computeRawMel(audio);
+      if (featuresLen === 0) {
+        this.reset();
+        return { features: new Float32Array(0), length: 0, cached: false, cachedFrames: 0, newFrames: 0 };
+      }
+      const features = this.preprocessor.normalizeFeatures(rawMel, nFrames, featuresLen);
       this._cachedRawMel = rawMel;
       this._cachedNFrames = nFrames;
       this._cachedAudioLen = N;
       this._cachedFeaturesLen = featuresLen;
 
       return {
-        ...result,
+        features,
+        length: featuresLen,
         cached: false,
         cachedFrames: 0,
         newFrames: featuresLen,
       };
     }

599-606: clear() duplicates reset().

Both methods have identical bodies. Consider having one delegate to the other to avoid drift.

♻️ Suggestion
   clear() {
-    this._cachedRawMel = null;
-    this._cachedNFrames = 0;
-    this._cachedAudioLen = 0;
-    this._cachedFeaturesLen = 0;
+    this.reset();
   }

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.

Copy link
Owner Author

@ysdede ysdede left a comment

Choose a reason for hiding this comment

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

Summary: This change overlaps with #29 (startFrame support and skipping cached prefix). #29 also includes the full-path optimization, so it supersedes this PR.
Recommendation: Close as superseded by #29 to avoid conflicts.
Tests: npm test

@ysdede
Copy link
Owner Author

ysdede commented Feb 9, 2026

Handled in PR#34 (release branch). Closing superseded PR.

@ysdede ysdede closed this Feb 9, 2026
@ysdede ysdede deleted the bolt/optimize-incremental-mel-16657204577315940198 branch February 9, 2026 21:09
@google-labs-jules
Copy link
Contributor

Handled in PR#34 (release branch). Closing superseded PR.

Understood. Acknowledging that this work is now obsolete and stopping work on this task.

@ysdede ysdede changed the title ⚡ Bolt: Optimize incremental mel processing Bolt: Optimize incremental mel processing Feb 12, 2026
Repository owner deleted a comment from google-labs-jules bot Feb 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant