5

I need a way to set mono audio output on my system.
I had used this solution before: Can I downmix stereo audio to mono?

pacmd load-module module-remap-sink sink_name=mono master=NAME_OF_AUDIO_SINK \
 channels=2 channel_map=mono,mono

However, it stopped working when I upgraded to Kubuntu 22.10, presumably because it now uses PipeWire instead of PulseAudio. When I do pacmd list-sinks I get:
No PulseAudio daemon running, or not running as session daemon.

How can I do the same (downmix stereo audio output to mono) on PipeWire?

I found here a solution to a similar problem, but if I understand correctly that's for getting mono input. I want mono output.
Even better if I can easily switch it to mono/stereo using GUI, or set it to mono only when my stupid earphones are connected.

PS: They should really implement Mono Sound as a profile/configuration on System Settings > Audio, but oh well...

geekley
  • 549
  • Also asked here: https://askubuntu.com/questions/1409194/enable-mono-audio-output-in-ubuntu-22-04lts – geekley Nov 08 '22 at 04:16

4 Answers4

2

I managed to achieve true mono output by combining the stereo stream into a mono sink Pipewire - Module Combine Stream:

use $ wpctl status to get the sink id of your desired sink and $ wpctl inspect [ID] to get the node.name variable to use on the configuration file.

$ wpctl status

PipeWire 'pipewire-0' [0.3.56, user@hostname, cookie:1163266174]

Audio ├─ Devices: │ 42. HD Audio Controller [alsa] │ 105. USB PnP Audio Device [alsa] │ ├─ Sinks: │ * 48. HD Audio Controller Analog Stereo [vol: 0.50] │ ├─ ... │ ├─ Sources: │ * 101. USB PnP Audio Device Mono [vol: 0.74] │ └─ ...


$ wpctl inspect 48

id 48, type PipeWire:Interface:Node
    ...
    ...
  * factory.id = "18"
    factory.mode = "merge"
    factory.name = "api.alsa.pcm.sink"
    ...
  * media.class = "Audio/Sink"
  * node.description = "HD Audio Controller Analog Stereo"
  * node.name = "alsa_output.pci-0000_08_00.4.analog-stereo"
  * node.nick = "ALC1220 Analog"
    ...
  * object.path = "alsa:pcm:1:front:1:playback"
  * object.serial = "49"
    ...
  • In your distribution folder of pipewire(usually /usr/share/pipewire), find the pipewire.conf file and add this configuration with the modifications that suits your needs. You can either just copy the part inside context.modules=[] or create a new file and add to the ~/.config/pipewire/pipewire.conf.d/ or ~/.config/pipewire/pipewire-pulse.conf.d directories.

  • At the context.modules section:

context.modules = [
{   name = libpipewire-module-combine-stream
        args = {
            combine.mode = sink
            node.name = "combine_stereo_to_mono_sink" # Can be any name of your choice
            node.description = "Mono Speakers" # This is the name that will appear in the sound settings
            combine.latency-compensate = false
            combine.props = {
            audio.position = [ MONO ]
            }
            stream.props = {
                stream.dont-remix = true
            }
            stream.rules = [
            {   matches = [
                    {   media.class = "Audio/Sink"
                        node.name = "alsa_output.pci-0000_08_00.4.analog-stereo" # Your node.name here
                    } ]
                    actions = { create-stream = {
                            audio.position = [ FL FR ]
                            combine.audio.position = [ MONO ] # These both are what combine both channels into one
                    } } }
            ]
        }
    }
]

After saving the file, either reboot your system or restart pipewire and wireplumber:

$ systemctl --user restart pipewire pipewire-pulse wireplumber

This is my sound settings: Mono Speakers Mono Speakers2

  • This doesn't work for me on Kubuntu 23.10. Instead, it makes all audio settings disappear. I made sure to use the correct node.name from wpctl inspect. – emk2203 Oct 20 '23 at 20:54
  • I'll try on a VM with Kubuntu to check the possible errors @emk2203, here on both fedora 39 and ubuntu 23.04 it worked, but both are gnome – Eduardo Moraes Nov 16 '23 at 22:20
1

Maybe you could use qpwgraph and link both L and R channels in a manner similar to this:

enter image description here

Profiles can be saved, but for that I redirect you to the docs. Here is a bit about saving and loading profiles with pipewire on ArchWiki: https://wiki.archlinux.org/title/PipeWire#PipeWire_patch_sets_for_command_line

Tooster
  • 467
  • OK, so I tried this. While this connection in the answer is wrong (it's linking mic to output), I was able to make it work temporarily for my case by linking monitor_FL to playback_FR (my earphone problem is that it has only R output on both sides, so although this isn't "mono" it would work for me; mixing connections didn't work). HOWEVER I was not able to persist settings across reboots. The program is probably buggy, because I couldn't make it apply the profile on startup via command-line - I would have to manually make the connection every time, which doesn't solve my problem. – geekley Nov 19 '22 at 21:51
  • I tried many different things, but the app doesn't even load the connection in the saved profile correctly. – geekley Nov 19 '22 at 21:59
  • 1
    @Tooster I have to say; even if this wouldn't work (that is if it won't work), I must say this anyway, a nice program recommendation! +1 for that, really. – William Martens Nov 21 '22 at 19:25
1

I managed to make mono audio output work in PipeWire by installing EasyEffects equalizer.

sudo apt install easyeffects
  1. Output > Effects > Add Effect > Stereo Tools
  2. On Stereo Matrix tab, choose "Mono Sum L+R". "Stereo to Mid-Side" seems to work too.
  3. In Preferences, make sure to enable "Launch Service at System Startup".
  4. Create presets for "Mono" and "Stereo" if desired (optional).

EasyEffects - Downmix audio output to mono EasyEffects - Launch service at system startup

geekley
  • 549
1
  • Another solution without the need to install another program would be creating a mono output configuration file for PipeWire.

  • For example the following configuration can be done per user session:

    • Create a mono-playback.conf in ~/.config/pipewire/pipewire.conf.d with the following:

      context.modules = [
          { name = libpipewire-module-loopback
              args = {
                  node.description = "Mono Playback Device"
                  capture.props = {
                      node.name      = "mono_output"
                      media.class    = "Audio/Sink"
                      audio.position = [ MONO ]
                  }
                  playback.props = {
                      node.name      = "playback.mono_output"
                      audio.position = [ MONO ]
                      node.passive   = true
                  }
              }
          }
      ]
      
    • Restart pipewire service:

      systemctl --user restart pipewire{,-pulse}.{service,socket}
      
    • This will create a virtual device (a sink in this case) named Mono Playback Device

    • The device can be selected by GUI from an audio applet or system settings. Example using KDE Plasma audio applet.

  • For Further reading to understand the options you can refer to PipeWire Wiki, Virtual Devices section.

  • Good, easy, device-independent solution. The volume seems to depend on the volume of the stereo volume settings, if set to 80%, it's about equal to it. – emk2203 Oct 20 '23 at 21:13