wwmm / easyeffects

Limiter, compressor, convolver, equalizer and auto volume and many other plugins for PipeWire applications
GNU General Public License v3.0
6.13k stars 264 forks source link

mutichannel (routing)? #1126

Open capoei opened 2 years ago

capoei commented 2 years ago

Is there any way to add multi-channel mangement/routing? just as an example my use case (which would also require the adition of the possibility of a other instance of the convolver): stereo signal > room correction convolution > crossovers via convolution resulting in 4 channels > routing of channels to my audio interface outputs

Digitalone1 commented 2 years ago

Okay, the user should exclude it on their own.

Digitalone1 commented 2 years ago

@JohnyPeaN you can already do it with the latest release.

The pipewire loopback in the default configuration loads an input and an output stream. Both do not show in device lists because they are streams.

If you load the pipewire loopback in an alternative way:

pw-loopback -m '[FL FR]' --capture-props='media.class=Audio/Sink'

A sink and an output stream are spawned, so you can select the sink as the output device in EasyEffects.

Anyway it's still tricky because every time the loopback is created, it changes name. For this reason you have to manually set the output device and exclude the loopback output stream in EasyEffects anytime the loopback configuration is generated. The exclusion is crucial because with Process All Output Stream set, the output loopback will fee our EasyEffects Sink.

Unfortunately I can't see a way to set the name of the nodes (even with the examples shown on the Pipewire Wiki posted above because it only sets the description on the sink). You can open a ticket on Pipewire Issue for this.

Anyway, it should work.

wwmm commented 2 years ago

Unfortunately I can't see a way to set the name of the nodes

This sets a decent name in my computer

pw-loopback -m '[ FL FR]' --capture-props='media.class=Audio/Sink node.name=myloop node.description=MyLoop'

In EasyEffects device selection menu we show the device description because it is more user friendly than the node name. So the description has to be set too.

wwmm commented 2 years ago

This sets a decent name in my computer

I meant to say a decent name for the devices. The stream related to the loopback and shown in our Players/Recorders tab will still be super ugly.

Digitalone1 commented 2 years ago

Indeed the name is not persistent and the loopback stream cannot be excluded. Unless there's a way to set the app id string on it. I don't know if it's possible.

wwmm commented 2 years ago

Maybe to change the playback stream tags we also have to pass --playbacke-props and set something there

wwmm commented 2 years ago

This changes the stream name

pw-loopback -m '[ FL FR]' --capture-props='media.class=Audio/Sink node.name=myloop node.description=MyLoop' --playback-props='node.name=myloop_playback node.description=MyLoop_Playback'
JohnyPeaN commented 2 years ago

Can confirm. This loopback can be excluded and persistently selected in output devices. Works on 2ch output. Will test later on 5.1.

JohnyPeaN commented 2 years ago

Managed to achieve quite working scenario:

EE: autorun = on manage all outputs = off profile autoload

~/.config/pipewire/pipewire.conf.d/10-my-loop.conf

context.modules = [
    {   name = libpipewire-module-loopback
        args = {
            audio.position = [ FL FR ]
            capture.props = {
                media.class = Audio/Sink
                node.name = myloop
                node.description = "MyLoop"
            }
            playback.props = {
                node.name = myloop_playback
                node.description = "MyLoop_Playback"
               }
        }
    }
]

I added myloop_playback to excluded list. Screenshot_EasyEffects_4

Manually configured MyLoop in pipewire tab > Output Device Screenshot_EasyEffects_2 Screenshot_20220417 Loopback device is automatically created with fixed name, EE starts and correctly uses it. Enabled application then get connected through EE, and loopback ( providing upmix ) to default sink. Other applications connect dirrectly to default sink.

Even switching output devices 2ch <> 5.1ch back and forth works on the fly and loopback enables/disables upmix.

This is persistent, no need to create and connect loopback by hand everytime and seems to be working great. Will use it this way to see if it has some caveats.

Winnus commented 1 year ago

Thank you ! The solution above worked out of the box for me on a Fedora 36 system.

Digitalone1 commented 1 year ago

@wwmm I think this issue should be stuck in place of #1216 and the title modified in Multichannel routing on EasyEffects.

ClumsyDerp commented 1 year ago

Screenshot_20220417

Stumbled across the same problem and wound up here eventually.

I've read through most of this issue and tried to understand what I could.

In my particular case I couldn't get it to work just yet, as using either EE or JamesDPS on my virtual surround sink causes all sound to just disappear all while only being stereo on top of it. That said, I've been wondering what tool/command is being used in the provided screenshot. It appears to be a part of common knowledge I seem to be missing or couldn't pick up on reading through this thread. Futher it could help me resolve my particular issue(s).

