easyeffects icon indicating copy to clipboard operation
easyeffects copied to clipboard

Explicit sink selection / Global "Excluded App List" ?

Open LebedevRI opened this issue 1 year ago • 8 comments

EasyEffects Version

7.1.6

What package are you using?

Other (specify below)

Distribution

debian sid

Describe the bug

With complicated pipewire configs, there may be a situation that there is a number of preexisting nodes, that already form some kind of a processing graph: config-pipewire.tar.xz.txt image

The idea is that "sink" is the default sink (that internally receives some final, absolutely mandatory, processing, and actually outputs to the audio card.). And everything (audio players, browser, etc) should output to that default `"sink", and never touch any other sink.

However, when starting EE, it tries to intercept all inputs to all Sinks: image image

That is kind of expected, i suppose. (I'm not sure if those extra sinks can be hidden on pipewire side.) The problem is, that completely messes up the preexisting graph, misconnects parts of it and maybe possibly creating cycles in it.

Even if i manually uncheck "Enable" and check "Exclude" for each of these inputs in EE "Output" -> "Players" list (see screenshot), that setting appears to be per-preset?

Expected Behavior

At the very least, i would love if there could be a setting (in EE's -> "PipeWire" -> "General" tab?) to explicitly tell it to ONLY intercept sources (players) that go to the chosen output. By chosen output, i mean the output that is referenced by the "Use Default Output" / "Name" preferences on that page.

Debug Log

No response

Additional Information

No response

LebedevRI avatar Jun 14 '24 21:06 LebedevRI

That is kind of expected, i suppose.

Forgot to elaborate: my general problem with that behavior is that it takes Sources that were never outputting to the Sink (to which EE then outputs the processed stream), and connects them.

I could imagine that there may theoretically be situations in which that is the desired behavior, but i really can't imagine that it should ever be the default behavior.

LebedevRI avatar Jun 14 '24 21:06 LebedevRI

I'm not sure if those extra sinks can be hidden on pipewire side

The reason why they are in EE players tab is that they are not sinks in the way we usually would expect. Like Pulseaudio PipeWire creates loopback devices through playback and recording streams. So for EE they are like any ordinary player/recorder stream. If you load a null-sink you will notice that it won't be visible in EE tab.

As usual there is a good and a bad side in having loopback devices implemented as streams. The bad side you have already seen. The good side is that people are able to apply effects to loopback devices... For example people that redirect smartphone audio to the PC through a loopback device can apply effects this way.

Forgot to elaborate: my general problem with that behavior is that it takes Sources that were never outputting to the Sink (to which EE then outputs the processed stream), and connects them

What you want seems similar to #1335 but for the output effects pipeline. It makes sense just like in the other issue. The problem is that PipeWire does not make it easy to actually implement it and I could never find a good solution. I wonder if the incomplete solution I was able to put in place for #1335 will help in your case.

My idea there was to use PW_KEY_TARGET_OBJECT https://github.com/wwmm/easyeffects/blob/3471aa440995ed3e1ab2383e77b6c1a6c44fa12c/src/pipe_manager.cpp#L313. The problem is that this tag may not be defined. It usually is only when the user selects a custom device in the players configuration. Maybe the targets set in PipeWire's configuration have the same effect.

wwmm avatar Jun 14 '24 22:06 wwmm

The good side is that people are able to apply effects to loopback devices... For example people that redirect smartphone audio to the PC through a loopback device can apply effects this way.

Right, sure. I'm just saying that it's already a solved problem outside of EE, you can edit the PW graph via qpwgrap / carla / etc, and even pavucontrol allows to specify where each Playback stream should go.

My idea there was to use PW_KEY_TARGET_OBJECT

https://github.com/wwmm/easyeffects/blob/3471aa440995ed3e1ab2383e77b6c1a6c44fa12c/src/pipe_manager.cpp#L313

. The problem is that this tag may not be defined. It usually is only when the user selects a custom device in the players configuration. Maybe the targets set in PipeWire's configuration have the same effect.

Right. That would solve it for me for sure, but i don't quite follow why the solution would be so special-cased. Why look for that specific tag specifically? It seems a bit backwards: i would think the solution would be to introspect the actual PW graph (& listen to it's updates), find the node ("Sink") to which we will be outputting, find all the nodes that feed into that "Sink", and proxy them through EE pipeline.

LebedevRI avatar Jun 14 '24 23:06 LebedevRI

Why look for that specific tag specifically? It seems a bit backwards: i would think the solution would be to introspect the actual PW graph (& listen to it's updates), find the node ("Sink") to which we will be outputting,find all the nodes that feed into that "Sink", and proxy them through EE pipeline.

This would work if all that information were available when we are notified about the node existence. But this isn't the workflow. It is totally valid in PipeWire to have a node that is not connected to anything. So when we are first notified about a node the information that comes does not include that this node will eventually be linked to a particular device. But at the same time this information comes we have to decide what to do with this node and we ask ourselves "Do we move it to our virtual device or not?". We can't keep waiting forever for a signal that may never come.

The reason why the approach you have in mind is not viable is because both on PipeWire and Pulseaudio the client reacts to server signals. It does not keep polling for information in an infinity loop. The server sets the tags when it considers it has to. And sometimes it may consider it does not have to. Once it does something it broadcasts a signal. There isn't a function call to "introspect the PW graph". We have to keep our own list of everything that we may need based on the signals that come.

wwmm avatar Jun 14 '24 23:06 wwmm

The reason why PW_KEY_TARGET_OBJECT helps is because when this tag is set its value comes together with the first signal about the node existence. So we can make a decision without having to wait for a signal that may or may not be emitted.

wwmm avatar Jun 14 '24 23:06 wwmm

@LebedevRI I've updated our master branch with the "fix" discussed before. Let me know if it was enough.

wwmm avatar Jun 18 '24 15:06 wwmm

@wwmm thank you! As long as you've checked that it succeeds in what it claims to do, it should be enough.

LebedevRI avatar Jun 18 '24 19:06 LebedevRI

@wwmm thank you! As long as you've checked that it succeeds in what it claims to do, it should be enough.

I only tested in VLC because I think it is the only player I have installed that allows selection of the output device. If I set a different device before creating the stream it works as intended.

wwmm avatar Jun 18 '24 20:06 wwmm

Yes, it appears to be working as intended on my configuration. @wwmm Thank you!

LebedevRI avatar Jul 06 '24 21:07 LebedevRI

For reference, it seems like this was fixed by https://github.com/wwmm/easyeffects/commit/5f207c83ff9f4dea64dfa0e97811dccb3334f5f8.

LebedevRI avatar Jul 22 '24 20:07 LebedevRI

For reference, it seems like this was fixed by 5f207c8.

Which completely breaks EE for me and makes it ignore all audio sources…

v-fox avatar Jul 23 '24 05:07 v-fox

For reference, it seems like this was fixed by 5f207c8.

Which completely breaks EE for me and makes it ignore all audio sources…

I still wonder how. That commit only changed how the output pipeline is handled. The same change was applied to the microphone pipeline many months before. So if that is the real source of the problem sources handling on your computer should have been broken for a while. Something else must be going on.

wwmm avatar Jul 23 '24 14:07 wwmm

I still wonder how. That commit only changed how the output pipeline is handled. The same change was applied to the microphone pipeline many months before. So if that is the real source of the problem sources handling on your computer should have been broken for a while. Something else must be going on.

Are you not using latest PW and WP versions/snapshots too? Usually, most devs refuse to take reports seriously if you're not using their latest snapshot, let alone release. In this case, it's especially bad because EE also triggers a bad crash and "random silence"-bug in PW.

It's like PW dev refuses to test with EE, so it sometimes gets broken, and you refuse to test with latest PW and this happens. Now it's a "double whammy" on the bleeding edge.

v-fox avatar Jul 23 '24 15:07 v-fox

Are you not using latest PW and WP versions/snapshots too?

I use the stable package in Arch Linux repositories. At this moment it has version 1.2.1.

and you refuse to test with latest PW and this happens

Are you really suggesting I should spend time building my own packages from PipeWire's master branch?

wwmm avatar Jul 23 '24 15:07 wwmm

As far as I can see version 1.2.1 was released last week. This is latest enough. And yet I still can not reproduce the bug. That is why I say something else must be involved.

wwmm avatar Jul 23 '24 15:07 wwmm

I use the stable package in Arch Linux repositories. At this moment it has version 1.2.1.

Seems like there were some substantial changes since then but it's probably recent enough. At least for the crash bug.

Ah, and do you have several sinks to choose? I do.

Are you really suggesting I should spend time building my own packages from PipeWire's master branch?

That's what almost any developer demands when debugging. Especially when it's your main dependency and you're on a distro that is designed for self-built packages. Personally, I just use openSUSE's OBS build-farm.

As far as I can see version 1.2.1 was released last week. This is latest enough. And yet I still can not reproduce the bug. That is why I say something else must be involved.

What about WP? Is it 0.5.5? By the way, I have this in my ~/.config/wireplumber/wireplumber.conf.d/10-defaults.conf:

wireplumber.settings = {
  device.routes.default-sink-volume = 0.2
  device.routes.default-source-volume = 0.6
  node.features.audio.monitor-ports = true
  node.features.audio.control-port = true
  node.filter.forward-format = true
}

v-fox avatar Jul 23 '24 15:07 v-fox

What about WP? Is it 0.5.5?

Yes.

Ah, and do you have several sinks to choose? I do.

Yes. Besides the optical port of my onboard card I also use bluetooth headphones/mic and there is also the hdmi card in my monitor. But this one I only use for testing purposes and not in my daily routine.

That's what almost any developer demands when debugging. Especially when it's your main dependency and you're on a distro that is designed for self-built packages. Personally, I just use openSUSE's OBS build-farm.

In the past I built packages from PipeWire's development branch from time to time. I do not see a reason to go through that annoyance again. The Arch Linux packages are updated fast enough to the latest PipeWire releases. As long as PipeWire devs do not take forever to make a release there is no need to switch my main computer away from the repository package.

By the way, I have this in my ~/.config/wireplumber/wireplumber.conf.d/10-defaults.conf

I do not have a wireplumber folder inside .config. Only the one at .local/state/wireplumber/. Probably because I never had the need to customize WirePlumber configurations. The only minor configuration I've ever done was to .config/pipewire/pipewire.conf.

wwmm avatar Jul 23 '24 16:07 wwmm

By the way, I have this in my ~/.config/wireplumber/wireplumber.conf.d/10-defaults.conf

And I do not see how the settings you've made could cause the problem you are facing. Maybe some kind of configuration is not enabled in your custom package at building time but it is in the Arch repository package? I would expect to see more reports similar to yours if the source of the problem was something more widespread.

wwmm avatar Jul 23 '24 16:07 wwmm

I do not have a wireplumber folder inside .config. Only the one at .local/state/wireplumber/. Probably because I never had the need to customize WirePlumber configurations. The only minor configuration I've ever did was to .config/pipewire/pipewire.conf.

That's why I'm bringing this up, in case it changes routing behaviour. I have quite a lot of customization there because I had to migrate my pipewire-media-session configs into it, especially ALSA's defaults part. But the rest don't seem to be routing-related.

The biggest configuration changes in PW & WP are related to smaller period sizes, shortened buffer size limits in range of 12-48 ms and forced increase of default resampling quality from level 4 to 9. But those seem irrelevant.

And I do not see how the settings you've made could cause the problem you are facing. Maybe some kind of configuration is not enabled in your custom package at building time but it is in the Arch repository package? I would expect to see more reports similar to yours if the source of the problem was something more widespread.

I don't think that I disabled or missed any features in either. Except for elogind and tests in WP.

I would expect to see more reports similar to yours if the source of the problem was something more widespread.

The PW crash bug that I've linked to is a complete disaster and it only has 3 upvotes including mine, so not many people are using EE in general, it seems. The worst part about it is players and Firefox randomly muting (probably, losing stream between source app and sink) on starting playback, pause/unpause and seeking. Crash happens when it doesn't fix itself after repeated unpause or seek. So, you would think that something so bad would also have a lot of reports and not be ignored for weeks by the developer, who even made a new release with a known bug like that.

v-fox avatar Jul 23 '24 16:07 v-fox

The PW crash bug that I've linked to is a complete disaster and it only has 3 upvotes including mine

Somehow I do not remember having ever seen PipeWire crashing.

so not many people are using EE in general, it seems.

I do not think it is because there is almost nobody using EasyEffects. We obvisouly do not have as many users as Firefox, KDE, LibreOffice, etc but there is probably a few hundreds out there. The interaction with the other system libraries packaged by each distributions maybe be somehow involved.

The worst part about it is players and Firefox randomly muting (probably, losing stream between source app and sink) on starting playback, pause/unpause and seeking.

This bug I see on my computer and I think it is related to an old bug I reported to PipeWire devs a long time ago https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/3547. It just got worse in the last 2 maybe 3 months. I do not see what I can do about it. I tried many things to fix it on my side along the years and nothing I did has had any effect on it. As far as pw-dot output is concerned everything that EasyEffects could do is done. The links are reported to be there and in the active state. And yet when the bug happens there is no audio.

wwmm avatar Jul 23 '24 16:07 wwmm

In any case like I said in the other issue the patches I did only do something if a target node is set by the stream https://github.com/wwmm/easyeffects/blob/c1b678a11846aa6eb9a3392a5332e8c1c5dab713/src/pipe_manager.cpp#L342. That is why I do not understand why you computer is having problems with it. All the streams that do not set a target should not be touched by the patch. And among the ones that set something only the streams that have a different output device as target should be avoided. It is almost like wireplumber has some kind of hidden cache on your computer that has set to your streams an output device as target that does not match the one used by EasyEffects.

wwmm avatar Jul 23 '24 16:07 wwmm

The worst part about it is players and Firefox randomly muting (probably, losing stream between source app and sink) on starting playback, pause/unpause and seeking.

This bug I see on my computer and I think it is related to an old bug I reported to PipeWire devs a long time ago https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/3547. It just got worse in the last 2 maybe 3 months. I do not see what I can do about it. I tried many things to fix it on my side along the years and nothing I did has had any effect on it. As far as pw-dot output is concerned everything that EasyEffects could do is done. The links are reported to be there and in the active state. And yet when the bug happens there is no audio.

Worse. This is not new, second similar bug. Here whole stream is lost, not just the right channel. Or maybe it morphed into it since I don't remember losing just one channel lately. But that's my point exactly: this is such a bad, long-standing and widespread bug that you would expect people complain by hundreds, yet it's somehow not the case. So this one may also be more widespread that it appears.

It is almost like wireplumber has some kind of hidden cache on your computer that has set to your streams an output device as target that does not match the one used by EasyEffects.

But that would mean that they don't switch when default is switched, yet I often switch between dedicated DAC with headphones and one with speakers. Sometimes I also connect a BT headset.

However, I just did a quick search for target in pw-dump while playing a Youtube video in Firefox and got "target.object": "jack_out" in the node of FF. Same goes for strawberry player. This might be the culprit but I still don't get where it came from. greping PW source showed:

pipewire/src/modules/module-protocol-pulse/modules/module-jackdbus-detect.c:161:                pw_properties_set(sink_props, PW_KEY_NODE_NAME, "jack_out");

Which is silly, considering that "jack instance" is PW itself, module-jackdbus-detect does not even seem to be loaded and no config for PW or WP mentions it, other than support.dbus = true in pipewire.conf

v-fox avatar Jul 23 '24 17:07 v-fox

However, I just did a quick search for target in pw-dump while playing a Youtube video in Firefox and got "target.object": "jack_out" in the node of FF. Same goes for strawberry player. This might be the culprit but I still don't get where it came from.

This is weird and it does not feel like the intended behavior. Or at least I've always assumed that a target node is only set if the stream requested it. In other words if the user selected a custom device in the player configuration.

If this weird target in your logs is indeed the "intended wireplumber/pipewire" behavior in setups like the one you have I guess I will have to put the new procedure behind a configuration option. Just going back to how we were before is not good. EasyEffects should not be touching streams where the user selected a custom output that is not the one EasyEffects is supposed to use.

wwmm avatar Jul 23 '24 17:07 wwmm

Worse. This is not new, second similar bug. Here whole stream is lost, not just the right channel. Or maybe it morphed into it since I don't remember losing just one channel lately. But that's my point exactly: this is such a bad, long-standing and widespread bug that you would expect people complain by hundreds, yet it's somehow not the case. So this one may also be more widespread that it appears.

FWIW, i, occasionally, very rarely, still see such kind of issues with EE. I strongly suspect there are race conditions going on. I'm not qualified to say whether or not the EE's "ad-hoc" way of handling PW graph is ad-hoc or PW is simply missing the right infra, but something there does seem aloof.

LebedevRI avatar Jul 23 '24 17:07 LebedevRI

This is weird and it does not feel like the intended behavior. Or at least I've always assumed that a target node is only set if the stream requested it. In other words if the user selected a custom device in the player configuration.

I assume that it was intended to be used only with real jackdbus running. But I haven't looked closer into it. Besides, something like that should probably be in WP instead of PW, so it might be some old stale code.

If this weird target in your logs is indeed the "intended wireplumber/pipewire" behavior in setups like the one you have I guess I will have to put the new procedure behind a configuration option. Just going back to how we were before is not good. EasyEffects should not be touching streams where the user selected a custom output that is not the one EasyEffects is supposed to use.

Making automatic exception for jack_out might also be an option. But, again, this is very messy hardcoded redirection for such niche case: running real jackd with PW, using its dbus binary and wanting PA apps being auto-redirected into it… Or maybe it's not even set by this module but I haven't any other trace of that name.

I strongly suspect there are race conditions going on.

Indeed.

v-fox avatar Jul 23 '24 18:07 v-fox

I strongly suspect there are race conditions going on.

For a long time I suspected that this bug was related to the fact we linked and unlinked our filters based on whether there were active streams connected to our virtual devices. I thought that maybe this was the race trigger. So a few weeks ago I decided to disable this behavior in the output pipeline. Nowadays PipeWire does a better job when it comes to pause the filters when nothing is actually sending audio. But unfortunately the missing audio bug still happens even if we do not remove the links between the filters.

I do not have any other place in EasyEffects that could seem the culprit. If the pipeline is already built by the time a player becomes active and there is no audio even when pw-dot reports that the links are all active the problem must be somewhere inside PipeWire.

wwmm avatar Jul 24 '24 00:07 wwmm

I'm not qualified to say whether or not the EE's "ad-hoc" way of handling PW graph is ad-hoc or PW is simply missing the right infra, but something there does seem aloof.

As I am using the the pw_filter objects PipeWire has created for the implementation of dsp filters the procedure I use is essentially the same as the one in PipeWire's backend for Jack apps. A long time ago I wondered if the fact I ask PipeWire to set passive links could be related to this bug but PipeWire's devs did not seem to think this could be the case. And setting the links to not be passive can have some undesirable side effects. So I am not sure this is an option to consider even if it somehow "solves" the bug.

wwmm avatar Jul 24 '24 00:07 wwmm

This is weird and it does not feel like the intended behavior. Or at least I've always assumed that a target node is only set if the stream requested it. In other words if the user selected a custom device in the player configuration.

I assume that it was intended to be used only with real jackdbus running. But I haven't looked closer into it. Besides, something like that should probably be in WP instead of PW, so it might be some old stale code.

It seems I finally figured it out and the real cause is even stupider: PW was reading original PA's configs in ~/.config/pulse which were made before PW even existed and contained lines like load-module module-jack-sink & set-default-sink jack_out for the original jackd. No wonder the name seemed familiar. The stupid thing was overriding its own configs with ancient PA configs for no reason. I didn't know it can ever read those. Moving ~/.config/pulse away removed the stupid forced target directive from appearing and EE started working without reverts.

Not sure how to even report something so broken-by-design. It probably was intended for "easier migration" at some point. One of those many insane things that PW & WP do with its "configuration" scripting hellscape.

v-fox avatar Jul 24 '24 03:07 v-fox

PW was reading original PA's configs in ~/.config/pulse which were made before PW even existed and contained lines like load-module module-jack-sink & set-default-sink jack_out for the original jackd. No wonder the name seemed familiar. The stupid thing was overriding its own configs with ancient PA configs for no reason. I didn't know it can ever read those.

It never crossed my mind something like this could happen. After reading this I decided to remove the old pulse folder that still was in my configuration folder :smile:

It probably was intended for "easier migration" at some point. One of those many insane things that PW & WP do with its "configuration" scripting hellscape.

Although I can see this helping users in some corner cases I think that on average this PipeWire's behavior does more harm than good. Once we move from a server to another we do not expect configuration files for the previous server to still be doing something.

wwmm avatar Jul 24 '24 14:07 wwmm