dimtpap / obs-pipewire-audio-capture

🔊 Audio device and application capture for OBS Studio using PipeWire
https://obsproject.com/forum/resources/pipewire-audio-capture.1458/
GNU General Public License v2.0
298 stars 9 forks source link

Virtual duplex devices are not detected #38

Closed RoarkGit closed 8 months ago

RoarkGit commented 8 months ago

I use Audio/Duplex devices for routing a bunch of inputs (e.g. microphone -> REAPER -> Duplex In; Duplex Out -> Discord), described here. These are not currently detected by this plugin.

I suspect the change would just be adding another condition to this bit of code: || strcmp(media_class, "Audio/Duplex") == 0

dimtpap commented 8 months ago

Should Duplex devices be shown both in the Input and Output capture sources?

RoarkGit commented 8 months ago

I think output is all that's needed. Consider these two duplex devices I have:

"Voice" Microphone Input -> REAPER In -> Reaper Out -> Voice In, then Voice Out actually produces the sound

"Discord" Discord Application Out -> Discord In, then Discord Out actually produces the sound

In all cases it's still the "output" end that is producing the sound to be captured. It wouldn't make sense to have OBS be feeding sound to the "input" side of things.

RoarkGit commented 8 months ago

Hmm, this doesn't seem to work as expected. I did this change locally as well last night to see, but wasn't sure if I did something wrong. When adding the device, OBS reports no output sound. If I add the same source as output via PulseAudio (pipewire-pulseaudio) it does seem to work, though.

dimtpap commented 8 months ago

What's the configuration for your virtual devices?

RoarkGit commented 8 months ago

I'm trying with two different devices and neither seems to work:

pipewire.conf

# This is a loopback device, I have "Desktop" set as my default audio output.
# It plays back through my physical audio interface.
context.modules = [
    {   name = libpipewire-module-loopback
        args = {
            node.description "Desktop Loopback"
            audio.position = "[ FL FR ]"
            capture.props = {
                media.class = "Audio/Sink"
                node.name = "stream.desktop.in"
                node.description "Desktop"
            }
            playback.props = {
                node.name = "stream.desktop.out"
                node.target = "alsa_output.usb-Schiit_Audio_Schiit_Unison_Universal_Dac-00.analog-stereo"
            }
        }
    }
}

# This is the Voice duplex device.
context.objects = [
    {   factory = adapter
        args = {
            factory.name      = support.null-audio-sink
            node.name         = "stream.voice"
            node.description  = "Voice"
            media.class       = "Audio/Duplex"
            audio.position    = "MONO"
        }
    }
]

The first device is set up like this (shown via qpwgraph with one application feeding output into it): image

The second device is set up like this (shown via qpwgraph): image

dimtpap commented 8 months ago

Try adding audio.channels = (number of audio channels) in playback.props

RoarkGit commented 8 months ago

No luck, and I do actually notice some strange behavior where the device keeps changing itself back to "Default."

image

This happens whenever I set the device to something else (in my case, "Desktop").

I can set it to different physical interfaces and it works fine, but any of the virtuals just get dropped and set to whatever the last physical interface was.

It's worth pointing out that no log messages get emitted when any of this happens. If I change between physical devices then I see output, but setting it to virtual devices doesn't do anything.

dimtpap commented 8 months ago

I got it to work after adding audio.channels = "1" in the args of the Voice duplex device and audio.channels = "2" in capture.props of the Desktop lookpback

RoarkGit commented 8 months ago

Interesting! That does appear to have done the trick. I've had this config going forever so haven't messed with it in awhile, I'll go read up on stuff again and see if there is something new / something I've missed that would have made this more obvious! Thanks for the help / quick fix.