Sound Blaster X4 and Pipewire
Table of Contents
For Christmas, I received a Sound Blaster X4. I wanted this because I like the idea of having two audio outputs (game and chat) and being able to mix between them on the fly. Of course, the one issue I ran into was not being able to do that mixing, because by default Linux doesn’t see the chat output for the device. After a bit of learning about ALSA and Pipewire, I was able to fix it.
Update 2024-06-19: WirePlumber updated how it looks for the customization files, so I have updated this post to reflect that. If you already followed this guide before, you can delete ~/.config/wireplumber/main.lua.d/51-alsa-custom.lua
(and the empty main.lua.d
directory), and then make the new config file shown in the WirePlumber alsa-custom
section.
New alsa-card-profile #
To start, you will need to make a new alsa-card-profile for the Sound Blaster X4. You can define this in your home config directory for easy management.
~/.config/alsa-card-profile/mixer/profile-sets/sound-blaster-x4.conf
[General]
auto-profiles = no
[Mapping analog-stereo]
device-strings = front:%f
channel-map = left,right
paths-output = analog-output analog-output-lineout analog-output-speaker
direction = output
priority = 15
[Mapping analog-surround-21]
device-strings = surround21:%f
channel-map = front-left,front-right,lfe
paths-output = analog-output analog-output-lineout analog-output-speaker
direction = output
priority = 13
[Mapping analog-surround-40]
device-strings = surround40:%f
channel-map = front-left,front-right,rear-left,rear-right
paths-output = analog-output analog-output-lineout analog-output-speaker
direction = output
priority = 12
[Mapping analog-surround-41]
device-strings = surround41:%f
channel-map = front-left,front-right,rear-left,rear-right,lfe
paths-output = analog-output analog-output-lineout analog-output-speaker
direction = output
priority = 13
[Mapping analog-surround-50]
device-strings = surround50:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center
paths-output = analog-output analog-output-lineout analog-output-speaker
direction = output
priority = 12
[Mapping analog-surround-51]
device-strings = surround51:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
paths-output = analog-output analog-output-lineout analog-output-speaker
direction = output
priority = 13
[Mapping analog-surround-71]
device-strings = surround71:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
paths-output = analog-output analog-output-lineout analog-output-speaker
direction = output
priority = 12
[Mapping analog-stereo-chat-output]
description-key = gaming-headset-chat
device-strings = hw:%f,1,0
channel-map = left,right
paths-output = analog-output analog-output-lineout analog-output-speaker
direction = output
priority = 15
[Mapping analog-stereo-chat-input]
description-key = gaming-headset-chat
device-strings = hw:%f,0,0
channel-map = left,right
paths-input = analog-input analog-input-linein analog-input-mic
direction = input
intended-roles = phone
priority = 15
[Profile sound-blaster-x4-20]
output-mappings = analog-stereo analog-stereo-chat-output
input-mappings = analog-stereo-chat-input
[Profile sound-blaster-x4-21]
output-mappings = analog-surround-21 analog-stereo-chat-output
input-mappings = analog-stereo-chat-input
[Profile sound-blaster-x4-40]
output-mappings = analog-surround-40 analog-stereo-chat-output
input-mappings = analog-stereo-chat-input
[Profile sound-blaster-x4-41]
output-mappings = analog-surround-41 analog-stereo-chat-output
input-mappings = analog-stereo-chat-input
[Profile sound-blaster-x4-50]
output-mappings = analog-surround-50 analog-stereo-chat-output
input-mappings = analog-stereo-chat-input
[Profile sound-blaster-x4-51]
output-mappings = analog-surround-51 analog-stereo-chat-output
input-mappings = analog-stereo-chat-input
[Profile sound-blaster-x4-71]
output-mappings = analog-surround-71 analog-stereo-chat-output
input-mappings = analog-stereo-chat-input
This file starts with auto-profiles = no
, which means that it won’t auto generate any profiles. It will instead only use the explicitly defined ones. Next are the mappings, which list out every input/output of the device. Finally we have the profiles, which will take the mappings and combine them together.
The mappings are pretty much copied from /usr/share/alsa-card-profile/mixer/profile-sets/default.conf
, but with added descriptions. Of note, the [Mapping analog-stereo-chat-output]
is what was missing from the default config, and is why there wasn’t a chat output channel present. The default (game) output is on device 0, and the chat output is on device 1:
aplay -l
...
card 3: X4 [Sound Blaster X4], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 3: X4 [Sound Blaster X4], device 1: USB Audio [USB Audio #1]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 3: X4 [Sound Blaster X4], device 2: USB Audio [USB Audio #2]
Subdevices: 1/1
Subdevice #0: subdevice #0
So, using device-strings = hw:%f,1,0
is what lets us access it! Also of note, for some reason the [Profile sound-blaster-x4-40]
does not show up, because for some reason [Mapping analog-surround-40]
isn’t valid for the device. If you check aplay -L
, you can see that surround40
is listed, so I am not sure why this is the case. I have left it defined just in case it decides to start working someday.
WirePlumber alsa-custom #
The only other thing you need is to configure the Sound Blaster X4 to use this new alsa-card-profile. You can define this in your home config directory as well. This is also assuming you are using WirePlumber.
~/.config/wireplumber/wireplumber.conf.d/51-alsa-custom.conf
monitor.alsa.rules = [
{
matches = [
{
device.nick = "Sound Blaster X4"
}
]
actions = {
update-props = {
api.alsa.use-acp = true,
api.acp.auto-profile = false
api.acp.auto-port = false
device.profile-set = "sound-blaster-x4.conf"
device.profile = "sound-blaster-x4-20"
}
}
}
]
This (and the alsa-card-profile above) is pretty much taken from the ArchWiki, but with the proper device.nick
.
If you followed this guide previously, you can delete the file ~/.config/wireplumber/main.lua.d/51-alsa-custom.lua
(and the empty main.lua.d
directory), as this isn’t used by WirePlumber anymore.
Reload #
Once those two files are in place, simply restart WirePlumber and you should be good to go!
systemctl --user restart wireplumber.service
Other Notes #
The Sound Blaster X4 also supports the digital iec958
mappings listed in the default.conf
file, but I wasn’t able to get them to work with my setup, and thus ignored them in the alsa-card-profile I made. Feel free to add them if you know you will need them.