Skip to content

24k sample-rate in macOS to minimize resampling#1741

Merged
yujonglee merged 2 commits intomainfrom
24k-sample-rate-in-macos-to-minimize-resamlping
Nov 20, 2025
Merged

24k sample-rate in macOS to minimize resampling#1741
yujonglee merged 2 commits intomainfrom
24k-sample-rate-in-macos-to-minimize-resamlping

Conversation

@yujonglee
Copy link
Contributor

No description provided.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 20, 2025

Warning

Rate limit exceeded

@yujonglee has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 20 minutes and 22 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between f30f862 and 2b60c0d.

📒 Files selected for processing (1)
  • crates/audio-utils/src/resampler/mod.rs (3 hunks)
📝 Walkthrough

Walkthrough

Core resampler components refactored with a Backend abstraction that enables passthrough optimization when input/output rates match, eliminating unnecessary interpolation. Listener actors updated to use a centralized platform-specific SAMPLE_RATE constant.

Changes

Cohort / File(s) Summary
Resampler backend abstraction
crates/audio-utils/src/resampler/dynamic_new.rs
Introduces Backend enum (Passthrough, Resampler) to abstract resampling strategies. Replaces direct RubatoChunkResampler driver field with generic backend field. Updates initialization, rebuild, and poll logic to dispatch through Backend based on rate equality.
Resampler bypass optimization
crates/audio-utils/src/resampler/dynamic_old.rs
Adds bypass flag that short-circuits resampling when source rate equals target rate, returning inner stream items directly. Flag initialized and updated on rate changes.
Resampler test updates
crates/audio-utils/src/resampler/mod.rs
Updates test expectations (Kalosm: 9896247 → 9906153 samples; dynamic\_old: 2791777 → 2791776 samples). Adds new test\_dynamic\_new\_resampler\_passthrough validating passthrough yields identical samples.
Platform-specific sample rate configuration
plugins/listener/src/actors/mod.rs
Introduces public const SAMPLE\_RATE with conditional compilation: 24,000 Hz on macOS, 16,000 Hz elsewhere.
Sample rate constant adoption
plugins/listener/src/actors/listener.rs, plugins/listener/src/actors/recorder.rs, plugins/listener/src/actors/source.rs
Replaces hardcoded 16000 with super::SAMPLE\_RATE references (removes local SAMPLE\_RATE in source.rs).
Cleanup
plugins/listener/src/actors/controller.rs
Removes unused tauri::Manager import.

Sequence Diagram(s)

sequenceDiagram
    participant poll as ResamplerDynamicNew::poll()
    participant backend as Backend
    participant passthrough as Passthrough Buffer
    participant resampler as Rubato Resampler

    alt Source rate == Target rate
        poll->>backend: Backend::Passthrough(buffer)
        activate backend
        backend->>passthrough: push_sample(sample)
        backend->>passthrough: try_yield_chunk()
        passthrough-->>backend: Some(chunk)
        deactivate backend
    else Source rate != Target rate
        poll->>backend: Backend::Resampler(resampler)
        activate backend
        backend->>resampler: push_sample(sample)
        backend->>resampler: try_yield_chunk()
        resampler-->>backend: Some(resampled_chunk)
        deactivate backend
    end
    
    backend-->>poll: chunk
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Backend abstraction implementation: Verify that passthrough/resampler dispatch logic correctly switches based on rate equality and handles state transitions properly.
  • Test expectation changes: Validate that updated sample counts (Kalosm, dynamic_old) reflect expected behavior rather than unintended regressions.
  • Platform-specific constant consistency: Ensure all listener actors use super::SAMPLE\_RATE uniformly and that macOS (24 kHz) vs. non-macOS (16 kHz) distinction is intentional.
  • Method signature changes: Confirm that try\_yield\_chunk's new allow\_partial parameter is properly threaded through the backend abstraction.

Possibly related PRs

  • Fix audio pipeline #1662: Main PR refactoring ResamplerDynamicNew to introduce the Backend abstraction enum, replacing direct RubatoChunkResampler driver usage with a generic dispatch layer—directly modifies the same resampler architecture introduced here.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The PR title 'done' is vague and generic, providing no meaningful information about the changeset's primary purpose or content. Replace the title with a descriptive summary of the main change, such as 'Support 24kHz sample rate on macOS to minimize resampling' or similar.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess relatedness to the changeset. Add a description explaining the purpose of the changes, such as why the sample rate was made platform-specific and what improvements it provides.

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.

@netlify
Copy link

netlify bot commented Nov 20, 2025

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit 2b60c0d
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/691e94d97796fd00085b4230
😎 Deploy Preview https://deploy-preview-1741--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@yujonglee yujonglee changed the title done 24k sample-rate in macOS to minimize resampling Nov 20, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f945c40 and f30f862.

📒 Files selected for processing (8)
  • crates/audio-utils/src/resampler/dynamic_new.rs (6 hunks)
  • crates/audio-utils/src/resampler/dynamic_old.rs (4 hunks)
  • crates/audio-utils/src/resampler/mod.rs (3 hunks)
  • plugins/listener/src/actors/controller.rs (0 hunks)
  • plugins/listener/src/actors/listener.rs (1 hunks)
  • plugins/listener/src/actors/mod.rs (1 hunks)
  • plugins/listener/src/actors/recorder.rs (1 hunks)
  • plugins/listener/src/actors/source.rs (1 hunks)
