diff --git a/.config/pipewire/client-rt.conf b/.config/pipewire/client-rt.conf new file mode 100644 index 0000000..c551fee --- /dev/null +++ b/.config/pipewire/client-rt.conf @@ -0,0 +1,136 @@ +# Real-time Client config file for PipeWire version "1.2.7" # +# +# Copy and edit this file in /etc/pipewire for system-wide changes +# or in ~/.config/pipewire for local changes. +# +# It is also possible to place a file with an updated section in +# /etc/pipewire/client-rt.conf.d/ for system-wide changes or in +# ~/.config/pipewire/client-rt.conf.d/ for local changes. +# + +context.properties = { + ## Configure properties in the system. + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + log.level = 0 + + #default.clock.quantum-limit = 8192 +} + +context.spa-libs = { + # = + # + # Used to find spa factory names. It maps an spa factory name + # regular expression to a library name that should contain + # that factory. + # + audio.convert.* = audioconvert/libspa-audioconvert + support.* = support/libspa-support +} + +context.modules = [ + #{ name = + # ( args = { = ... } ) + # ( flags = [ ( ifexists ) ( nofail ) ] ) + # ( condition = [ { = ... } ... ] ) + #} + # + # Loads a module with the given parameters. + # If ifexists is given, the module is ignored when it is not found. + # If nofail is given, module initialization failures are ignored. + # + # Uses realtime scheduling to boost the audio thread priorities + { name = libpipewire-module-rt + args = { + #rt.prio = 83 + #rt.time.soft = -1 + #rt.time.hard = -1 + } + flags = [ ifexists nofail ] + } + + # The native communication protocol. + { name = libpipewire-module-protocol-native } + + # Allows creating nodes that run in the context of the + # client. Is used by all clients that want to provide + # data to PipeWire. + { name = libpipewire-module-client-node } + + # Allows creating devices that run in the context of the + # client. Is used by the session manager. + { name = libpipewire-module-client-device } + + # Makes a factory for wrapping nodes in an adapter with a + # converter and resampler. + { name = libpipewire-module-adapter } + + # Allows applications to create metadata objects. It creates + # a factory for Metadata objects. + { name = libpipewire-module-metadata } + + # Provides factories to make session manager objects. + { name = libpipewire-module-session-manager } +] + +filter.properties = { + #node.latency = 1024/48000 +} + +stream.properties = { + #node.latency = 1024/48000 + #node.autoconnect = true + #resample.quality = 4 + #channelmix.normalize = false + #channelmix.mix-lfe = true + #channelmix.upmix = true + #channelmix.upmix-method = psd # none, simple + #channelmix.lfe-cutoff = 150 + #channelmix.fc-cutoff = 12000 + #channelmix.rear-delay = 12.0 + #channelmix.stereo-widen = 0.0 + #channelmix.hilbert-taps = 0 + #dither.noise = 0 +} + +stream.rules = [ + { matches = [ + { + # all keys must match the value. ! negates. ~ starts regex. + #application.name = "pw-cat" + #node.name = "~Google Chrome$" + } + ] + actions = { + update-props = { + #node.latency = 512/48000 + } + } + } +] + +alsa.properties = { + #alsa.deny = false + # ALSA params take a single value, an array [] of values + # or a range { min=.. max=... } + #alsa.access = [ MMAP_INTERLEAVED MMAP_NONINTERLEAVED RW_INTERLEAVED RW_NONINTERLEAVED ] + #alsa.format = [ FLOAT S32 S24 S24_3 S16 U8 ] + #alsa.rate = { min=1 max=384000 } # or [ 44100 48000 .. ] + #alsa.channels = { min=1 max=64 } # or [ 2 4 6 .. ] + #alsa.period-bytes = { min=128 max=2097152 } # or [ 128 256 1024 .. ] + #alsa.buffer-bytes = { min=256 max=4194304 } # or [ 256 512 4096 .. ] + + #alsa.volume-method = cubic # linear, cubic +} + +# client specific properties +alsa.rules = [ + { matches = [ { application.process.binary = "resolve" } ] + actions = { + update-props = { + alsa.buffer-bytes = 131072 + } + } + } +] diff --git a/.config/pipewire/client.conf b/.config/pipewire/client.conf new file mode 100644 index 0000000..743f378 --- /dev/null +++ b/.config/pipewire/client.conf @@ -0,0 +1,86 @@ +# Client config file for PipeWire version "1.2.7" # +# +# Copy and edit this file in /etc/pipewire for system-wide changes +# or in ~/.config/pipewire for local changes. +# +# It is also possible to place a file with an updated section in +# /etc/pipewire/client.conf.d/ for system-wide changes or in +# ~/.config/pipewire/client.conf.d/ for local changes. +# + +context.properties = { + ## Configure properties in the system. + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + log.level = 0 + + #default.clock.quantum-limit = 8192 +} + +context.spa-libs = { + # = + # + # Used to find spa factory names. It maps an spa factory name + # regular expression to a library name that should contain + # that factory. + # + audio.convert.* = audioconvert/libspa-audioconvert + support.* = support/libspa-support +} + +context.modules = [ + #{ name = + # ( args = { = ... } ) + # ( flags = [ ( ifexists ) ( nofail ) ] ) + # ( condition = [ { = ... } ... ] ) + #} + # + # Loads a module with the given parameters. + # If ifexists is given, the module is ignored when it is not found. + # If nofail is given, module initialization failures are ignored. + # + + # The native communication protocol. + { name = libpipewire-module-protocol-native } + + # Allows creating nodes that run in the context of the + # client. Is used by all clients that want to provide + # data to PipeWire. + { name = libpipewire-module-client-node } + + # Allows creating devices that run in the context of the + # client. Is used by the session manager. + { name = libpipewire-module-client-device } + + # Makes a factory for wrapping nodes in an adapter with a + # converter and resampler. + { name = libpipewire-module-adapter } + + # Allows applications to create metadata objects. It creates + # a factory for Metadata objects. + { name = libpipewire-module-metadata } + + # Provides factories to make session manager objects. + { name = libpipewire-module-session-manager } +] + +filter.properties = { + #node.latency = 1024/48000 +} + +stream.properties = { + #node.latency = 1024/48000 + #node.autoconnect = true + #resample.quality = 4 + #channelmix.normalize = false + #channelmix.mix-lfe = true + #channelmix.upmix = true + #channelmix.upmix-method = psd # none, simple + #channelmix.lfe-cutoff = 150 + #channelmix.fc-cutoff = 12000 + #channelmix.rear-delay = 12.0 + #channelmix.stereo-widen = 0.0 + #channelmix.hilbert-taps = 0 + #dither.noise = 0 +} diff --git a/.config/pipewire/filter-chain.conf b/.config/pipewire/filter-chain.conf new file mode 100644 index 0000000..f48d641 --- /dev/null +++ b/.config/pipewire/filter-chain.conf @@ -0,0 +1,63 @@ +# Filter-chain config file for PipeWire version "1.2.7" # +# +# This is a base config file for running filters. +# +# Place filter fragments in /etc/pipewire/filter-chain.conf.d/ +# for system-wide changes or in ~/.config/pipewire/filter-chain.conf.d/ +# for local changes. +# +# Run the filters with pipewire -c filter-chain.conf +# + +context.properties = { + ## Configure properties in the system. + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + log.level = 0 +} + +context.spa-libs = { + # = + # + # Used to find spa factory names. It maps an spa factory name + # regular expression to a library name that should contain + # that factory. + # + audio.convert.* = audioconvert/libspa-audioconvert + support.* = support/libspa-support +} + +context.modules = [ + #{ name = + # ( args = { = ... } ) + # ( flags = [ ( ifexists ) ( nofail ) ] ) + # ( condition = [ { = ... } ... ] ) + #} + # + # Loads a module with the given parameters. + # If ifexists is given, the module is ignored when it is not found. + # If nofail is given, module initialization failures are ignored. + # + # Uses realtime scheduling to boost the audio thread priorities + { name = libpipewire-module-rt + args = { + #rt.prio = 83 + #rt.time.soft = -1 + #rt.time.hard = -1 + } + flags = [ ifexists nofail ] + } + + # The native communication protocol. + { name = libpipewire-module-protocol-native } + + # Allows creating nodes that run in the context of the + # client. Is used by all clients that want to provide + # data to PipeWire. + { name = libpipewire-module-client-node } + + # Makes a factory for wrapping nodes in an adapter with a + # converter and resampler. + { name = libpipewire-module-adapter } +] diff --git a/.config/pipewire/jack.conf b/.config/pipewire/jack.conf new file mode 100644 index 0000000..194baf5 --- /dev/null +++ b/.config/pipewire/jack.conf @@ -0,0 +1,139 @@ +# JACK client config file for PipeWire version "1.2.7" # +# +# Copy and edit this file in /etc/pipewire for system-wide changes +# or in ~/.config/pipewire for local changes. +# +# It is also possible to place a file with an updated section in +# /etc/pipewire/jack.conf.d/ for system-wide changes or in +# ~/.config/pipewire/jack.conf.d/ for local changes. +# + +context.properties = { + ## Configure properties in the system. + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + log.level = 0 + + #default.clock.quantum-limit = 8192 +} + +context.spa-libs = { + # = + # + # Used to find spa factory names. It maps an spa factory name + # regular expression to a library name that should contain + # that factory. + # + support.* = support/libspa-support +} + +context.modules = [ + #{ name = + # ( args = { = ... } ) + # ( flags = [ ( ifexists ) ( nofail ) ] ) + # ( condition = [ { = ... } ... ] ) + #} + # + # Loads a module with the given parameters. + # If ifexists is given, the module is ignored when it is not found. + # If nofail is given, module initialization failures are ignored. + # + # + # Boost the data thread priority. + { name = libpipewire-module-rt + args = { + #rt.prio = 83 + #rt.time.soft = -1 + #rt.time.hard = -1 + } + flags = [ ifexists nofail ] + } + + # The native communication protocol. + { name = libpipewire-module-protocol-native } + + # Allows creating nodes that run in the context of the + # client. Is used by all clients that want to provide + # data to PipeWire. + { name = libpipewire-module-client-node } + + # Allows applications to create metadata objects. It creates + # a factory for Metadata objects. + { name = libpipewire-module-metadata } +] + +# global properties for all jack clients +jack.properties = { + #node.latency = 1024/48000 + #node.rate = 1/48000 + #node.quantum = 1024/48000 + #node.lock-quantum = true + #node.force-quantum = 0 + #jack.show-monitor = true + #jack.merge-monitor = true + #jack.show-midi = true + #jack.short-name = false + #jack.filter-name = false + #jack.filter-char = " " + # + # allow: Don't restrict self connect requests + # fail-external: Fail self connect requests to external ports only + # ignore-external: Ignore self connect requests to external ports only + # fail-all: Fail all self connect requests + # ignore-all: Ignore all self connect requests + #jack.self-connect-mode = allow + # + # allow: Allow connect request of other ports + # fail: Fail connect requests of other ports + # ignore: Ignore connect requests of other ports + #jack.other-connect-mode = allow + #jack.locked-process = true + #jack.default-as-system = false + #jack.fix-midi-events = true + #jack.global-buffer-size = false + #jack.max-client-ports = 768 + #jack.fill-aliases = false + #jack.writable-input = true +} + +# client specific properties +jack.rules = [ + { matches = [ + { + # all keys must match the value. ! negates. ~ starts regex. + #client.name = "Carla" + #application.process.binary = "jack_simple_client" + #application.name = "~jack_simple_client.*" + } + ] + actions = { + update-props = { + #node.latency = 512/48000 + } + } + } + { matches = [ { application.process.binary = "jack_bufsize" } ] + actions = { + update-props = { + jack.global-buffer-size = true # quantum set globally using metadata + } + } + } + { matches = [ { application.process.binary = "qsynth" } ] + actions = { + update-props = { + node.always-process = false # makes qsynth idle + node.pause-on-idle = false # makes audio fade out when idle + node.passive = out # makes the sink and qsynth suspend + } + } + } + { matches = [ { client.name = "Mixxx" } ] + actions = { + update-props = { + jack.merge-monitor = false + } + } + } +] diff --git a/.config/pipewire/minimal.conf b/.config/pipewire/minimal.conf new file mode 100644 index 0000000..251b225 --- /dev/null +++ b/.config/pipewire/minimal.conf @@ -0,0 +1,476 @@ +# Simple daemon config file for PipeWire version "1.2.7" # +# +# Copy and edit this file in /etc/pipewire for system-wide changes +# or in ~/.config/pipewire for local changes. +# +# It is also possible to place a file with an updated section in +# /etc/pipewire/minimal.conf.d/ for system-wide changes or in +# ~/.config/pipewire/minimal.conf.d/ for local changes. +# + +context.properties = { + ## Configure properties in the system. + #library.name.system = support/libspa-support + #context.data-loop.library.name.system = support/libspa-support + #support.dbus = true + #link.max-buffers = 64 + link.max-buffers = 16 # version < 3 clients can't handle more + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + #clock.power-of-two-quantum = true + #log.level = 2 + #cpu.zero.denormals = false + + core.daemon = true # listening for socket connections + core.name = pipewire-0 # core name and socket name + + ## Properties for the DSP configuration. + #default.clock.rate = 48000 + #default.clock.allowed-rates = [ 48000 ] + #default.clock.quantum = 1024 + #default.clock.min-quantum = 32 + #default.clock.max-quantum = 2048 + #default.clock.quantum-limit = 8192 + #default.clock.quantum-floor = 4 + #default.video.width = 640 + #default.video.height = 480 + #default.video.rate.num = 25 + #default.video.rate.denom = 1 + # + settings.check-quantum = true + settings.check-rate = true + + # This config can use udev or hardcoded ALSA devices. Make sure to + # change the alsa device below when disabling udev + minimal.use-udev = true + + # Load the pulseaudio emulation daemon + minimal.use-pulse = true +} + +context.properties.rules = [ + { matches = [ { cpu.vm.name = !null } ] + actions = { + update-props = { + # These overrides are only applied when running in a vm. + default.clock.min-quantum = 1024 + } + } + } +] + +context.spa-libs = { + # = + # + # Used to find spa factory names. It maps an spa factory name + # regular expression to a library name that should contain + # that factory. + # + audio.convert.* = audioconvert/libspa-audioconvert + audio.adapt = audioconvert/libspa-audioconvert + api.alsa.* = alsa/libspa-alsa + support.* = support/libspa-support +} + +context.modules = [ + #{ name = + # ( args = { = ... } ) + # ( flags = [ ( ifexists ) ( nofail ) ] ) + # ( condition = [ { = ... } ... ] ) + #} + # + # Loads a module with the given parameters. + # If ifexists is given, the module is ignored when it is not found. + # If nofail is given, module initialization failures are ignored. + # + + # Uses realtime scheduling to boost the audio thread priorities. This uses + # RTKit if the user doesn't have permission to use regular realtime + # scheduling. + { name = libpipewire-module-rt + args = { + nice.level = -11 + rt.prio = 88 + #rt.time.soft = -1 + #rt.time.hard = -1 + } + flags = [ ifexists nofail ] + } + + # The native communication protocol. + { name = libpipewire-module-protocol-native } + + # The profile module. Allows application to access profiler + # and performance data. It provides an interface that is used + # by pw-top and pw-profiler. + { name = libpipewire-module-profiler } + + # Allows applications to create metadata objects. It creates + # a factory for Metadata objects. + { name = libpipewire-module-metadata } + + # Creates a factory for making nodes that run in the + # context of the PipeWire server. + { name = libpipewire-module-spa-node-factory } + + { name = libpipewire-module-spa-device-factory } + + # Allows creating nodes that run in the context of the + # client. Is used by all clients that want to provide + # data to PipeWire. + { name = libpipewire-module-client-node } + + # The access module can perform access checks and block + # new clients. + { name = libpipewire-module-access + args = { + # access.allowed to list an array of paths of allowed + # apps. + #access.allowed = [ + # /usr/bin/pipewire-media-session + #] + + # An array of rejected paths. + #access.rejected = [ ] + + # An array of paths with restricted access. + #access.restricted = [ ] + + # Anything not in the above lists gets assigned the + # access.force permission. + #access.force = flatpak + } + } + + # Makes a factory for wrapping nodes in an adapter with a + # converter and resampler. + { name = libpipewire-module-adapter } + + # Makes a factory for creating links between ports. + { name = libpipewire-module-link-factory } + + { name = libpipewire-module-protocol-pulse + condition = [ { minimal.use-pulse = true } ] + } +] + +pulse.properties = { + # the addresses this server listens on + server.address = [ + "unix:native" + ] +} + +stream.properties = { + adapter.auto-port-config = { mode = dsp } +} + +context.objects = [ + #{ factory = + # ( args = { = ... } ) + # ( flags = [ ( nofail ) ] ) + # ( condition = [ { = ... } ... ] ) + #} + # + # Creates an object from a PipeWire factory with the given parameters. + # If nofail is given, errors are ignored (and no object is created). + # + #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } } + #{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] } + #{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } } + #{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } } + #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test node.description = audiotestsrc } } + #{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } } + + # Make a default metadata store + { factory = metadata + args = { + metadata.name = default + # metadata.values = [ + # { key = default.audio.sink value = { name = somesink } } + # { key = default.audio.source value = { name = somesource } } + # ] + } + } + + # A default dummy driver. This handles nodes marked with the "node.always-process" + # property when no other driver is currently active. JACK clients need this. + { factory = spa-node-factory + args = { + factory.name = support.node.driver + node.name = Dummy-Driver + node.group = pipewire.dummy + priority.driver = 20000 + } + } + { factory = spa-node-factory + args = { + factory.name = support.node.driver + node.name = Freewheel-Driver + priority.driver = 19000 + node.group = pipewire.freewheel + node.freewheel = true + #freewheel.wait = 10 + } + } + + # This creates a ALSA udev device that will enumerate all + # ALSA devices. Because it is using ACP and has the auto-profile + # property set, this will enable a profile and create associated + # nodes, which will be automatically configured to their best + # configuration with the auto-port-config settings. + # Extra node and device params can be given with node.param and + # device.param prefixes. + { factory = spa-device-factory + args = { + factory.name = api.alsa.enum.udev + alsa.use-acp = true + device.object.properties = { + api.acp.auto-profile = true + api.acp.auto-port = true + device.object.properties = { + node.adapter = audio.adapt + resample.disable = false + adapter.auto-port-config = { + mode = dsp + monitor = false + control = false + position = preserve # unknown, aux + } + #node.param.Props = { + # channelVolumes = [ 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.6 ] + #} + } + #device.param.Profile = { + # #idx = 0 + # name = pro-audio + #} + } + } + condition = [ { minimal.use-udev = true } ] + } + + # This creates a single PCM source device for the given + # alsa device path hw:0. You can change source to sink + # to make a sink in the same way. + { factory = adapter + args = { + factory.name = api.alsa.pcm.source + node.name = "system" + node.description = "system" + media.class = "Audio/Source" + api.alsa.path = "hw:4" + #api.alsa.period-size = 0 + #api.alsa.period-num = 0 + #api.alsa.headroom = 0 + #api.alsa.start-delay = 0 + #api.alsa.disable-mmap = false + #api.alsa.disable-batch = false + #api.alsa.use-chmap = false + #api.alsa.multirate = true + #latency.internal.rate = 0 + #latency.internal.ns = 0 + #clock.name = api.alsa.0 + node.suspend-on-idle = true + #audio.format = "S32" + #audio.rate = 48000 + #audio.allowed-rates = [ ] + #audio.channels = 4 + #audio.position = [ FL FR RL RR ] + #resample.quality = 4 + resample.disable = true + #monitor.channel-volumes = false + #channelmix.normalize = false + #channelmix.mix-lfe = true + #channelmix.upmix = true + #channelmix.upmix-method = psd # none, simple + #channelmix.lfe-cutoff = 150 + #channelmix.fc-cutoff = 12000 + #channelmix.rear-delay = 12.0 + #channelmix.stereo-widen = 0.0 + #channelmix.hilbert-taps = 0 + #channelmix.disable = false + #dither.noise = 0 + #node.param.Props = { + # params = [ + # audio.channels 6 + # ] + #} + adapter.auto-port-config = { + mode = dsp + monitor = false + control = false + position = unknown # aux, preserve + } + #node.param.PortConfig = { + # direction = Output + # mode = dsp + # format = { + # mediaType = audio + # mediaSubtype = raw + # format = F32 + # rate = 48000 + # channels = 4 + # position = [ FL FR RL RR ] + # } + #} + #node.param.Props = { + # channelVolumes = [ 0.5 0.4 0.3 0.5 ] + #} + } + condition = [ { minimal.use-udev = false } ] + } + { factory = adapter + args = { + factory.name = api.alsa.pcm.sink + node.name = "system" + node.description = "system" + media.class = "Audio/Sink" + api.alsa.path = "hw:4" + #api.alsa.period-size = 0 + #api.alsa.period-num = 0 + #api.alsa.headroom = 0 + #api.alsa.start-delay = 0 + #api.alsa.disable-mmap = false + #api.alsa.disable-batch = false + #api.alsa.use-chmap = false + #api.alsa.multirate = true + #latency.internal.rate = 0 + #latency.internal.ns = 0 + #clock.name = api.alsa.0 + node.suspend-on-idle = true + #audio.format = "S32" + #audio.rate = 48000 + #audio.allowed-rates = [ ] + #audio.channels = 2 + #audio.position = "FL,FR" + #resample.quality = 4 + resample.disable = true + #channelmix.normalize = false + #channelmix.mix-lfe = true + #channelmix.upmix = true + #channelmix.upmix-method = psd # none, simple + #channelmix.lfe-cutoff = 150 + #channelmix.fc-cutoff = 12000 + #channelmix.rear-delay = 12.0 + #channelmix.stereo-widen = 0.0 + #channelmix.hilbert-taps = 0 + #channelmix.disable = false + #dither.noise = 0 + #node.param.Props = { + # params = [ + # audio.format S16 + # ] + #} + adapter.auto-port-config = { + mode = dsp + monitor = false + control = false + position = unknown # aux, preserve + } + #node.param.PortConfig = { + # direction = Input + # mode = dsp + # monitor = true + # format = { + # mediaType = audio + # mediaSubtype = raw + # format = F32 + # rate = 48000 + # channels = 4 + # } + #} + #node.param.Props = { + # channelVolumes = [ 0.5 0.4 0.3 0.5 ] + #} + } + condition = [ { minimal.use-udev = false } ] + } + # This creates a new Source node. It will have input ports + # that you can link, to provide audio for this source. + #{ factory = adapter + # args = { + # factory.name = support.null-audio-sink + # node.name = "my-mic" + # node.description = "Microphone" + # media.class = "Audio/Source/Virtual" + # audio.position = "FL,FR" + # monitor.passthrough = true + # adapter.auto-port-config = { + # mode = dsp + # monitor = true + # position = preserve # unknown, aux, preserve + # } + # } + #} + # This creates a new link between the source and the virtual + # source ports. + #{ factory = link-factory + # args = { + # link.output.node = system + # link.output.port = capture_1 + # link.input.node = my-mic + # link.input.port = input_FL + # } + #} + #{ factory = link-factory + # args = { + # link.output.node = system + # link.output.port = capture_2 + # link.input.node = my-mic + # link.input.port = input_FR + # } + #} +] + +context.exec = [ + #{ path = + # ( args = "" | [ ... ] ) + # ( condition = [ { = ... } ... ] ) + #} + # + # Execute the given program with arguments. + # + # You can optionally start the pulseaudio-server here as well + # but it is better to start it as a systemd service. + # It can be interesting to start another daemon here that listens + # on another address with the -a option (eg. -a tcp:4713). + # + ##{ path = "/usr/bin/pipewire" args = "-c pipewire-pulse.conf" } +] + +node.rules = [ + { matches = [ + { + # all keys must match the value. ! negates. ~ starts regex. + #alsa.card_name = "ICUSBAUDIO7D" + #api.alsa.pcm.stream = "playback" + } + ] + actions = { + update-props = { + #node.name = "alsa_playback.ICUSBAUDIO7D" + } + } + } +] +device.rules = [ + { matches = [ + { + #alsa.card_name = "ICUSBAUDIO7D" + } + ] + actions = { + update-props = { + #device.name = "alsa_card.ICUSBAUDIO7D" + #api.acp.auto-profile = false + #api.acp.auto-port = false + #device.param.Profile = { + # #idx = 0 + # name = off + #} + } + } + } +] diff --git a/.config/pipewire/pipewire-aes67.conf b/.config/pipewire/pipewire-aes67.conf new file mode 100644 index 0000000..5993797 --- /dev/null +++ b/.config/pipewire/pipewire-aes67.conf @@ -0,0 +1,153 @@ +# AES67 config file for PipeWire version "1.2.7" # +# +# Copy and edit this file in /etc/pipewire for system-wide changes +# or in ~/.config/pipewire for local changes. +# +# It is also possible to place a file with an updated section in +# /etc/pipewire/pipewire-aes67.conf.d/ for system-wide changes or in +# ~/.config/pipewire/pipewire-aes67.conf.d/ for local changes. +# + +context.properties = { + ## Configure properties in the system. + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + #log.level = 2 + + #default.clock.quantum-limit = 8192 +} + +context.spa-libs = { + support.* = support/libspa-support +} + +context.objects = [ + # An example clock reading from /dev/ptp0. You can also specify the network interface name, + # pipewire will query the interface for the current active PHC index. Another option is to + # sync the ptp clock to CLOCK_TAI and then set clock.id = tai, keep in mind that tai may + # also be synced by a NTP client. + # The precedence is: device, interface, id + { factory = spa-node-factory + args = { + factory.name = support.node.driver + node.name = PTP0-Driver + node.group = pipewire.ptp0 + # This driver should only be used for network nodes marked with group + priority.driver = 100000 + clock.name = "clock.system.ptp0" + ### Please select the PTP hardware clock here + # Interface name is the preferred method of specifying the PHC + clock.interface = "eth0" + #clock.device = "/dev/ptp0" + #clock.id = tai + # Lower this in case of periodic out-of-sync + resync.ms = 1.5 + object.export = true + } + } +] + +context.modules = [ + { name = libpipewire-module-rt + args = { + nice.level = -11 + #rt.prio = 83 + #rt.time.soft = -1 + #rt.time.hard = -1 + } + flags = [ ifexists nofail ] + } + { name = libpipewire-module-protocol-native } + { name = libpipewire-module-client-node } + { name = libpipewire-module-spa-node-factory } + { name = libpipewire-module-adapter } + { name = libpipewire-module-rtp-sap + args = { + ### Please select the interface here + local.ifname = eth0 + sap.ip = 239.255.255.255 + sap.port = 9875 + net.ttl = 32 + net.loop = false + # If you use another PTPv2 daemon supporting management + # messages over a UNIX socket, specify its path here + ptp.management-socket = "/var/run/ptp4lro" + + stream.rules = [ + { + matches = [ + { + rtp.session = "~.*" + } + ] + actions = { + create-stream = { + node.virtual = false + media.class = "Audio/Source" + device.api = aes67 + # You can adjust the latency buffering here. Use integer values only + sess.latency.msec = 3 + node.group = pipewire.ptp0 + } + } + }, + { + matches = [ + { + sess.sap.announce = true + } + ] + actions = { + announce-stream = {} + } + } + ] + } + }, + { name = libpipewire-module-rtp-sink + args = { + ### Please select the interface here + local.ifname = eth0 + ### If you want to create multiple output streams, please copy the whole + ### module-rtp-sink block, but change this multicast IP to another unused + ### one keeping 239.69.x.x range unless you know you need another one + destination.ip = 239.69.150.243 + destination.port = 5004 + net.mtu = 1280 + net.ttl = 32 + net.loop = false + # These should typically be equal + # You can customize packet length, but 1 ms should work for every device + # Consult receiver documentation to ensure it supports the value you set + sess.min-ptime = 1 + sess.max-ptime = 1 + ### Please change this, especially if you create multiple sinks + sess.name = "PipeWire RTP stream" + sess.media = "audio" + # This property is used if you aren't using ptp4l 4 + sess.ts-refclk = "ptp=traceable" + sess.ts-offset = 0 + # You can adjust the latency buffering here. Use integer values only + sess.latency.msec = 3 + audio.format = "S24BE" + audio.rate = 48000 + audio.channels = 2 + # These channel names will be visible both to applications and AES67 receivers + node.channel-names = ["CH1", "CH2"] + + stream.props = { + ### Please change the sink name, this is necessary when you create multiple sinks + node.name = "rtp-sink" + media.class = "Audio/Sink" + node.virtual = false + device.api = aes67 + sess.sap.announce = true + node.always-process = true + node.group = pipewire.ptp0 + rtp.ntp = 0 + rtp.fetch-ts-refclk = true + } + } + }, +] diff --git a/.config/pipewire/pipewire-avb.conf b/.config/pipewire/pipewire-avb.conf new file mode 100644 index 0000000..8537732 --- /dev/null +++ b/.config/pipewire/pipewire-avb.conf @@ -0,0 +1,80 @@ +# PulseAudio config file for PipeWire version "1.2.7" # +# +# Copy and edit this file in /etc/pipewire for system-wide changes +# or in ~/.config/pipewire for local changes. +# +# It is also possible to place a file with an updated section in +# /etc/pipewire/pipewire-pulse.conf.d/ for system-wide changes or in +# ~/.config/pipewire/pipewire-pulse.conf.d/ for local changes. +# + +context.properties = { + ## Configure properties in the system. + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + #log.level = 2 + + #default.clock.quantum-limit = 8192 +} + +context.spa-libs = { + audio.convert.* = audioconvert/libspa-audioconvert + support.* = support/libspa-support +} + +context.modules = [ + { name = libpipewire-module-rt + args = { + nice.level = -11 + #rt.prio = 83 + #rt.time.soft = -1 + #rt.time.hard = -1 + } + flags = [ ifexists nofail ] + } + { name = libpipewire-module-protocol-native } + { name = libpipewire-module-client-node } + { name = libpipewire-module-adapter } + { name = libpipewire-module-avb + args = { + # contents of avb.properties can also be placed here + # to have config per server. + } + } +] + +# Extra modules can be loaded here. Setup in default.pa can be moved here +context.exec = [ + #{ path = "pactl" args = "load-module module-always-sink" } +] + +stream.properties = { + #node.latency = 1024/48000 + #node.autoconnect = true + #resample.quality = 4 + #channelmix.normalize = false + #channelmix.mix-lfe = true + #channelmix.upmix = true + #channelmix.lfe-cutoff = 120 + #channelmix.fc-cutoff = 6000 + #channelmix.rear-delay = 12.0 + #channelmix.stereo-widen = 0.1 + #channelmix.hilbert-taps = 0 +} + +avb.properties = { + # the addresses this server listens on + #ifname = "eth0.2" + ifname = "enp3s0" +} + +avb.properties.rules = [ + { matches = [ { cpu.vm.name = !null } ] + actions = { + update-props = { + # These overrides are only applied when running in a vm. + } + } + } +] diff --git a/.config/pipewire/pipewire-pulse.conf b/.config/pipewire/pipewire-pulse.conf new file mode 100644 index 0000000..33fa495 --- /dev/null +++ b/.config/pipewire/pipewire-pulse.conf @@ -0,0 +1,180 @@ +# PulseAudio config file for PipeWire version "1.2.7" # +# +# Copy and edit this file in /etc/pipewire for system-wide changes +# or in ~/.config/pipewire for local changes. +# +# It is also possible to place a file with an updated section in +# /etc/pipewire/pipewire-pulse.conf.d/ for system-wide changes or in +# ~/.config/pipewire/pipewire-pulse.conf.d/ for local changes. +# + +context.properties = { + ## Configure properties in the system. + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + #log.level = 2 + + #default.clock.quantum-limit = 8192 +} + +context.spa-libs = { + audio.convert.* = audioconvert/libspa-audioconvert + support.* = support/libspa-support +} + +context.modules = [ + { name = libpipewire-module-rt + args = { + nice.level = -11 + #rt.prio = 83 + #rt.time.soft = -1 + #rt.time.hard = -1 + #uclamp.min = 0 + #uclamp.max = 1024 + } + flags = [ ifexists nofail ] + } + { name = libpipewire-module-protocol-native } + { name = libpipewire-module-client-node } + { name = libpipewire-module-adapter } + { name = libpipewire-module-metadata } + + { name = libpipewire-module-protocol-pulse + args = { + # contents of pulse.properties can also be placed here + # to have config per server. + } + } +] + +# Extra scripts can be started here. Setup in default.pa can be moved in +# a script or in pulse.cmd below +context.exec = [ + #{ path = "pactl" args = "load-module module-always-sink" } + #{ path = "pactl" args = "upload-sample my-sample.wav my-sample" } + #{ path = "/usr/bin/sh" args = "~/.config/pipewire/default.pw" } +] + +# Extra commands can be executed here. +# load-module : loads a module with args and flags +# args = " " +# ( flags = [ nofail ] ) +pulse.cmd = [ + { cmd = "load-module" args = "module-always-sink" flags = [ ] } + { cmd = "load-module" args = "module-device-manager" flags = [ ] } + { cmd = "load-module" args = "module-device-restore" flags = [ ] } + { cmd = "load-module" args = "module-stream-restore" flags = [ ] } + #{ cmd = "load-module" args = "module-switch-on-connect" } + #{ cmd = "load-module" args = "module-gsettings" flags = [ nofail ] } +] + +stream.properties = { + #node.latency = 1024/48000 + #node.autoconnect = true + #resample.quality = 4 + #channelmix.normalize = false + #channelmix.mix-lfe = true + #channelmix.upmix = true + #channelmix.upmix-method = psd # none, simple + #channelmix.lfe-cutoff = 150 + #channelmix.fc-cutoff = 12000 + #channelmix.rear-delay = 12.0 + #channelmix.stereo-widen = 0.0 + #channelmix.hilbert-taps = 0 + #dither.noise = 0 +} + +pulse.properties = { + # the addresses this server listens on + server.address = [ + "unix:native" + #"unix:/tmp/something" # absolute paths may be used + #"tcp:4713" # IPv4 and IPv6 on all addresses + #"tcp:[::]:9999" # IPv6 on all addresses + #"tcp:127.0.0.1:8888" # IPv4 on a single address + # + #{ address = "tcp:4713" # address + # max-clients = 64 # maximum number of clients + # listen-backlog = 32 # backlog in the server listen queue + # client.access = "restricted" # permissions for clients + #} + ] + #server.dbus-name = "org.pulseaudio.Server" + #pulse.allow-module-loading = true + #pulse.min.req = 128/48000 # 2.7ms + #pulse.default.req = 960/48000 # 20 milliseconds + #pulse.min.frag = 128/48000 # 2.7ms + #pulse.default.frag = 96000/48000 # 2 seconds + #pulse.default.tlength = 96000/48000 # 2 seconds + #pulse.min.quantum = 128/48000 # 2.7ms + #pulse.idle.timeout = 0 # don't pause after underruns + #pulse.default.format = F32 + #pulse.default.position = [ FL FR ] +} + +pulse.properties.rules = [ + { matches = [ { cpu.vm.name = !null } ] + actions = { + update-props = { + # These overrides are only applied when running in a vm. + pulse.min.quantum = 1024/48000 # 22ms + } + } + } +] + +# client/stream specific properties +pulse.rules = [ + { + matches = [ + { + # all keys must match the value. ! negates. ~ starts regex. + #client.name = "Firefox" + #application.process.binary = "teams" + #application.name = "~speech-dispatcher.*" + } + ] + actions = { + update-props = { + #node.latency = 512/48000 + } + # Possible quirks:" + # force-s16-info forces sink and source info as S16 format + # remove-capture-dont-move removes the capture DONT_MOVE flag + # block-source-volume blocks updates to source volume + # block-sink-volume blocks updates to sink volume + #quirks = [ ] + } + } + { + # skype does not want to use devices that don't have an S16 sample format. + matches = [ + { application.process.binary = "teams" } + { application.process.binary = "teams-insiders" } + { application.process.binary = "skypeforlinux" } + ] + actions = { quirks = [ force-s16-info ] } + } + { + # firefox marks the capture streams as don't move and then they + # can't be moved with pavucontrol or other tools. + matches = [ { application.process.binary = "firefox" } ] + actions = { quirks = [ remove-capture-dont-move ] } + } + { + # speech dispatcher asks for too small latency and then underruns. + matches = [ { application.name = "~speech-dispatcher.*" } ] + actions = { + update-props = { + pulse.min.req = 512/48000 # 10.6ms + pulse.min.quantum = 512/48000 # 10.6ms + pulse.idle.timeout = 5 # pause after 5 seconds of underrun + } + } + } + #{ + # matches = [ { application.process.binary = "Discord" } ] + # actions = { quirks = [ block-source-volume ] } + #} +] diff --git a/.config/pipewire/pipewire.conf b/.config/pipewire/pipewire.conf new file mode 100644 index 0000000..b5721cf --- /dev/null +++ b/.config/pipewire/pipewire.conf @@ -0,0 +1,344 @@ +# Daemon config file for PipeWire version "1.2.7" # +# +# Copy and edit this file in /etc/pipewire for system-wide changes +# or in ~/.config/pipewire for local changes. +# +# It is also possible to place a file with an updated section in +# /etc/pipewire/pipewire.conf.d/ for system-wide changes or in +# ~/.config/pipewire/pipewire.conf.d/ for local changes. +# + +context.properties = { + ## Configure properties in the system. + #library.name.system = support/libspa-support + #context.data-loop.library.name.system = support/libspa-support + #support.dbus = true + #link.max-buffers = 64 + link.max-buffers = 16 # version < 3 clients can't handle more + #mem.warn-mlock = false + #mem.allow-mlock = true + #mem.mlock-all = false + #clock.power-of-two-quantum = true + #log.level = 2 + #cpu.zero.denormals = false + + #loop.rt-prio = -1 # -1 = use module-rt prio, 0 disable rt + #loop.class = data.rt + #thread.affinity = [ 0 1 ] # optional array of CPUs + #context.num-data-loops = 1 # -1 = num-cpus, 0 = no data loops + # + #context.data-loops = [ + # { loop.rt-prio = -1 + # loop.class = [ data.rt audio.rt ] + # #library.name.system = support/libspa-support + # thread.name = data-loop.0 + # #thread.affinity = [ 0 1 ] # optional array of CPUs + # } + #] + + core.daemon = true # listening for socket connections + core.name = pipewire-0 # core name and socket name + + ## Properties for the DSP configuration. + #default.clock.rate = 48000 + default.clock.allowed-rates = [ 44100 48000 ] # This is not default because: https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PipeWire#setting-global-sample-rate + #default.clock.quantum = 1024 + #default.clock.min-quantum = 32 + #default.clock.max-quantum = 2048 + #default.clock.quantum-limit = 8192 + #default.clock.quantum-floor = 4 + #default.video.width = 640 + #default.video.height = 480 + #default.video.rate.num = 25 + #default.video.rate.denom = 1 + # + #settings.check-quantum = false + #settings.check-rate = false + + # keys checked below to disable module loading + module.x11.bell = true + # enables autoloading of access module, when disabled an alternative + # access module needs to be loaded. + module.access = true + # enables autoloading of module-jackdbus-detect + module.jackdbus-detect = true +} + +context.properties.rules = [ + { matches = [ { cpu.vm.name = !null } ] + actions = { + update-props = { + # These overrides are only applied when running in a vm. + default.clock.min-quantum = 1024 + } + } + } +] + +context.spa-libs = { + # = + # + # Used to find spa factory names. It maps an spa factory name + # regular expression to a library name that should contain + # that factory. + # + audio.convert.* = audioconvert/libspa-audioconvert + avb.* = avb/libspa-avb + api.alsa.* = alsa/libspa-alsa + api.v4l2.* = v4l2/libspa-v4l2 + api.libcamera.* = libcamera/libspa-libcamera + api.bluez5.* = bluez5/libspa-bluez5 + api.vulkan.* = vulkan/libspa-vulkan + api.jack.* = jack/libspa-jack + support.* = support/libspa-support + video.convert.* = videoconvert/libspa-videoconvert + #videotestsrc = videotestsrc/libspa-videotestsrc + #audiotestsrc = audiotestsrc/libspa-audiotestsrc +} + +context.modules = [ + #{ name = + # ( args = { = ... } ) + # ( flags = [ ( ifexists ) ( nofail ) ] ) + # ( condition = [ { = ... } ... ] ) + #} + # + # Loads a module with the given parameters. + # If ifexists is given, the module is ignored when it is not found. + # If nofail is given, module initialization failures are ignored. + # If condition is given, the module is loaded only when the context + # properties all match the match rules. + # + + # Uses realtime scheduling to boost the audio thread priorities. This uses + # RTKit if the user doesn't have permission to use regular realtime + # scheduling. You can also clamp utilisation values to improve scheduling + # on embedded and heterogeneous systems, e.g. Arm big.LITTLE devices. + { name = libpipewire-module-rt + args = { + nice.level = -11 + rt.prio = 88 + #rt.time.soft = -1 + #rt.time.hard = -1 + #uclamp.min = 0 + #uclamp.max = 1024 + } + flags = [ ifexists nofail ] + } + + # The native communication protocol. + { name = libpipewire-module-protocol-native + args = { + # List of server Unix sockets, and optionally permissions + #sockets = [ { name = "pipewire-0" }, { name = "pipewire-0-manager" } ] + } + } + + # The profile module. Allows application to access profiler + # and performance data. It provides an interface that is used + # by pw-top and pw-profiler. + { name = libpipewire-module-profiler } + + # Allows applications to create metadata objects. It creates + # a factory for Metadata objects. + { name = libpipewire-module-metadata } + + # Creates a factory for making devices that run in the + # context of the PipeWire server. + { name = libpipewire-module-spa-device-factory } + + # Creates a factory for making nodes that run in the + # context of the PipeWire server. + { name = libpipewire-module-spa-node-factory } + + # Allows creating nodes that run in the context of the + # client. Is used by all clients that want to provide + # data to PipeWire. + { name = libpipewire-module-client-node } + + # Allows creating devices that run in the context of the + # client. Is used by the session manager. + { name = libpipewire-module-client-device } + + # The portal module monitors the PID of the portal process + # and tags connections with the same PID as portal + # connections. + { name = libpipewire-module-portal + flags = [ ifexists nofail ] + } + + # The access module can perform access checks and block + # new clients. + { name = libpipewire-module-access + args = { + # Socket-specific access permissions + #access.socket = { pipewire-0 = "default", pipewire-0-manager = "unrestricted" } + + # Deprecated legacy mode (not socket-based), + # for now enabled by default if access.socket is not specified + #access.legacy = true + } + condition = [ { module.access = true } ] + } + + # Makes a factory for wrapping nodes in an adapter with a + # converter and resampler. + { name = libpipewire-module-adapter } + + # Makes a factory for creating links between ports. + { name = libpipewire-module-link-factory } + + # Provides factories to make session manager objects. + { name = libpipewire-module-session-manager } + + # Use libcanberra to play X11 Bell + { name = libpipewire-module-x11-bell + args = { + #sink.name = "@DEFAULT_SINK@" + #sample.name = "bell-window-system" + #x11.display = null + #x11.xauthority = null + } + flags = [ ifexists nofail ] + condition = [ { module.x11.bell = true } ] + } + { name = libpipewire-module-jackdbus-detect + args = { + #jack.library = libjack.so.0 + #jack.server = null + #jack.client-name = PipeWire + #jack.connect = true + #tunnel.mode = duplex # source|sink|duplex + source.props = { + #audio.channels = 2 + #midi.ports = 1 + #audio.position = [ FL FR ] + # extra sink properties + } + sink.props = { + #audio.channels = 2 + #midi.ports = 1 + #audio.position = [ FL FR ] + # extra sink properties + } + } + flags = [ ifexists nofail ] + condition = [ { module.jackdbus-detect = true } ] + } +] + +context.objects = [ + #{ factory = + # ( args = { = ... } ) + # ( flags = [ ( nofail ) ] ) + # ( condition = [ { = ... } ... ] ) + #} + # + # Creates an object from a PipeWire factory with the given parameters. + # If nofail is given, errors are ignored (and no object is created). + # If condition is given, the object is created only when the context properties + # all match the match rules. + # + #{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc node.description = videotestsrc "Spa:Pod:Object:Param:Props:patternType" = 1 } } + #{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] } + #{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } } + #{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } } + #{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test node.description = audiotestsrc } } + #{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } } + + # A default dummy driver. This handles nodes marked with the "node.always-process" + # property when no other driver is currently active. JACK clients need this. + { factory = spa-node-factory + args = { + factory.name = support.node.driver + node.name = Dummy-Driver + node.group = pipewire.dummy + node.sync-group = sync.dummy + priority.driver = 200000 + #clock.id = monotonic # realtime | tai | monotonic-raw | boottime + #clock.name = "clock.system.monotonic" + } + } + { factory = spa-node-factory + args = { + factory.name = support.node.driver + node.name = Freewheel-Driver + priority.driver = 190000 + node.group = pipewire.freewheel + node.sync-group = sync.dummy + node.freewheel = true + #freewheel.wait = 10 + } + } + + # This creates a new Source node. It will have input ports + # that you can link, to provide audio for this source. + #{ factory = adapter + # args = { + # factory.name = support.null-audio-sink + # node.name = "my-mic" + # node.description = "Microphone" + # media.class = "Audio/Source/Virtual" + # audio.position = "FL,FR" + # monitor.passthrough = true + # } + #} + + # This creates a single PCM source device for the given + # alsa device path hw:0. You can change source to sink + # to make a sink in the same way. + #{ factory = adapter + # args = { + # factory.name = api.alsa.pcm.source + # node.name = "alsa-source" + # node.description = "PCM Source" + # media.class = "Audio/Source" + # api.alsa.path = "hw:0" + # api.alsa.period-size = 1024 + # api.alsa.headroom = 0 + # api.alsa.disable-mmap = false + # api.alsa.disable-batch = false + # audio.format = "S16LE" + # audio.rate = 48000 + # audio.channels = 2 + # audio.position = "FL,FR" + # } + #} + + # Use the metadata factory to create metadata and some default values. + #{ factory = metadata + # args = { + # metadata.name = my-metadata + # metadata.values = [ + # { key = default.audio.sink value = { name = somesink } } + # { key = default.audio.source value = { name = somesource } } + # ] + # } + #} +] + +context.exec = [ + #{ path = + # ( args = "" | [ ... ] ) + # ( condition = [ { = ... } ... ] ) + #} + # + # Execute the given program with arguments. + # If condition is given, the program is executed only when the context + # properties all match the match rules. + # + # You can optionally start the session manager here, + # but it is better to start it as a systemd service. + # Run the session manager with -h for options. + # + #{ path = "/usr/bin/pipewire-media-session" args = "" + # condition = [ { exec.session-manager = null } { exec.session-manager = true } ] } + # + # You can optionally start the pulseaudio-server here as well + # but it is better to start it as a systemd service. + # It can be interesting to start another daemon here that listens + # on another address with the -a option (eg. -a tcp:4713). + # + #{ path = "/usr/bin/pipewire" args = [ "-c" "pipewire-pulse.conf" ] + # condition = [ { exec.pipewire-pulse = null } { exec.pipewire-pulse = true } ] } +] diff --git a/.config/pipewire/pipewire.conf.d/10-null-sink_1.conf b/.config/pipewire/pipewire.conf.d/10-null-sink_1.conf new file mode 100644 index 0000000..68aa3aa --- /dev/null +++ b/.config/pipewire/pipewire.conf.d/10-null-sink_1.conf @@ -0,0 +1,18 @@ +context.objects = [ + { factory = adapter + args = { + factory.name = support.null-audio-sink + node.name = "null-sink-1" + node.description = "Null Sink 1" + media.class = Audio/Sink + audio.position = [ FL FR ] + monitor.channel-volumes = true + monitor.passthrough = true + adapter.auto-port-config = { + mode = dsp + monitor = true + position = preserve + } + } + } +] diff --git a/.config/pipewire/pipewire.conf.d/11-null-sink_2.conf b/.config/pipewire/pipewire.conf.d/11-null-sink_2.conf new file mode 100644 index 0000000..dc2e6f1 --- /dev/null +++ b/.config/pipewire/pipewire.conf.d/11-null-sink_2.conf @@ -0,0 +1,18 @@ +context.objects = [ + { factory = adapter + args = { + factory.name = support.null-audio-sink + node.name = "null-sink-2" + node.description = "Null Sink 2" + media.class = Audio/Sink + audio.position = [ FL FR ] + monitor.channel-volumes = true + monitor.passthrough = true + adapter.auto-port-config = { + mode = dsp + monitor = true + position = preserve + } + } + } +] diff --git a/.config/pipewire/pipewire.conf.d/20-application-loopback_1.conf b/.config/pipewire/pipewire.conf.d/20-application-loopback_1.conf new file mode 100644 index 0000000..7e960d9 --- /dev/null +++ b/.config/pipewire/pipewire.conf.d/20-application-loopback_1.conf @@ -0,0 +1,16 @@ +context.modules = [{ + name = libpipewire-module-loopback + args = { + audio.position = [ FL FR ] + capture.props = { + media.class = "Audio/Sink" + node.name = "application-loopback-1-sink" + node.description = "Application-Loopback 1 Sink" + } + playback.props = { + media.class = "Stream/Output/Audio" + node.name = "application-loopback-1-playback" + node.description = "Application-Loopback 1 Playback" + } + } +}] diff --git a/.config/pipewire/pipewire.conf.d/21-application-loopback_2.conf b/.config/pipewire/pipewire.conf.d/21-application-loopback_2.conf new file mode 100644 index 0000000..beef4bc --- /dev/null +++ b/.config/pipewire/pipewire.conf.d/21-application-loopback_2.conf @@ -0,0 +1,16 @@ +context.modules = [{ + name = libpipewire-module-loopback + args = { + audio.position = [ FL FR ] + capture.props = { + media.class = "Audio/Sink" + node.name = "application-loopback-2-sink" + node.description = "Application-Loopback 2 Sink" + } + playback.props = { + media.class = "Stream/Output/Audio" + node.name = "application-loopback-2-playback" + node.description = "Application-Loopback 2 Playback" + } + } +}] diff --git a/.config/pipewire/pipewire.conf.d/30-device-loopback_1.conf b/.config/pipewire/pipewire.conf.d/30-device-loopback_1.conf new file mode 100644 index 0000000..df3a1c9 --- /dev/null +++ b/.config/pipewire/pipewire.conf.d/30-device-loopback_1.conf @@ -0,0 +1,20 @@ +context.modules = [ + { + name = libpipewire-module-loopback + args = { + audio.position = [ FL FR ] + capture.props = { + media.class = "Stream/Input/Audio" + node.name = "device-loopback-1-recording" + node.description = "Device-Loopback 1 Recording" + } + playback.props = { + media.class = "Stream/Output/Audio" + node.name = "device-loopback-1-playback" + node.description = "Device-Loopback 1 Playback" + } + audio.volume = 0.5 + audio.mute = true + } + } +] diff --git a/.config/pipewire/pipewire.conf.d/31-device-loopback_2.conf b/.config/pipewire/pipewire.conf.d/31-device-loopback_2.conf new file mode 100644 index 0000000..4d69e80 --- /dev/null +++ b/.config/pipewire/pipewire.conf.d/31-device-loopback_2.conf @@ -0,0 +1,20 @@ +context.modules = [ + { + name = libpipewire-module-loopback + args = { + audio.position = [ FL FR ] + capture.props = { + media.class = "Stream/Input/Audio" + node.name = "device-loopback-2-recording" + node.description = "Device-Loopback 2 Recording" + } + playback.props = { + media.class = "Stream/Output/Audio" + node.name = "device-loopback-2-playback" + node.description = "Device-Loopback 2 Playback" + } + audio.volume = 0.5 + audio.mute = true + } + } +]