A working bass equalizer for the SteelSeries Arctis Nova 7 on Linux, built on a native PipeWire filter-chain with a small GTK app to drive it.
SteelSeries ships no Linux software for these headsets. The two obvious
alternatives both turned out to be dead ends on Arch (measurements below), so
this takes the boring route that actually works: a filter-chain defined in a
config file, a systemd user service that keeps it alive, and a GTK front-end
that writes parameters live over pw-cli.
- 10 presets - Flat, Bass Boost, Deep Bass, Punch, V-Shape, Rock & Metal, Vocal Clarity, Classical & Piano, Warm, Late Night
- Strength slider (0-150%) that scales whichever preset is selected, so you tune by feel instead of editing numbers
- Per-band sliders for bass, sub, low mids, presence and air
- Automatic preamp that trims input by exactly the largest boost, so the chain cannot clip
- Settings persist and are reapplied at login
Everything applies live. No service restarts, no relogin.
- PipeWire (tested on 1.6.7)
- Python 3 with PyGObject and GTK 3 (Arch:
python-gobject gtk3) pactlfromlibpulse
git clone https://github.com/Dotims/arctis-eq
cd arctis-eq
./install.shThe installer autodetects the Arctis sink. If you have several output devices and it picks wrong, name it yourself:
ARCTIS_SINK=alsa_output.usb-SteelSeries_Arctis_Nova_7-00.analog-stereo ./install.shUninstall with ./uninstall.sh, which also hands the default sink back to the
headset so audio keeps working.
apps -> arctis_eq (filter-chain) -> Arctis Nova 7
config/arctis-eq.conf.in defines five biquad bands per channel plus a preamp:
| Node | Type | Role |
|---|---|---|
pre |
linear | preamp, clipping headroom |
ls |
low shelf | broad bass |
sub |
peaking | sub weight below the shelf |
mud |
peaking | cut so bass stops masking vocals |
pres |
peaking | presence, guitar and cymbal attack |
air |
high shelf | top-end openness |
The service runs pipewire -c against that config, which hosts a separate
PipeWire instance. That matters: it needs no daemon restart to load, and if it
dies it takes nothing else down. WirePlumber records a fallback
(default.configured.audio.sink.0) pointing back at the hardware sink, so a
missing EQ node means unprocessed audio rather than silence.
The GTK app never edits the config. It resolves the node id from pw-dump and
pushes gains with pw-cli set-param, batching every band into one call and
throttling writes while a slider is being dragged.
Both were tried first. Both failed, and both failed quietly, which is the annoying part - each reported success while changing nothing.
Hardware EQ via headsetcontrol. The Nova 7 advertises CAP_EQUALIZER
(10 bands, ±10 dB) and headsetcontrol -e prints Successfully set equalizer!.
That message only confirms the HID write succeeded, not that the headset applied
anything. Cutting all ten bands by -10 dB produced no audible change at all.
EasyEffects 8.2.4. It routes audio correctly - the graph really is
easyeffects_sink -> ee_soe_equalizer -> ... -> hardware - but it wipes its
own equalizer state on every start. ~/.config/easyeffects/db/equalizerrc
holds inputGain, band0Gain and friends; after an app restart those keys are
simply gone. easyeffects -a output returns an empty string and -l <preset>
does not load. Net effect: audio passes through untouched.
Measured, playing pink noise and comparing energy below 120 Hz against 0.8-1.6 kHz on a recording of the hardware sink monitor:
| Path | Tilt (low minus mid) |
|---|---|
| Raw signal | +7.6 dB |
| Through EasyEffects, bass preset loaded | +6.8 dB |
| Through this filter-chain | +18.9 dB |
That +7.6 dB baseline is just the natural spectrum of pink noise, not any equalizer at work. EasyEffects lands on the same figure within measurement noise, which is the whole point.
The measurement rig was validated first: the same method on a file processed
with ffmpeg -af bass=g=12 reports +12.0 dB, as it should.
If you reproduce this, note that ffmpeg -v error swallows volumedetect
output, since it logs at info level.
Presets are shapes; the Strength slider scales them. Start at a preset near what you want, then move Strength rather than touching individual bands.
Leave Automatic preamp on. Boosting bass without trimming input is how you get clipping on loud tracks. With it on, a +8 dB preset trims input by 8 dB, and you make up the difference with the volume knob.
MIT