Patch to add a new "pwsink" mixer plugin for the PipeWire output - #2565
Patch to add a new "pwsink" mixer plugin for the PipeWire output#2565gearhead wants to merge 2 commits into
Conversation
Unlike the existing pipewire mixer plugin (PipeWireMixerPlugin.cxx), which sets SPA_PROP_channelVolumes on MPD's own pw_stream (a per-client software gain stage applied before the signal reaches the sink, and not shared with other PipeWire clients), this plugin opens its own independent PipeWire client connection and drives a sink node's volume directly: - By default it follows the system's current default sink, resolved via the "default" pw_metadata object's "default.audio.sink" property (the same mechanism @DEFAULT_AUDIO_SINK@ uses). - If the output's "target" config option names a specific node, this plugin follows that node's volume instead, keeping audio routing and volume control pointed at the same sink without a second config key. WirePlumber then applies the resulting volume through the ALSA hardware mixer control when the sink's Route reports one (route.hw-volume = true), or through PipeWire's own software volume otherwise -- giving PipeWire outputs the same "real hardware mixer" option that ALSA, OSS and PulseAudio outputs already have via mixer_type "hardware", instead of always paying for a second, client-side software gain stage on top of whatever WirePlumber itself applies. MPD's own pw_stream is pinned to unity gain via pipewire_output_set_volume() while this mixer is open, so the sink's own volume is the only gain stage in effect. WirePlumber/wpctl display and set volume on a cubic scale rather than linear PCM gain; this is replicated here (config option "mixer_volume_curve") so a given MPD volume percentage matches what "wpctl get-volume" shows for the same node. For a "pipewire" output, mixer_type "hardware" previously fell through to the output's own registered mixer_plugin (PipeWireMixerPlugin.cxx), i.e. the same client-side stream volume used when mixer_type is left unset entirely -- there was no way to ask for a real hardware/sink-backed mixer at all. Special-case the HARDWARE case for pipewire outputs: if "mixer_type" is explicitly present in that output's config block (regardless of what any global default mixer_type is), use the new PwSinkMixer instead of the output's own plugin. If "mixer_type" is absent from the block, behaviour is unchanged (client-side stream volume via PipeWireMixerPlugin.cxx). This intentionally inspects the block's raw configuration rather than the already-resolved MixerType, since the resolved value alone cannot distinguish "not configured, inherited the HARDWARE default" from "explicitly configured as hardware" -- and those two cases need different plugins here specifically because pipewire's own default mixer plugin already occupies the HARDWARE slot. Output types other than "pipewire" are unaffected by this patch. Also here is the documentation of the new behaviour of mixer_type "hardware" for pipewire outputs a "pipewire" ref label so other sections can link to it, describe the hardware-mixer opt-in and the mixer_volume_curve option in plugins.rst, and mention PipeWire alongside ALSA/OSS/PulseAudio in the mixer_type descriptions in user.rst and mpd.conf.5.rst.
|
This is a big wall of text and a big wall of code. Is this LLM-generated code, or did you write every line (of code and text) manually? Before I look at any this:
|
|
As I expected, all builds fail. Of course they do! |
|
Max, I Apologize for the wall of text I did not have a feel for how much depth we wanted here. As for coding 'pipewire' into the MPC core. I can work on adding this code to the existing pipewire plugin to avoid that test in the core. I did have llm help for sure. I have been developing and using this patch for quite a while. Yes, I'll maintain it. I built this patch yesterday and am running it currently with no issues on the RPi. It does what it's supposed to do and it falls back to default behavior when configured as such. It appears that MPD had a later commit to when I forked. I just built my fork on Arch Linux, it builds and runs as well. I do not get exactly why it failed to build here. Please help me to understand what is going on with that. The git has changed since I pulled the repo, but still builds when I apply this as a patch to the current git. I forked I dev for the RuneAudio and we use MPD as the front end for it. Previously, we used ALSA. In a bare alsa setup, we try to use the native alsa volume control and wanted to basically duplicate that functionality with pipewire. I did not want to interfere with the initial audio stream navigated by MPD to pipewire, so opted to have a separate connection to wireplumber to control the sink volume. I use this to build it on Arch that I got from the mpd-git AUR: I get this package when I use the mpd-git AUR and substitute my fork... If I install it and enable it as a user service I get it to work and it does as I expect. If I comment that out, it defaults to normal mpd operation and this connection goes away. |
Added pwsink volume to the pipewire plugin
|
I hate reading all these LLM-generated too-verbose texts/code, and most likely I will reject this PR for that reason - reviewing LLM slop code is a DoS attack on maintainer's time. If you didn't bother to take the time to write this piece of code, don't expect me to take the time to read the code. Your LLM has certainly misunderstood the meaning of |
|
I do apologize for bothering you on this. The attention of hardware was my call. I was trying to mimic how the alsa worked. If you are heard set against this patch, that's fine. I'll apply and use it locally. |
|
Max, I can strip out the comments. |
|
Don't strip out comments. Documentation/comments are good, but only if they mean something. So please, don't submit LLM garbage here. That is not worth my time.
That would certainly an improvment over your current design. |
Unlike the existing pipewire mixer plugin (PipeWireMixerPlugin.cxx), which sets SPA_PROP_channelVolumes on MPD's own pw_stream (a per-client software gain stage applied before the signal reaches the sink, and not shared with other PipeWire clients), this plugin opens its own independent PipeWire client connection and drives a sink node's volume directly:
WirePlumber then applies the resulting volume through the ALSA hardware mixer control when the sink's Route reports one (route.hw-volume = true), or through PipeWire's own software volume otherwise -- giving PipeWire outputs the same "real hardware mixer" option that ALSA, OSS and PulseAudio outputs already have via mixer_type "hardware", instead of always paying for a second, client-side software gain stage on top of whatever WirePlumber itself applies.
MPD's own pw_stream is pinned to unity gain via
pipewire_output_set_volume() while this mixer is open, so the sink's own volume is the only gain stage in effect.
WirePlumber/wpctl display and set volume on a cubic scale rather than linear PCM gain; this is replicated here (config option "mixer_volume_curve") so a given MPD volume percentage matches what "wpctl get-volume" shows for the same node.
For a "pipewire" output, mixer_type "hardware" previously fell through to the output's own registered mixer_plugin (PipeWireMixerPlugin.cxx), i.e. the same client-side stream volume used when mixer_type is left unset entirely -- there was no way to ask for a real hardware/sink-backed mixer at all.
Special-case the HARDWARE case for pipewire outputs: if "mixer_type" is explicitly present in that output's config block (regardless of what any global default mixer_type is), use the new PwSinkMixer instead of the output's own plugin. If "mixer_type" is absent from the block, behaviour is unchanged (client-side stream volume via PipeWireMixerPlugin.cxx).
This intentionally inspects the block's raw configuration rather than the already-resolved MixerType, since the resolved value alone cannot distinguish "not configured, inherited the HARDWARE default" from "explicitly configured as hardware" -- and those two cases need different plugins here specifically because pipewire's own default mixer plugin already occupies the HARDWARE slot.
Output types other than "pipewire" are unaffected by this patch.
Also here is the documentation of the new behaviour of mixer_type "hardware" for pipewire outputs a "pipewire" ref label so other sections can link to it, describe the hardware-mixer opt-in and the mixer_volume_curve option in plugins.rst, and mention PipeWire alongside ALSA/OSS/PulseAudio in the mixer_type descriptions in user.rst and mpd.conf.5.rst.