aleho / gnome-shell-volume-mixer

GNOME Shell Extension allowing separate configuration of PulseAudio devices
https://extensions.gnome.org/extension/858/volume-mixer/
GNU General Public License v2.0
136 stars 32 forks source link

No PipeWire support #133

Closed xerz-one closed 3 years ago

xerz-one commented 3 years ago

When the system is using PipeWire as its audio server, regardless of whenever pipewire-pulse is installed, the extension is unable to run and stops itself. This is a compatibility issue to be regarded, as there is an ongoing push for PipeWire which includes default shipping on the next Fedora version.

This has been tested in Arch Linux, with GNOME 3.38.4 and PipeWire 0.3.23.

aleho commented 3 years ago

This extension doesn't do anything special in regards to accessing Pulseaudio. It either works or doesn't, but that's not up to me.

Moreover, Pipewire's Pulseaudio implementation is supposed to be a drop-in replacement. An application using Pulseaudio is supposed not to care about the server at all. So, even if I could add fixes for how I'm dealing with the server (which I can't) I really shouldn't.

Currently I'm using pipewire-pulse on Fedora and the extension behaves normally. There might be something broken with the Python script, but I still think this would be a bug in Pipewire.

Can you run the Python helper and provide it's output?

xerz-one commented 3 years ago

Running pautils/cardinfo.py merely returns {}, no additional error logs. Meanwhile, pavucontrol is able to see my devices just fine. Pavucontrol showing my sound cards

AlexWayfer commented 3 years ago

I have such error after about 1 second of DE reload:

image

shell-volume-mixer@derhofbauer.at/pautils/cardinfo.py also returns {}.

Vash63 commented 3 years ago

I'm also seeing this. It should probably be reported with Pipewire though, not here. Has anyone done so yet?

aleho commented 3 years ago

I'd have reported this issue if only I knew what to report.

All PA commands via Python are working here (I'm using feature/sinks-improvements branch currently, but that shouldn't actually make a difference). Pipewire 0.3.23.

Don't know what's wrong with the setups where it's broken. Especially since if the PA calls fail there should be an error, normally.

The branch feature/sinks-improvements contains updates to card / sink data retrieval. Could you try calling DEBUG=1 ./shell-volume-mixer@derhofbauer.at/pautils/query.py cards or DEBUG=1 ./shell-volume-mixer@derhofbauer.at/pautils/query.py sinks and paste the output here?

Vash63 commented 3 years ago

Just {} again for DEBUG=1 on cardinfo.py. I don't have a sinkinfo.py in my install.

aleho commented 3 years ago

@Vash63 Please checkout this repo and try the branch feature/sinks-improvements. It has a new util to query both sinks and cards:

DEBUG=1 ./shell-volume-mixer@derhofbauer.at/pautils/query.py cards DEBUG=1 ./shell-volume-mixer@derhofbauer.at/pautils/query.py sinks

Vash63 commented 3 years ago

Both output the same:

Requesting all available data
Query done
{}
aleho commented 3 years ago

Sorry, I really don't know what to do here.

The helper clearly doesn't fail, so it can only handle the data it is provided by the libpulse bindings. If there's no failure and no errors are being reported I'm pretty sure it's a system setup thing.

There's a libpulse import at the top of the introspected library:

try:
    lib = CDLL('libpulse.so.0')
except:
    lib = CDLL('libpulse.so')

Maybe your system path's are different?

Nevertheless, the pipewire-pulse implementation is supposed to provide a drop-in replacement. If it works in Pulseaudio it has to work in Pipewire.


pactl info:

…
Server Name: PulseAudio (on PipeWire 0.3.24)
Server Version: 14.0.0
…

DEBUG=1 ./query.py cards

Querying details...
Requesting all available data
In callback
Callback done
In callback
Callback done
In callback
Callback done
In callback
All done
Query done
{
    "46": {
        "index": 46,
        "alsaCard": 1,
        "name": "alsa_card.pci-0000_06_00.1",
        "description": "HD-Audio Generic",
        "active_profile": "off",
        "profiles": {
            "off": {
                "name": "off",
                "description": "Off",
                "available": true
            },
            "HiFi": {
                "name": "HiFi",
                "description": "Play HiFi quality Music",
                "available": false
            }
        },
        "ports": {
            "[Out] HDMI3": {
                "name": "[Out] HDMI3",
                "description": "HDMI3 Output",
                "direction": "out",
                "available": false
            },
            "[Out] HDMI2": {
                "name": "[Out] HDMI2",
                "description": "HDMI2 Output",
                "direction": "out",
                "available": false
            },
            "[Out] HDMI1": {
                "name": "[Out] HDMI1",
                "description": "HDMI1 Output",
                "direction": "out",
                "available": false
            }
        }
    }
}
…
saivert commented 3 years ago

The problem is that you loop for 1000 iterations but this isn't guaranteed to be enough to let everything initialize and connect. On my systems it sometimes returns all the card info and sometimes just "{}".

You need to use the event system in pulseaudio to check when it has actually connected.

But simply increasing the loops to 2000 or even higher may work but that is an ugly hack and you should fix your code.

I had success with this change (line 69)

while self._pa_state != pa.CONTEXT_TERMINATED:

I did not check the feature/sinks-improvements branch. edit: I just checked out feature/sinks-improvements branch and you do the same mistake there. Line 63 in pulseaudio.py.

Try this patch for feature/sinks-improvements branch:

diff --git a/shell-volume-mixer@derhofbauer.at/pautils/pulseaudio.py b/shell-volume-mixer@derhofbauer.at/pautils/pulseaudio.py
index 191fab0..578dce7 100755
--- a/shell-volume-mixer@derhofbauer.at/pautils/pulseaudio.py
+++ b/shell-volume-mixer@derhofbauer.at/pautils/pulseaudio.py
@@ -51,6 +51,15 @@ class Pulseaudio:
     def context_notify_cb(self, context, userdata):
         try:
             self._pa_state = pa.context_get_state(context)
+            sstate = ["PA_CONTEXT_UNCONNECTED",
+                      "PA_CONTEXT_CONNECTING",
+                      "PA_CONTEXT_AUTHORIZING",
+                      "PA_CONTEXT_SETTING_NAME",
+                      "PA_CONTEXT_READY",
+                      "PA_CONTEXT_FAILED",
+                      "PA_CONTEXT_TERMINATED"][self._pa_state]
+            log.debug("State:", sstate)
+
         except Exception:
             self._pa_state = pa.CONTEXT_FAILED
             log.debug('Context failed')
@@ -59,9 +68,7 @@ class Pulseaudio:
         log.debug('Querying details...')
         operation = None

-        loops = 1000
-        while loops > 0:
-            loops -= 1
+        while self._pa_state != pa.CONTEXT_TERMINATED:

             if self._pa_state == pa.CONTEXT_FAILED:
                 self._data = self._error
@@ -100,11 +107,12 @@ class Pulseaudio:

         return self._data

-    def pa_cb(self, context, struct, cindex, user_data):
+    def pa_cb(self, context, struct, eol, user_data):
         log.debug('In callback')

-        if not struct or not struct[0]:
-            log.debug('All done')
+        if eol: # End of list
+            self._op_done = True
+            log.debug('Callback done')
             return

         item = self.cb_data(struct[0])
@@ -112,9 +120,6 @@ class Pulseaudio:
         if item and 'index' in item:
             self._data[item['index']] = item

-        self._op_done = True
-        log.debug('Callback done')
-
     @abc.abstractmethod
     def build_callback(self):
         return
aleho commented 3 years ago

The looping was there to stop it from running forever. Can't remember why I added it in the first place, that code is many years old.

Vash63 commented 3 years ago

I can confirm the above patch fixes the python files for me. I can no longer test the extension proper as I've upgraded to Gnome 40, but both ./query.py cards as well as ./query.py sinks are now outputting my card/sink data.

aleho commented 3 years ago

Cool! I just pushed an update to the branch, this should fix it then.

aleho commented 3 years ago

@Vash63 As for Gnome 40: Don't know if this will happen soon here. There's a lot to adapt and test and I'm very busy at the moment.