perf(linux): eliminate unnecessary PipeWire resampling by matching stream clock - #40
Closed
Horuse wants to merge 1 commit into
Closed
perf(linux): eliminate unnecessary PipeWire resampling by matching stream clock#40Horuse wants to merge 1 commit into
Horuse wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Replaces the Linux virtual-device configuration-file workflow with native
PipeWire runtime objects. Splitwave creates
support.null-audio-sinkadaptersthrough
core.create_object, removes owned nodes throughregistry.destroy_global, and restores the saved virtual-device list when theapp starts. The legacy
50-splitwave-sinks.conffile is removed withoutrestarting PipeWire.
The Linux audio path now uses the sample rate and channel count reported by
PipeWire or stored in the Splitwave virtual-device configuration. Playback,
cue playback, microphone and sink-monitor capture propagate these values into
PipeWire format negotiation. System and app capture use the pipeline sample
rate. Capture streams advertise a rate range with the requested rate as the
default, observe the negotiated format through PipeWire's
param_changedevent, and atomically notify the normalizer when that rate changes. The
normalizer then drops the transition backlog and rebuilds its resampler without
restarting the capture stream. The playback callback writes directly into the
mapped PipeWire buffer, so it performs no allocation.
Why is this the right approach?
PipeWire provides the complete lifecycle API needed here: server objects can
be created through the core and removed through the registry. Runtime objects
avoid restarting the user's audio server and interrupting unrelated apps.
Splitwave's existing
virtual-devices.jsonstore provides persistence, whilethe in-process cache supplies the configured format to
device_info.External PipeWire nodes are resolved from registry properties. The parser
handles
audio.rate, fractionalnode.ratevalues such as1/44100,audio.channels, and channel counts derived fromaudio.position. Missingformat information returns an explicit device error instead of silently using
48 kHz stereo.
No new dependency was added.
Checklist
bun run checkpasses — frontend code was not changed; command was not runcargo check --manifest-path src-tauri/Cargo.tomlpasses on macOS, Linux, Windowsbun run formatleaves the tree clean —cargo fmtpasses#[derive(TS)]changes)change adds no allocations, locks, or syscalls to cpal / SCK callbacks
or
DspWorker::runPlatform coverage
cargo check --manifest-path src-tauri/Cargo.tomlon macOS, Linux successfully.cargo check --manifest-path src-tauri/Cargo.tomlsuccessfully with PipeWire, PulseAudio, GTK and WebKit development libraries installed.cargo test --manifest-path src-tauri/Cargo.toml --libon Linux