💤 Files with no reviewable changes (1)
  • plugins/listener/src/actors/controller.rs
🧰 Additional context used
🧬 Code graph analysis (4)
crates/audio-utils/src/resampler/dynamic_old.rs (2)
crates/audio-utils/src/resampler/mod.rs (3)
  • ResamplerDynamicOld (142-143)
  • new (39-47)
  • source (25-25)
crates/audio-utils/src/resampler/dynamic_new.rs (1)
  • new (139-165)
crates/audio-utils/src/resampler/mod.rs (1)
crates/audio-utils/src/resampler/dynamic_new.rs (1)
  • new (139-165)
plugins/listener/src/actors/source.rs (1)
crates/audio-utils/src/lib.rs (1)
  • chunk_size_for_stt (230-236)
crates/audio-utils/src/resampler/dynamic_new.rs (2)
crates/audio-utils/src/resampler/dynamic_old.rs (1)
  • new (23-37)
crates/audio-utils/src/resampler/driver.rs (3)
  • new (20-35)
  • push_sample (73-75)
  • process_all_ready_blocks (80-92)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Redirect rules - hyprnote
  • GitHub Check: Header rules - hyprnote
  • GitHub Check: Pages changed - hyprnote
  • GitHub Check: fmt
  • GitHub Check: ci (macos, macos-14)
🔇 Additional comments (8)
crates/audio-utils/src/resampler/dynamic_old.rs (1)

19-19: LGTM: Bypass optimization is correctly implemented.

The bypass flag properly short-circuits interpolation when source and target rates match, and the seeded flag ensures correct re-initialization when transitioning from bypass to non-bypass mode after a rate change.

Also applies to: 25-25, 35-35, 47-47, 65-67

crates/audio-utils/src/resampler/mod.rs (1)

136-136: Updated test expectations reflect algorithmic changes.

The modified expected sample counts align with the bypass optimization introduced in this PR.

Also applies to: 146-146

crates/audio-utils/src/resampler/dynamic_new.rs (2)

21-120: Excellent Backend abstraction design.

The Backend enum cleanly separates passthrough buffering from Rubato-based resampling. The drain_for_rate_change and drain_at_eos methods ensure no samples are lost when switching between backends during rate changes.


146-155: Passthrough optimization correctly implemented.

The constructor properly selects Backend::Passthrough when rates match, and rebuild_backend correctly switches between passthrough and resampling modes when the source rate changes. The poll loop ensures samples are drained before switching backends (lines 227-243).

Also applies to: 167-178

plugins/listener/src/actors/mod.rs (1)

13-16: Centralized, platform-specific SAMPLE_RATE looks good

The cfg-gated SAMPLE_RATE cleanly centralizes the rate and makes the macOS 24 kHz vs others 16 kHz distinction explicit for all actor modules using super::SAMPLE_RATE. No issues from this definition itself.

plugins/listener/src/actors/recorder.rs (1)

60-65: Recorder WAV spec now matches runtime sample rate

Using super::SAMPLE_RATE for the WAV sample_rate keeps the on-disk spec aligned with the audio data produced by SourceActor (24 kHz on macOS, 16 kHz elsewhere). This makes the recorder consistent with the capture and STT pipelines.

plugins/listener/src/actors/source.rs (1)

262-278: Consistent use of shared SAMPLE_RATE in capture pipeline

Switching both mic and speaker to use chunk_size_for_stt(super::SAMPLE_RATE) and .resampled_chunks(super::SAMPLE_RATE, chunk_size) ties the capture side cleanly to the centralized constant. That keeps chunk sizing and resampling behavior aligned with the OS-specific rate used elsewhere (listener and recorder), while leaving non-macOS behavior effectively unchanged.

plugins/listener/src/actors/listener.rs (1)

205-216: Confirm whether owhisper server actually uses the sample_rate parameter

The original review comment's observation is valid. I found that:

  • Single mode (line 212) now passes super::SAMPLE_RATE (24 kHz on macOS)
  • Dual mode (line 252) still passes hard-coded 16000
  • Both capture paths via SourceActor send 24 kHz on macOS for either mode

However, the owhisper server appears to hard-code resampling to 16 kHz internally (see owhisper-server/src/server.rs:428 .to_i16_le_chunks(16000, 512) and realtime.rs:137 .resample(16000)), which suggests the sample_rate parameter may be informational only and currently ignored.

What you should verify:

  1. Does owhisper server actually use the ListenParams.sample_rate field, or is it always hard-coded to 16 kHz regardless of what's passed?
  2. If it's ignored today, will future versions respect it?

Why it matters:

  • If sample_rate is ignored: the inconsistency is harmless but confusing; consider adding a code comment explaining why
  • If sample_rate is (or will be) used: Dual mode on macOS needs to be updated to super::SAMPLE_RATE to align with what SourceActor is actually sending, or explicitly document why it differs

@yujonglee yujonglee merged commit 9697241 into main Nov 20, 2025
6 of 8 checks passed
@yujonglee yujonglee deleted the 24k-sample-rate-in-macos-to-minimize-resamlping branch November 20, 2025 04:11
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