This project provides automated installation and configuration of multiple audio profiles including spatial audio (HeSuVi 5.1) for PipeWire.
This project is designed as a resource-efficient audio enhancement solution for laptops. Instead of expensive external audio hardware, it uses CPU-optimized PipeWire filter chains to significantly improve audio quality while keeping system resource usage minimal. Perfect for:
- Limited hardware: Works on budget/ultrabook laptops with modest built-in speakers
- Low CPU overhead: Highly optimized filters with minimal performance impact (~1-2% CPU)
- Maximum compatibility: Works with any PipeWire-capable Linux distribution
- Desktop environment independent: Works seamlessly on GNOME, KDE, XFCE, i3, Wayland, X11, and other Linux desktop environments
- Spatial audio: HeSuVi 5.1 convolution support for immersive listening experiences
These audio profiles are made for the ASUS Vivobook Go E1504FA with its built-in speakers.
The presets feature:
- Bass cut-off at 65 Hz (suitable for small notebook speakers)
- EQ tuned to compensate for laptop speaker limitations
- Soft-limiter to prevent distortion on small drivers
This project provides automated installation and configuration of PipeWire with multiple audio profiles.
-
HeSuVi 5.1 (
sink-eq10-5.1.conf)- 5.1 Surround-Sound processing (FL, FR, FC, LFE, SL, SR)
- HeSuVi HRTF filter for spatial audio
- Conversion to stereo output
- 10-band EQ per channel (separate L/R processing)
-
Standard EQ (
sink-eq10-wide.conf)- 10-Band Graphic Equalizer
- Stereo processing (FL, FR)
- Optimized for standard stereo playback
- Stereo widening (Widen effect)
- Soft-Limiter protection against clipping
- Real-Time (RT) Priority for low audio latency
- Automatic Soundcard Detection and audio sink configuration
- User-Level Installation in
~/.config/pipewire/ - De-Esser to reduce sibilance (S/Sh sounds)
- Soft-Limiter to prevent digital clipping
- Dynamic Config Detection - Automatically detects active PipeWire config
- Multi-Channel Support - Full support for Mono/Stereo/5.1 configurations
- Dark/Light Theme - Automatically follows system preferences
- Auto-Reload on Config Switch - GUI automatically reloads when default sink changes
- Multi-Language Support - English & German with automatic browser detection
- PWA Ready - Offline-capable web application
- PipeWire installed and active
wpctl(Part of PipeWire)playerctl(for audio playback control during restart)sudoordoasfor group management- Python 3.8+ (for GUI)
- Flask (for GUI)
- Configuration in
/etc/security/limits.d/25-pw-rlimits.conf - Membership in the
pipewiregroup
- Gunicorn (for production-grade server)
Python dependencies are automatically installed during ./install user into a virtual environment at ~/.local/share/goldaudio/venv/.
Current dependencies:
Flask==3.0.0
Werkzeug==3.0.1
gunicorn==21.2.0
Flask-Babel==4.0.0
Babel==2.14.0
Jinja2==3.1.2
pytz==2024.1
Manual installation (optional, only if you want to install outside the automated setup):
# From requirements.txt
pip install -r requirements.txt
# Or individually
pip install Flask gunicorn Flask-Babelchmod +x ./install
./install userThe script will:
- Create directories in
~/.config/pipewire/ - Detect your current username
- Detect the soundcard and its sink ID automatically
- Adjust file paths (HeSuVi, EQ filters)
- Automatically create and configure Python virtual environment in
~/.local/share/goldaudio/venv/ - Install Python dependencies from requirements.txt into the venv
- Install and configure GUI files to
~/.local/share/goldaudio/ - Install translation files (English, German, Turkish)
- Copy systemd service files to
~/.config/systemd/user/ - Enable and start systemd services for automatic backend startup
- Add you to the
pipewiregroup (for RT priority) - Create automatic backups if configurations already exist
Check pipewire.conf exists?
├─ YES → Ask if override
│ ├─ YES → Install new pipewire.conf
│ └─ NO → Keep existing
└─ NO → Install pipewire.conf
Install filter configurations (always)
Install HeSuVi files (always)
Detect audio sink (wpctl)
Set target.object in configs
Create Python venv (if not exists)
├─ Create venv in ~/.local/share/goldaudio/venv/
└─ Install requirements from requirements.txt
Install GUI files
├─ Copy gui.py, config.json, gunicorn_config.py
├─ Copy templates/ and static/ files
└─ Copy translations/
Install systemd services (always)
├─ Copy to ~/.config/systemd/user/
├─ Enable pipewire-eq.service
├─ Enable pipewire-listen.service
└─ Start pipewire-listen.service
Add user to pipewire group
./install uninstallThe script will:
- Remove HeSuVi files
- Remove filter configurations (sink-eq10-5.1.conf, sink-eq10-wide.conf)
- Ask if pipewire.conf should be removed
- YES → Delete pipewire.conf
- NO → Keep pipewire.conf (preserves manual edits)
- Disable and remove systemd service files
- Remove user from
pipewiregroup
.
├── install # Installation script
├── gui.py # Web GUI server with dynamic config detection
├── gunicorn_config.py # Gunicorn configuration
├── config.json # GUI configuration
├── babel_config.py # Multi-language configuration
├── requirements.txt # Python dependencies
├── README.md # This file
├── LICENSE # MIT License
├── pipewire.conf.d/
│ ├── pipewire.conf # Main PipeWire configuration
│ ├── sink-eq10-5.1.conf # HeSuVi 5.1 filter configuration (separate L/R)
│ └── sink-eq10-wide.conf # Standard EQ stereo configuration
├── hesuvi/
│ └── hesuvi.wav # HeSuVi HRTF Impulse Response
├── systemd-services/
│ ├── pipewire-eq.service # Systemd service for Gunicorn backend
│ └── pipewire-listen.service # Systemd service for auto-starting EQ on PipeWire activity
├── static/
│ ├── css/
│ │ ├── main.css # Main stylesheet (Light/Dark theme)
│ │ ├── main.min.css # Minified stylesheet
│ │ ├── round.css # Material Design icons
│ │ └── round.min.css # Minified Material Design icons
│ ├── fonts/ # Font files for Material Design icons
│ ├── img/ # Images and icons
│ │ ├── favicon.ico # Light theme favicon
│ │ ├── favicon-light.ico # Dark theme favicon
│ │ ├── music_note.svg # SVG music note icon
│ │ ├── music_note.ico # Music note favicon
│ │ └── screenshot.png # Application screenshot
│ ├── js/
│ │ ├── main.js # EQ editor logic with auto-config detection
│ │ ├── main.min.js # Minified main script
│ │ ├── change-language.js # Language auto-detection
│ │ ├── change-language.min.js # Minified language switcher
│ │ ├── serviceworker.js # PWA service worker
│ │ ├── serviceworker.min.js # Minified service worker
│ │ ├── theme-toggler.js # Light/Dark theme switcher
│ │ └── theme-toggler.min.js # Minified theme toggler
│ └── manifest.json # PWA manifest
└── templates/
├── eq.html # Web GUI interface
└── eq.min.html # Minified Web GUI interface
Specialized configuration for spatial audio:
- Input: 5.1 Surround-Sound (FL, FR, FC, LFE, SL, SR)
- Processing: HeSuVi HRTF filter with 10-band EQ per channel
- Output: Stereo (FL, FR) with spatial impression
- Channels: Separate L/R processing (synchronized updates via GUI)
- Use Case: Movies, TV series, immersive games
Graphic 10-band equalizer for everyday music:
EQ Bands:
- High-Pass (65 Hz) - removes inaudible sub-bass
- Bass Boost (120 Hz, +6dB) - kick punch
- Foundation (200 Hz, +5dB) - bass body
- Warmth (400 Hz, +3dB) - warmth and proximity
- Anti-Boxy (600 Hz, -1.5dB) - reduces papery sound
- Anti-Nasal (1000 Hz, -2dB) - reduces nasal tone
- Midrange Clarity (1500 Hz, -2dB) - clarity and separation
- Anti-Plastic (2000 Hz, -3dB) - natural, organic sound
- Presence (4500 Hz, +1.5dB) - speech intelligibility
- Brilliance (9000 Hz, +2dB) - detail and sparkle
- Air (12000 Hz, +2dB) - silkiness and extension
Additional Features:
- De-Esser (6 kHz, -1.5dB) - reduces sibilance from S/Sh sounds
- Soft-Limiter (High-Shelf, 10 kHz, -1dB) - prevents digital clipping
- Stereo widening (0.35) - wider stereo impression
- Final gain (1.15 = +1dB) - transparent level boost
- CPU Impact: Low (11 EQ bands only)
Signal Flow:
Input → High-Pass → EQ Bands (1-11) → De-Esser → Final Gain → Soft-Limiter → Output
Factor = 10^(dB / 20)
+1dB ≈ 1.12
+2dB ≈ 1.26
+3dB ≈ 1.41
+4dB ≈ 1.58
+6dB ≈ 2.00
The project includes an interactive web-based EQ editor for real-time audio adjustments.
- Real-time EQ adjustments with instant preview
- Dual sliders per band: Gain (dB) and Q (bandwidth) control
- Automatic Config Detection: Detects active PipeWire config via
node.description - Auto-Reload on Config Switch: GUI automatically reloads when you change the default sink (via
wpctl set-default) - Multi-Channel Support: Full support for 5.1 L/R channel synchronization
- Audio presets: Music, Podcast, Bright, Warm, Reset
- Visual feedback: Live value displays and status messages
- Automatic backups: All changes are backed up to
~/.local/share/goldaudio/backups/ - Dark/Light Theme: Automatically follows system preferences (respects
prefers-color-scheme) - Multi-Language UI: English, Deutsch & Türkçe with automatic browser detection
- PWA Support: Can be installed as standalone app
- Modern UI: Responsive design with Material Design icons
The GUI supports multiple languages with automatic detection:
Supported Languages:
- 🇬🇧 English
- 🇩🇪 Deutsch (German)
- 🇹🇷 Türkçe (Turkish)
How language selection works:
-
Auto-Detection (first visit):
- Browser language is detected (e.g.,
de-DE→de) - Page is automatically rendered in detected language
- Selection is saved to browser localStorage
- Browser language is detected (e.g.,
-
URL Parameter:
- Access specific language:
http://127.0.0.1:1338/?lang=de - Overrides browser language and saves to localStorage
- Access specific language:
Example:
# German user opens GUI → automatically in German
# User can access English via: http://127.0.0.1:1338/?lang=en
# User can access Turkish via: http://127.0.0.1:1338/?lang=tr
# Page reloads and stays in selected language (localStorage)The GUI automatically adapts to your system's color scheme preference:
- Light Theme: Clean, bright interface optimized for daytime use
- Dark Theme: Dark interface optimized for low-light environments
Supported in:
- Linux (GNOME, KDE, X11, Wayland)
- Firefox, Chrome, Safari
- Respects system
prefers-color-schemesetting
To change theme:
- System Setting: Change your OS theme (Settings → Appearance)
- Browser Override: Browser dev tools → Console:
// Force dark theme document.documentElement.style.colorScheme = 'dark'; // Force light theme document.documentElement.style.colorScheme = 'light';
The GUI automatically detects which PipeWire configuration is currently active:
# Mapping of PipeWire configs
CONFIG_MAPPING = {
"Pipewire Gold Standard Audio": "sink-eq10-wide.conf",
"Pipewire Gold (5.1) Audio": "sink-eq10-5.1.conf"
}How it works:
- GUI queries active sink via
wpctl status - Reads
node.descriptionfrom sink - Matches against CONFIG_MAPPING
- Loads corresponding config file
- Falls back to
sink-eq10-wide.confif detection fails
Manual config switching:
# List available sinks
wpctl status
# Set sink as default (GUI will automatically reload)
wpctl set-default <sink-id>
# GUI automatically detects new config and reloadsWhen you change the default sink using wpctl set-default:
- Frontend polls
/api/config-infoevery 2 seconds - Server detects config change (with 1-second caching)
- GUI auto-reloads automatically (
location.reload()) - New values are loaded and displayed
Example workflow:
# Terminal 1: Start GUI
python3 gui.py
# Terminal 2: Switch to different sink
wpctl status # List sinks
wpctl set-default <sink-id> # Change default
# GUI automatically reloads and shows new config values!For 5.1 configurations with separate L/R channels:
- Automatic Detection: GUI detects
_Land_Rsuffixes - Synchronized Updates: Both channels updated with same values
- Single GUI Interface: Same sliders control both channels
- Backup Strategy: One backup per update (covers both channels)
Example 5.1 band structure:
eq_band_1_L ← Left channel
eq_band_1_R ← Right channel (automatically updated)
Note: Python dependencies are automatically installed during installation into ~/.local/share/goldaudio/venv/. You can either activate the venv or use the venv Python directly.
Option 1: Using venv directly
~/.local/share/goldaudio/venv/bin/python3 ~/.local/share/goldaudio/gui.pyOption 2: Activate venv first
source ~/.local/share/goldaudio/venv/bin/activate
python3 ~/.local/share/goldaudio/gui.pyPros:
- Simple startup
- Auto-reload on code changes
- Great for development and testing
Cons:
- Single-threaded (only one connection at a time)
- Not suitable for production
- Slower performance
Then open your browser and navigate to: http://127.0.0.1:1338
Option 1: Using venv directly
~/.local/share/goldaudio/venv/bin/python3 -B -m gunicorn --config ~/.local/share/goldaudio/gunicorn_config.py --chdir ~/.local/share/goldaudio gui:appOption 2: Activate venv first
source ~/.local/share/goldaudio/venv/bin/activate
cd ~/.local/share/goldaudio
python3 -B -m gunicorn --config gunicorn_config.py gui:appPros:
- Multi-worker support (concurrent connections)
- Better performance and stability
- Production-grade reliability
- Pre-fork worker model for robustness
Cons:
- More resource intensive than Flask dev server
All dependencies pre-installed during ./install user. No additional setup needed!
Then navigate to: http://127.0.0.1:1338
The systemd service files are automatically installed and enabled during the ./install user process. No manual setup needed!
What gets installed automatically:
-
pipewire-eq.service - Starts the Gunicorn backend
- Virtual environment:
~/.local/share/goldaudio/venv/ - Multi-worker Gunicorn server (2 workers)
- Resource limits (64M memory, 50% CPU)
- Auto-restart on failure (5 second delay)
- Port: 1338
- Virtual environment:
-
pipewire-listen.service - Auto-starts EQ editor when PipeWire is active
- Monitors PipeWire state changes
- Automatically starts
pipewire-eq.servicewhen compatible audio sink detected - Stops service when switching to different audio device
- Protects backups during EQ operation
After install completes:
- Services are copied to
~/.config/systemd/user/ - Services are enabled for automatic startup on boot
pipewire-listen.serviceis started immediately- Backend starts automatically when you log in
Manual service management:
If you need to restart or manage the services manually:
# Check service status
systemctl --user status pipewire-eq.service
systemctl --user status pipewire-listen.service
# View logs in real-time
journalctl --user -u pipewire-eq.service -f
journalctl --user -u pipewire-listen.service -f
# Stop/restart services
systemctl --user stop pipewire-eq.service
systemctl --user restart pipewire-eq.service
# View all services
systemctl --user list-units --type=serviceCustomization:
Edit ~/.config/systemd/user/pipewire-eq.service to adjust:
- Port (default: 1338)
- Worker count (default: 2)
- Memory limit (default: 64M)
- CPU quota (default: 50%)
After changes:
systemctl --user daemon-reload
systemctl --user restart pipewire-eq.serviceDisable automatic startup (if needed):
systemctl --user disable pipewire-listen.service
systemctl --user disable pipewire-eq.serviceEdit config.json to customize GUI behavior:
{
"site_config": {
"title": "PipeWire Gold Audio EQ Editor",
"port": 1338,
"host": "127.0.0.1"
}
}All EQ changes are automatically backed up to:
~/.local/share/goldaudio/backups/
- Backup strategy: Circular (oldest backup is overwritten when limit reached)
- Max backups: 10 per configuration file
- Naming:
sink-eq10-wide.conf.backup_YYYYMMDD_HHMMSS - Multi-channel backups: Single backup covers all L/R channels in 5.1
Available presets for quick EQ switching:
- Music - Boosted bass and presence for music listening
- Podcast - Optimized for speech intelligibility
- Bright - Bright, detailed sound for analytical listening
- Warm - Warm, smooth sound for casual listening
- Reset - Revert to default configuration
The installation script automatically adjusts the following values:
target.object = "sink-name" # Your audio sinkFile paths are set to the user's installation directory:
~/.config/pipewire/hesuvi/hesuvi.wav
If automatic detection doesn't work:
-
Get sink ID:
wpctl status
Look for "Speaker + Headphones" and note the ID (e.g. 75)
-
Get sink name:
wpctl inspect <ID> | grep 'node.name' | awk '{print $4}' | tr -d '"'
-
Manually edit configuration:
editor ~/.config/pipewire/pipewire.conf.d/sink-eq10-wide.confFind and update:
target.object = "alsa_output.pci-0000_03_00.6.HiFi__hw_Generic_1__sink"
For optimal audio latency, PipeWire should run with Real-Time (RT) priority.
# Check RT limits
cat /etc/security/limits.d/25-pw-rlimits.conf
# Check RT status
ps -mo pid,tid,rtprio,comm -C pipewireThe installation script automatically adds you to the pipewire group. After login, RT priority should be enabled.
Important: Log out and log back in for group changes to take effect!
After installation and restart, new audio sinks will be created automatically.
- Pipewire Gold (5.1) Audio - HeSuVi 5.1 for spatial audio (separate L/R channels)
- Pipewire Gold Standard Audio - 10-Band EQ for standard stereo
# List all available sinks
wpctl status
# Set default sink (GUI will auto-reload with new config)
wpctl set-default <sink-id>
# Inspect sink details (see active filters)
wpctl inspect <sink-id>
# Get active config's node.description
wpctl inspect <sink-id> | grep 'node.description'
# Restart PipeWire after manual config changes
systemctl --user restart pipewire
# View logs
journalctl --user -u pipewire -f# Check available sinks
wpctl status
# Verify sink is active
wpctl inspect <sink-id>
# Set the sink as default
wpctl set-default <sink-id>
# Restart PipeWire
systemctl --user restart pipewire# Restart PipeWire (required after config changes)
systemctl --user restart pipewire
# Check logs for errors
journalctl --user -u pipewire -f
# Verify target.object is correct
grep "target.object" ~/.config/pipewire/pipewire.conf.d/sink-eq10-wide.conf
# Check sink name manually
wpctl inspect <sink-id> | grep 'node.name'The GUI uses node.description to detect active config:
# Check actual node.description
wpctl status | grep '*' | awk '{print $3}' | tr -d '.' | head -n1 | xargs wpctl inspect | grep 'node.description'
# If not in CONFIG_MAPPING, add to gui.py:
CONFIG_MAPPING = {
"Your Config Name": "your-config-file.conf"
}
# Restart GUI after changesCheck if polling is active:
- Open Browser DevTools (F12)
- Check Console for
config_inforequests - Should see requests every 2 seconds
If no polling:
# Check browser console for JavaScript errors
# Make sure /api/config-info endpoint is working:
curl http://127.0.0.1:1338/api/config-infoManual reload:
# Force page reload after changing sink
wpctl set-default <sink-id>
# Then manually refresh browser (Ctrl+R or Cmd+R)Check browser localStorage:
// In browser DevTools Console:
localStorage.getItem('language')
// Clear language preference
localStorage.removeItem('language')
// Hard refresh browser (Ctrl+Shift+R)Check Flask-Babel configuration:
# Verify translations exist
ls -la translations/
# Should show: en/, de/, tr/ directories with LC_MESSAGES/messages.poEnsure bands have correct naming with _L and _R suffixes:
# Check band names in config
grep "name = " ~/.config/pipewire/pipewire.conf.d/sink-eq10-5.1.conf | head -20
# Should show: eq_band_1_L, eq_band_1_R, etc.This indicates CPU overload. Solutions:
- Disable HeSuVi 5.1 (high CPU cost)
- Increase quantum size in pipewire.conf:
default.clock.quantum = 2048 - Check CPU usage:
top -p $(pgrep pipewire)
# Check user group membership
groups $USER
# Expected output should include: pipewire
# Check limits
ulimit -r
# Should show: unlimited
# Restart PipeWire
systemctl --user restart pipewire
# Verify RT priority
ps -mo pid,tid,rtprio,comm -C pipewireIf audio sounds distorted or clips:
- Reduce EQ gains (especially bands 1-3)
- Verify soft-limiter is enabled at 10 kHz, -1dB
- Check playback volume in system settings
- Reduce overall gain if needed
Python dependencies issue (if installation failed):
# Reinstall dependencies into venv
source ~/.local/share/goldaudio/venv/bin/activate
pip install -r requirements.txt
# Or from the project directory
~/.local/share/goldaudio/venv/bin/pip install -r ~/path/to/requirements.txtFlask dev server issues:
# Activate venv first
source ~/.local/share/goldaudio/venv/bin/activate
# Run with verbose output
python3 -u ~/.local/share/goldaudio/gui.pyGunicorn issues:
# Activate venv and run from GUI directory
source ~/.local/share/goldaudio/venv/bin/activate
cd ~/.local/share/goldaudio
python3 -B -m gunicorn --config gunicorn_config.py gui:app
# If pkg_resources error occurs, try Flask dev server instead
python3 -u gui.pyCheck venv status:
# Verify venv exists and is working
~/.local/share/goldaudio/venv/bin/python3 --version
# List installed packages
~/.local/share/goldaudio/venv/bin/pip list
# Should include: Flask, gunicorn, Flask-BabelEQ bands can be adjusted in sink-eq10-wide.conf or through the web GUI:
{ type = "builtin" name = "eq_band_1" label = "bq_peaking"
control = { Freq = 120.0 Q = 1.5 Gain = 6.0 } }- Freq: Center frequency in Hz
- Q: Quality factor (higher = narrower bandwidth, more precise)
- Gain: Boost/Cut in dB (positive = boost, negative = cut)
- Start the GUI:
python3 gui.pyorpython3 -B -m gunicorn --config gunicorn_config.py gui:app - Open http://127.0.0.1:1338 in your browser
- GUI automatically detects active config
- Language automatically selected (Browser → localStorage → default EN)
- Adjust sliders for Gain and Q values
- Click "Save changes" to apply
- Changes are automatically backed up and PipeWire is restarted
- GUI remains open with updated values
Edit ~/.config/pipewire/pipewire.conf.d/sink-eq10-wide.conf directly and restart PipeWire:
systemctl --user restart pipewireFor 5.1 configs, remember to update both _L and _R channels:
# Edit sink-eq10-5.1.conf
editor ~/.config/pipewire/pipewire.conf.d/sink-eq10-5.1.conf
# Update both channels, then restart
systemctl --user restart pipewireTo make limiter less aggressive:
{ type = "builtin" name = "soft_limiter" label = "bq_highshelf"
control = { Freq = 10000.0 Q = 0.7 Gain = -0.5 } }To make limiter more aggressive:
{ type = "builtin" name = "soft_limiter" label = "bq_highshelf"
control = { Freq = 10000.0 Q = 0.7 Gain = -2.0 } }After any changes:
systemctl --user restart pipewire- User-level installation only: System-wide installation can cause audio playback issues when switching the default device
- No hardware compressor: PipeWire filter-chain does not include native compressor. Use soft-limiter or reduce EQ gains instead.
- Single target device: Each configuration targets one audio sink. For multiple devices, manually create separate configurations.
- HeSuVi 5.1 CPU intensive: Convolver + 20 EQ bands require significant CPU. Use Standard EQ for lower-end systems.
- GUI requires restart: EQ parameter changes via GUI trigger automatic PipeWire restart (~2 seconds of audio loss)
- 5.1 detection: GUI requires
_Land_Rsuffixes for 5.1 channel detection. Standard configs without suffixes work as Stereo. - Config polling interval: 2-second polling may introduce slight delay in detecting config changes
- Language files: Translation files must exist in
translations/directory for multi-language support
Contributions are welcome! Please feel free to submit improvements, bug reports, or new features.
This project is licensed under the MIT License. See LICENSE for details.
Last Updated: 2026-03-27
Version: 1.0.5
Status: Stable ✅

