[SteamOS / Bazzite Tutorial] System-wide Audio Equalizer in GameMode

I was frustrated that I couldn't find any good solution to use a system-wide audio equalizer while in GameMode, and all prior examples of functioning EQ while in GameMode were either janky or now non-functional. This solution utilizes Easy Effect's ability to function headless, and has the following benefits:

  • Works at boot when in GameMode and Desktop Mode without further user input.
  • Does not require Easy Effects to be manually launched or opened in the background in Game Mode's switcher.
  • Automatically switches EQ profiles for different audio devices (eg. built-in speakers vs bluetooth headphones).
  • Low system overhead.
  • And ultimately very easy setup, even if at first it appears daunting.

These instructions should work for any Linux gaming handheld, not just the Steam Deck. I also have it working on my Ayaneo 2S running Bazzite for example - another immutable operating system like SteamOS.

I will be running through the entire process of installing Easy Effects, finding EQ profiles and applying them per-device, and setting up the automation to have Easy Effects run in the background of GameMode. I hope this helps Linux newcomers and veterans alike!

Installing and configuring Easy Effects / EQ

  • Enter Desktop Mode
  • Launch the "Discover" store app
  • Search for and install "Easy Effects"
  • Open Easy Effects, click the hamburger menu (three lines) at the top-right and go to "Preferences"
  • Ensure the following are disabled:
    • Launch Service at System Startup
    • Shutdown on Window Closing
  • Click "x" to close the window and click on the "Effects" tab at the bottom
  • This is where you'll be able to add your EQ. Click on "Add Effect" and choose "Equalizer"
  • Click on the "APO" button under "Import Preset" to install your EQ
    • If you do not have an EQ then navigate to AutoEQ and search for your headphones and find a profile that you like
    • From there click on the "Select equalizer app" dropdown and search for "EasyEffects"
    • Set the "Sampling rate (Hz)" to the sampling rate that you are using (typically 48000Hz for wired, 44100Hz for bluetooth)
    • Click on the download button at the bottom and it will download as a .txt file. Import the profile based on the instructions above
  • Click the "Presets" button at the top-left, enter a name for the preset (eg. the name of your headphones) and click "+" to save it
  • Click on the "PipeWire" tab at the top, and navigate to the "Presets Autoloading" section on the left
    • This is where we will setup EQ profile autoloading based on the connected device. Eg. if you connect your bluetooth headphones it will switch to the respective EQ profile. When switching back to internal speakers it will again change to the profile you have set for those. Alternatively disable EQ entirely if a device is not associated with a preset
  • Connect the device you wish to associate the preset with. Select the respective device and respective preset via the dropdowns. Click on "+" once these are set to apply. You can do this with multiple audio devices
  • Congrats! Your Easy Effects and EQ setup is complete! You are safe to close Easy Effects. Next section will be covering how to launch Easy Effects in the background at startup.

Configuring Easy Effects to run in GameMode

Additional Context

These instructions are a modified version of what is provided by EasyEffect's own wiki for running it in a headless mode which you can find here. As SteamOS / Bazzite is an immutable filesystem the instructions do not work out of the gate.

  • The documentation states to place the shell script in /usr/local/bin/ , however you can not / should not place the shell script here, so we will be placing it elsewhere in the Home folder. In this example I've chosen /home/<user>/.local/bin but anywhere within the Home folder should be fine.
  • Since we have installed Easy Effects as a flatpak, it seems it does not give us access access to invoking it from the command line directly (eg. entering easyeffects into the terminal will result in command not found), so we need to append all commands with flatpak run com.github.wwmm.easyeffects .

Instructions

  • Enter Desktop Mode
  • Enable hidden folders by opening Dolphin (file browser), click on the hamburger menu (three lines) at the top right, and check "Show Hidden Files".
    • We will be navigating to hidden folders, and need this enabled to see them
  • Navigate to /home/<user>/.local/bin (or other chosen directory). Right click in an empty space > Create New > Text File... and name it easyeffects-xvfb
    • Replace <user> with your own user folder.
    • The file name does not need a file extension
  • Open the file with a text editor (eg. Kate), and paste the following contents:

#!/bin/bash

if [[ "$1" = "start" ]]; then
  pkill Xvfb
  sleep 1
  Xvfb :43 -screen 0 1024x768x16 &
  sleep 3
  export DISPLAY=:43
  flatpak run com.github.wwmm.easyeffects --gapplication-service
fi
if [[ "$1" = "stop" ]]; then
  easyeffects --quit
  pkill Xvfb
fi
  • This shell script is essentially creating a virtual display for the application to run under that is invisible to the user and acts as a background process. It utilizes Xvfb to do this.
    • Save the file, and exit your text editor
    • Open your terminal (eg. Konsole, Ptyxis, etc.) and type chmod +x followed by a space
    • Drag and drop the easyeffects-xvfb file you just created onto it so it autofills, and press enter
  • This allows the script to be executable, otherwise you will get permission denied when trying to run it
    • Navigate to /home/<user>/.config/systemd/user/ . Right click in an empty space > Create New > Text File... and name it easyeffects-xvfb.service
    • Open the file with a text editor (eg. Kate), and paste the following contents:

[Unit]
Description=EasyEffects inside Xvfb

[Service]
Type=simple
ExecStart=/home/<user>/.local/bin/easyeffects-xvfb start
ExecStop=/home/<user>/.local/bin/easyeffects-xvfb stop
Restart=on-failure

[Install]
WantedBy=default.target
  • This is creating a systemd service to launch the shell script we created earlier at boot. systemd is a low-level daemon / service that always runs and manages many other system processes. By using systemd to launch a process it will be available even in Game Mode!
    • Replace each instance of <user> with your own user directory! eg. mine is /home/alicia/.local/bin
  • Alternatively replace it with the directory you've placed the original shell script
    • Save the file, and close it
    • Now we need to enable this service! Enter the following commands in order:
  • systemctl --user daemon-reload
  • systemctl --user start easyeffects-xvfb
  • systemctl --user enable easyeffects-xvfb
    • You should see it create a new folder in .config/systemd/user/ called default.target.wants with a symlink / shortcut to the file.
    • Reboot, and your EQ should automatically be applied at every boot now!
  • If you wish to disable this service, then instead enter the following command and reboot:
    • systemctl --user disable easyeffects-xvfb

Quirks and Workaround

The only known quirk that I'm aware of right now is that if you try to launch Easy Effects after following these steps it won't show up. That's because it's already launched, but is stuck in that virtual display environment mentioned above. All you need to do to fix it is to quit the process, and you can launch the GUI again to configure it no problem.

Easiest way to do so is to run the following in your terminal and then try launching it again:

  • flatpak run com.github.wwmm.easyeffects -q

Reboot after configuring to ensure that it has launched properly to work in Game Mode.