Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Arctis EQ

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.

What you get

  • 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.

Requirements

  • PipeWire (tested on 1.6.7)
  • Python 3 with PyGObject and GTK 3 (Arch: python-gobject gtk3)
  • pactl from libpulse

Install

git clone https://github.com/Dotims/arctis-eq
cd arctis-eq
./install.sh

The 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.sh

Uninstall with ./uninstall.sh, which also hands the default sink back to the headset so audio keeps working.

How it works

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.

Why not the obvious options

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.

Tuning

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.

License

MIT

About

Working bass equalizer for the SteelSeries Arctis Nova 7 on Linux: PipeWire filter-chain plus a GTK app, after the hardware EQ and EasyEffects both failed

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages