Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolves #3092 Add source support to wireplumber module #3638

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

RowanLeeder
Copy link

This change adds support for source (microphone etc) nodes to the WirePlumber module.

This is done via a new "node-type": "Audio/Source" param (defaults to "Audio/Sink").

The intent here is to use two instances of the module to control the speakers and microphone separately:

// first instance controls speakers
"wireplumber#sink": {
    "format": "{volume}%",
    "format-muted": "",
    "on-click": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
},
// second instance controls microphone
"wireplumber#source": {
    "node-type": "Audio/Source",
    "format": "",
    "format-muted": "",
    "on-click": "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
}

- Adds microphone support etc to the wireplumber module.

  The existing module hardcodes the selected node type to "Audio/Sink". This feature allows the user to override this
  via `"node-type": "Audio/Source"`.

- Unlike the pulseaudio module, this change does not try to see the module manage both input and output. The same effect
  can be achieved by running two instances of the wireplumber module.

  This approach:
  - Works around some of the complexity overhead that seem to have caused similar PRs to stall.
  - Using separate module instances also allows both the microphone and speaker levels to be controlled with a scroll
    wheel. This is something a unified module like pulseaudio struggles with.
  - Similarly, separate instances allows the source volume level to be exposed as the state. Ie- the linear-gradient
    css patterns can be applied to both input and output.
- The module only fetches nodes for "node-type". This causes the 'onMixerChanged' log to spam whenever two or more
  wireplumber modules were registered on different nodes. To reduce this the unknown node warning will now only print
  if the node is not the focus of any current module.
@RowanLeeder
Copy link
Author

Re the use of two instances. While this is a break from the all-in-one pattern of the pulseaudio module etc, it does have several advantages.

The first is its simple. As is there doesn't seem to be a need for sink/source specific handling code. The module appears to function perfectly fine when targeting 'Audio/Source'. So other than logging, the only functionally change here was to swap the hardcoded value out with a parameter. The risk of a backwards breaking change should be very low.

The second is usability. The pulseaudio module bundles all the controls into a single event handler. To control both the speaker and microphone levels you need to use alt keys etc. You also can't export the source levels via states either.

Meanwhile with two instances you can get a two slider-esq controls that work consistently for both sink and source:
2024-09-25T06:07:19,377837198+10:00

"wireplumber#sink": {
    "format": "{icon}",
    "format-muted": "",
    "on-click": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle",
    "on-click-right": "helvum",
    "format-icons": ["", "", ""],
    "scroll-step": 5,
    "states": { "p0":0, "p5":5, "p10":10, "p15":15, "p20":20, "p25":25, "p30":30, "p35":35, "p40":40, "p45":45, "p50":50, "p55":55, "p60":60, "p65":65, "p70":70, "p75":75, "p80":80, "p85":85, "p90":90, "p95":95, "p100":100 }
},
"wireplumber#source": {
    "node-type": "Audio/Source",
    "format": "",
    "format-muted": "",
    "on-click": "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle",
    "scroll-step": 5,
    "states": { "p0":0, "p5":5, "p10":10, "p15":15, "p20":20, "p25":25, "p30":30, "p35":35, "p40":40, "p45":45, "p50":50, "p55":55, "p60":60, "p65":65, "p70":70, "p75":75, "p80":80, "p85":85, "p90":90, "p95":95, "p100":100 }
}
/* these rules apply to both the #sink and #source instances */
#wireplumber { padding: 0 4px; margin: 0 0px; min-width: 18px; }

#wireplumber.muted { color: #8c8c8c; }
#wireplumber.p0 { background: linear-gradient(to top, rgba(200,200,200,0.2) 0%, transparent 100%); }
#wireplumber.p5 { background: linear-gradient(to top, rgba(200,200,200,0.2) 5%, transparent 95%); }
#wireplumber.p10 { background: linear-gradient(to top, rgba(200,200,200,0.2) 10%, transparent 90%); }
#wireplumber.p15 { background: linear-gradient(to top, rgba(200,200,200,0.2) 15%, transparent 85%); }
#wireplumber.p20 { background: linear-gradient(to top, rgba(200,200,200,0.2) 20%, transparent 80%); }
#wireplumber.p25 { background: linear-gradient(to top, rgba(200,200,200,0.2) 25%, transparent 75%); }
#wireplumber.p30 { background: linear-gradient(to top, rgba(200,200,200,0.2) 30%, transparent 70%); }
#wireplumber.p35 { background: linear-gradient(to top, rgba(200,200,200,0.2) 35%, transparent 65%); }
#wireplumber.p40 { background: linear-gradient(to top, rgba(200,200,200,0.2) 40%, transparent 60%); }
#wireplumber.p45 { background: linear-gradient(to top, rgba(200,200,200,0.2) 45%, transparent 55%); }
#wireplumber.p50 { background: linear-gradient(to top, rgba(200,200,200,0.2) 50%, transparent 50%); }
#wireplumber.p55 { background: linear-gradient(to top, rgba(200,200,200,0.2) 55%, transparent 45%); }
#wireplumber.p60 { background: linear-gradient(to top, rgba(200,200,200,0.2) 60%, transparent 40%); }
#wireplumber.p65 { background: linear-gradient(to top, rgba(200,200,200,0.2) 65%, transparent 35%); }
#wireplumber.p70 { background: linear-gradient(to top, rgba(200,200,200,0.2) 70%, transparent 30%); }
#wireplumber.p75 { background: linear-gradient(to top, rgba(200,200,200,0.2) 75%, transparent 25%); }
#wireplumber.p80 { background: linear-gradient(to top, rgba(200,200,200,0.2) 80%, transparent 20%); }
#wireplumber.p85 { background: linear-gradient(to top, rgba(200,200,200,0.2) 85%, transparent 15%); }
#wireplumber.p90 { background: linear-gradient(to top, rgba(200,200,200,0.2) 90%, transparent 10%); }
#wireplumber.p95 { background: linear-gradient(to top, rgba(200,200,200,0.2) 95%, transparent 5%); }
#wireplumber.p100 { background: linear-gradient(to top, rgba(200,200,200,0.2) 100%, transparent 0%); }

@RowanLeeder RowanLeeder changed the title Issue #3092: Add source support to wireplumber module Resolves #3092 Add source support to wireplumber module Sep 24, 2024
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