Skip to content

pipewire: each output without a buffer writes into its own scratch - #961

Merged
jcelerier merged 2 commits into
masterfrom
edu/pipewire-unlinked-outputs
Oct 28, 2026
Merged

jcelerier merged 2 commits into
masterfrom
edu/pipewire-unlinked-outputs

Conversation

@edumeneses

@edumeneses edumeneses commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

PipeWire gives no buffer to an output port that nothing is linked to. fetch_cycle_buffers leaves those outputs null, and assign_chunk_pointers pointed every one of them at the same m_scratch. So whatever the tick wrote to one unlinked output landed in all the others.

Nothing reads those ports, so nobody hears it. But the hardware output meters read the tick's outputs after the mix, and they show it. Edu hit this testing the mixer (ossia/score#2302) with score's outputs left unlinked:

  • a signal sent to /out/1 showed on every channel's meter;
  • a stereo source, with three outputs, showed on the third one too.

With 64 outputs and a stereo default sink, channels 3 to 64 all share one buffer in the same way. The per-channel /out/N gains of #950 also scaled that shared buffer once per alias.

The fix:

  • m_scratch holds one block per output.
  • assign_chunk_pointers takes a stride, so the i-th missing output writes at scratch + i * stride.
  • The inputs keep their single shared m_silence: the stride defaults to 0.

Tests, in score (they live there with the other PipeWire tests). They are in ossia/score#2336, which bumps this:

  • test_unit_pipewire_quantum: two missing channels get distinct scratch.
  • test_unit_pipewire_protocol_quantum: a private daemon with no sink and three unlinked outputs. Each output must still hold what the tick wrote to it. Without the fix it fails: 18 times, an output held another channel's signal at the end of the tick.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Lc7tYGHRn6TmaxMEfBTswW

PipeWire hands no buffer to an output port that nothing is linked to.
Every such port was pointed at the same discard buffer, so whatever the
tick wrote to one of them landed in all the others. The audio could not
be heard, since nothing reads those ports, but the hardware output
meters read the tick's outputs after the mix: a signal sent to /out/1
showed on every unlinked channel, and a stereo source on a third one.

The scratch now holds one block per output, and a missing output gets
its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lc7tYGHRn6TmaxMEfBTswW
@edumeneses
edumeneses temporarily deployed to Apple Certificate October 13, 2026 06:00 — with GitHub Actions Inactive
@edumeneses
edumeneses temporarily deployed to Apple Certificate October 13, 2026 06:00 — with GitHub Actions Inactive
@edumeneses
edumeneses temporarily deployed to Apple Certificate October 13, 2026 06:00 — with GitHub Actions Inactive
@edumeneses
edumeneses temporarily deployed to Apple Certificate October 13, 2026 06:00 — with GitHub Actions Inactive
@edumeneses
edumeneses temporarily deployed to Apple Certificate October 13, 2026 06:00 — with GitHub Actions Inactive
@edumeneses
edumeneses temporarily deployed to Apple Certificate October 13, 2026 06:00 — with GitHub Actions Inactive
@edumeneses
edumeneses temporarily deployed to Apple Certificate October 13, 2026 06:00 — with GitHub Actions Inactive
@edumeneses
edumeneses temporarily deployed to Apple Certificate October 13, 2026 06:00 — with GitHub Actions Inactive
@edumeneses
edumeneses temporarily deployed to Apple Certificate October 13, 2026 06:00 — with GitHub Actions Inactive
@jcelerier
jcelerier marked this pull request as ready for review October 28, 2026 01:58
@jcelerier
jcelerier merged commit 76cff05 into master Oct 28, 2026
44 of 47 checks passed
@jcelerier
jcelerier deleted the edu/pipewire-unlinked-outputs branch October 28, 2026 01:58
@jcelerier

Copy link
Copy Markdown
Member

lgtm, thanks!

This branch was previously deployed

1 inactive deployment
Apple Certificate — b6a88970 Deployed Oct 13, 2026 by edumeneses via Unity3D (macOS) #1319
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.

2 participants