If anyone could point me towards the correct direction it'd be much appreciated.

Digitalone1 commented 1 year ago

@ClumsyDerp the tool is helvum. But you don't really need it. Just install pavucontrol and redirect the loopback output to the multichannel device.

ClumsyDerp commented 1 year ago

Tinkered around with the tools but it appears I got a different setup from JohnyPean.

Helvum Screenshot (attempted to recreate JohnyPean's setup)

Bottom line: The ADI 2 DAC is my actual physical device and only has two channels as shown by helvum and is entirely bypassed in my example, which strikes me as wrong - or rather, I'd have to somehow throw eight channels into two. From my limited understanding I may just be sending my sound in circles right now, if even that 🤡

The "Virtual Surround Sink" is a "fake" Pipewire 7.1 sink, as per their example.

Desired outcome: Apply EE equalizer features but retain 7.1 virtual surround.

Digitalone1 commented 1 year ago

You should enable Firefox in EasyEffects. EasyEffects should be set to output to myloop (as it seems to already be configured).

Then you go in Pavucontrol and redirect myloop_playback to the DAC.

Digitalone1 commented 1 year ago

For what I said, which is the usual configuration, you won't get the up/downmix because the DAC is only 2 channels.

For what you want, it seems the virtual surround you got is not enough because the 7.1 virtual surround sink is not an output stream. So you can't redirect it in pavucontrol.

You could try to send EasyEffects to 2.0 Virtual Surround Sink and to to redirect the 7.1 Virtual Surround Sink to the DAC. But I'm afraid you can't do it from pavucontrol and the only option is doing it manually, which is not a true downmix like you you wanted.

Digitalone1 commented 1 year ago

Oh, now I see from the sink-virtual-surround-7.1-hesuvi.conf that the capture is the 7.1 and the playback is the 2.0, so I think want you want can't be done because we don't have a way to upmix from 2 to 8 channels.

The upmix we suggested here is happening because fortunately we can link 2 channel filters to 2 channel virtual sinks. Then Pipewire does the upmix on its own.

For what you want, you need first an upmix and then a downmix. That configuration is not good and EasyEffects can't do both.

wwmm commented 1 year ago

The ADI 2 DAC is my actual physical device and only has two channels as shown by helvum Desired outcome: Apply EE equalizer features but retain 7.1 virtual surround.

Even without EasyEffects in the way it does not make much sense to me to create this kind of virtual surround if your sound card has only 2 channels. If I am not mistaken the virtual surround created by PipeWire and Pulseaudio is intended for hardware that actually have all these channels. So even without EasyEffects you won't be retaining the 7.1 surround. It will be downmixed to stereo. Am I missing something here?

ClumsyDerp commented 1 year ago

The ADI 2 DAC is my actual physical device and only has two channels as shown by helvum Desired outcome: Apply EE equalizer features but retain 7.1 virtual surround.

Even without EasyEffects in the way it does not make much sense to me to create this kind of virtual surround if your sound card has only 2 channels. If I am not mistaken the virtual surround created by PipeWire and Pulseaudio is intended for hardware that actually have all these channels. So even without EasyEffects you won't be retaining the 7.1 surround. It will be downmixed to stereo. Am I missing something here?

I can't argue for pipewire's way of handling things, as well as potential magic that is going on under the surface but I can vouch for a spacial upgrade compared to stereo and all directions seem to be fully in tact. It's comparable, if not exceeding Window's spacial sound API - in this instance compared to DTS:X, which I also use/own.

If you happen to own a pair of headphones feel free to try it out for yourself, it only takes a few minutes to set up.

Simply copy the file content from { name = libpipewire-module-filter-chain [...] } into your pipewire.cfg's context.modules = [...] section and replace the hrir.wav's references to an actual reference file on your system.

wwmm commented 1 year ago

It's comparable, if not exceeding Window's spacial sound API - in this instance compared to DTS:X, which I also use/own.

Interesting. I had the impression that the downmixing to stereo would kill any spatial feeling that had been added by the virtual surround.

But in this case I do not see why a custom loopback device between your virtual surround sink and EasyEFfects virtual sink should not work. I admit I did not read all the conversation in detail because I am at my work now. But if downmixing is not a problem a loopback from 7.1 to stereo should work.

Digitalone1 commented 1 year ago

Try it. Maybe you're lucky.

ClumsyDerp commented 1 year ago

Unfortunately did not work, but I might as well been doing something wrong.

Picture.

I pretty much build what you've suggested, haven't done anything with pavucontrol yet, though.

Additional info:

I'll dig a bit into pavucontrol.

Cheers.

Digitalone1 commented 1 year ago

Close Plasma System Settings, it won't help you.

You have to redirect the streams with Pavucontrol (install it if you does not have it).

Uncheck the enable checkbutton for Virtual Surround in EasyEffects (leave it excluded).

In Pavucontrol, first tab (Players), MyLoop_Playback to Virtual Surround and Virtual Surround Sink to ADI DAC.

ClumsyDerp commented 1 year ago

Hope this is what it's supposed to be; opening Pavucontrol makes a mess of helvum 🤡

No idea why MyLoop_Playback receives two PulseAudio Volume Controls.

Beyond that the only way to get sound out of FF is to route it against the ADI DAC directly and then neither EE works, nor the surround sound. MyLoop_Playback and Virtual Surround remain dead quiet.

At this point I already feel as though I'm in way over my head 🙈

Digitalone1 commented 1 year ago

In pavucontrol is everything good. The issues is virtual surround 2.0 going into EasyEffects sink. Remove that link from helvum.

ClumsyDerp commented 1 year ago

Hey, sorry for the late response. Sleep, work, you know the drill.

That said, I got good news. Some of the mess cleaned itself up (MyLoop_Playback no longer has two PulseAudio Volume Controls) upon boot and it now works as expected and further the way you laid out above. Confirmed EQ effects to be applied and the surround sink still plays back on all channels.

Link

Sorry for hijacking this particular issue, should it have been misplaced.

Thanks for the support, much appreciated and if nothing else I hope it'll serve others down the line.

Cheers!

rijnhard commented 1 year ago

this is probably a naive comment, but if I have to think about my dream scenario for multi-channel audio handling,

multi channel source
          --> (filter all channels) e.g. some funny bunch of filters I slap together for my own Dynamic Range Compression
          --> (start individual channel filters) 
                   | -> FR/FL  --> (2 chan filter) 
                   | -> Centre --> (1 chan filter)
                   | -> RL/RR  --> (2 chan filter)
          --> (end individual channel filters) 
          --> (filter all channels)
          --> FFmpeg encoding for output format

I remember back when I used windows, with K-Lite I used to construct filter & processing graphs in all sorts of weird and wonderful ways. and then re-encode the output so that I could feed it into a sound card or a receiver over HDMI.

rijnhard commented 1 year ago

(barring the FFmpeg part which I think is really out of scope unless somehow the output can marked as passthrough for pipewire)

a structure like that could be really flexible for anyone wants to handle any kind of processing, the choice to combine 2 channels together for a 2channel filter for example is also pretty useful.

It doesn't directly solve upmixing or downmixing but can be a good structural building block for how to cater for that later on. Maybe easier basic mixing options would simply be:

Probably the biggest consequence is that filters need to be aware of how many channels they can accept and how many the pipe is trying to provide it, which it shouldn't allow if there's a mismatch.

wwmm commented 1 year ago

this is probably a naive comment, but if I have to think about my dream scenario for multi-channel audio handling,

I would not call it naive. In a multichannel setup it is a reasonable expectation to be able to apply different filters for each channel. It just isn't what EasyEffects evolved for. An approach similar the Windows EQualizer APO would make more sense in this case.

Probably the biggest consequence is that filters need to be aware of how many channels they can accept and how many the pipe is trying to provide it, which it shouldn't allow if there's a mismatch.

There are 2 ways to create filters in PipeWire but if I remember well in both of them you have to hardcode the number of filter channels. So the filter would probably have to be made by default with a large number of channels.

But the worse is dealing with third party filters that are designed for stereo. I think that the Windows Equalizer APO uses its own filters for everything. What makes things a lot easier. But most of the ones used in EasyEffects are LV2 filters designed for stereo.

rijnhard commented 1 year ago

I would not call it naive. In a multichannel setup it is a reasonable expectation to be able to apply different filters for each channel. It just isn't what EasyEffects evolved for. An approach similar the Windows EQualizer APO would make more sense in this case.

So that would mean a rearchitecture, ouch. Painful. If that were to happen then you would want to basically make it a graph engine.

There are 2 ways to create filters in PipeWire but if I remember well in both of them you have to hardcode the number of filter channels. So the filter would probably have to be made by default with a large number of channels.

I don't think this is a problem really. I'll elaborate below.

But the worse is dealing with third party filters that are designed for stereo. I think that the Windows Equalizer APO uses its own filters for everything. What makes things a lot easier. But most of the ones used in EasyEffects are LV2 filters designed for stereo.

You don't actually need full multi channel support on every filter, most will work fine applied to a single or 2 channels, and with a bit of elbow work and some ui magic (linking a couple instances of the same filter together) you could use 2 channel filters pretty effectively.

With a good foundation you can always work on a specific set of filters being multi channel, or the community can. To be a bit cheeky I don't think that's really the goal here. Of course that's the dream, but not the starting point, by comparison easy effects is still a young project, so I don't think anyone expects it to solve all those rather complex problems in a short timeline.

Of course this is all subject to your vision for it and what you want it to be at the end of the day.

wwmm commented 1 year ago

So that would mean a rearchitecture, ouch. Painful.

Very painful. When I started this project I had things like Viper4Android in mind. And as I have a stereo sound system stereo audio inevitably became a central point in EasyEffects design.

You don't actually need full multi channel support on every filter, most will work fine applied to a single or 2 channels, and with a bit of elbow work and some ui magic (linking a couple instances of the same filter together) you could use 2 channel filters pretty effectively.

As multichannel support is never going to happen to third party stereo plugins ignoring one of the 2 channels would be the only option when trying to apply them in a surround setup. Technically it will probably work but there are some annoyances. Our graphical interface will still try to show 2 level meters for example. So besides the special handling to links in the pipeline the plugin window would have to adapt to each scenario and showing only what makes sense. Nothing particularly complicated to ensure. But I would expect other small inconsistencies to show themselves along the way.

There are also plugins that do not make any sense at all outside of a stereo setup and that we would have to make sure are never added to multichannel processing. The crossfeed and the stereo tools plugins are one example.

But the hard part is that we would be essentially talking about one pipeline for each surround channel. At the end of the day this is what would happen with plugins that have only one or two channels. Handling them and allowing the user to configure them through our window would be quite challenging considering that PipeWire may change the sound card profile at any moment.

Of course this is all subject to your vision for it and what you want it to be at the end of the day.

I think it would be super cool to support multichannel. But I have to be realist. With the main developers (me and @Digitalone1) being stereo users and the amount of work necessary for proper multichannel support being really big I do not see this happening even in the far future. Maybe once we finally start to support multiple filter instances a good solution comes to my mind. But at this moment it feels like a distant dream.

ilippert commented 1 year ago

with respect to https://github.com/wwmm/easyeffects/issues/1126#issuecomment-1147748628

This is persistent, no need to create and connect loopback by hand everytime and seems to be working great. Will use it this way to see if it has some caveats.

I agree that it works across boots, great.

However, when I send my computer to sleep/suspension, the loop device stops subsequently working. I reboot, and then it works again.

wwmm commented 1 year ago

However, when I send my computer to sleep/suspension, the loop device stops subsequently working. I reboot, and then it works again.

It may be worth to tell this to PipeWire developers. If only the loopback is not coming back after the PC sleeps it may be a bug on their side.

ilippert commented 1 year ago

It may be worth to tell this to PipeWire developers.

done – https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2862

kode54 commented 10 months ago

What about upmixing mono playback sources to stereo? Is there a filter I can add that will only upmix as necessary?

wwmm commented 10 months ago

What about upmixing mono playback sources to stereo? Is there a filter I can add that will only upmix as necessary?

There is the Stereo Tools plugin but it is not going to do it ondemand only to what is necessary. It will change the stereo matrix of everything that is passing through the effects pipeline.

b1r63r commented 4 months ago

I think my proposed roadmap would be

1) offer the same number of inputs as the selected output coding would then be limited to handling the difficulties in switching number of inputs when output switches etc. run effects only on the front stereo speakers and pass everything else through unchanged. this would of course lead to some timing issues between channels, but ok for now.

2) add basic timing adjustments for individual channels i guess this will be needed to delay the pass-through channels so they sync up with the filtered ones, as well as to cater for speaker placement in 5.1 or 7.1 systems these must be tied to the selected output since 5.1 speaker system needs different timings than a 5.1 headphone.

3) add handling of the subwoofer channel. offer the ability to remove the sub channel from what is presented to the clients so that filtering on the front channels includes low frequency signal. then apply a 2.0 -> 2.1 filter that directs lf output to the sub (of course given that the selected output is one with a subwoofer channel). this way the subwoofer gets integrated into the filter chain without having to deal with true multi channel yet.

4) think hard about how to do proper multi channel filtering. maybe by implementing a multi-channel equalizer as first step, keep lv2 effects as 2 channel only, and define a way to make new multi channel filters. Maybe there is a standard already for multi channel plugins?

i think this would give the fastest path to enabling a useable multi-channel easyeffects. then let it evolve from there.