Skip to content
onlymashPublic

About

A wireless headset control center for the Linux desktop

Topics

Resources

Stars

20 stars

Watchers

0 watching

Forks

Repository files navigation

WaveTune

English | 简体中文

An unofficial multi-brand wireless headset control center for the Linux desktop (ported from EncoDeck), built with Rust and GTK4 / Libadwaita. It currently supports OPPO, OnePlus, realme, and EarFun wireless headsets, with a decoupled multi-brand architecture ready for expanding to additional brands in the future.

This project is not affiliated with or endorsed by any headset vendor. See docs/api/OPPO_BLUETOOTH_API.md and docs/api/EARFUN_BLUETOOTH_API.md for private Bluetooth protocol details and hardware verification notes.

Features

  • Status Monitoring & 3D Preview: Real-time battery levels, charging status where reported by the protocol, in-ear wear and case-lid state where available, firmware version display, device artwork, and interactive 3D model preview.
  • Noise Control: Switch between Active Noise Cancellation (with multi-level intensity), Transparency mode (including Vocal Enhancement), and Adaptive noise control. Availability follows model capabilities; a wear-state gate is applied only when the protocol reports physical wear state. EarFun GAIA reports the in-ear detection setting but not physical wear or charging state.
  • Sound & Audio Effects: Built-in sound presets, custom multi-band Equalizer (EQ), Spatial Audio (Fixed / Head Tracking), and low-latency Game Mode.
  • Controls & Utilities: Customize left/right touch and call gestures, long-press noise-control cycling, dual-device connection and paired-host switching, in-ear auto-pause, sleep detection, earbud fit test, Find My Earbuds, prompt volume adjustment, and microphone selection on compatible EarFun profiles. Choose the target from a compact popover and use the find/stop action in the controls card. EarFun features are enabled according to each registered model's compatibility profile and implemented controls; hardware validation is recorded separately and is not an additional enablement requirement.
  • Desktop Integration: Native GTK4 / Libadwaita UI with English/Chinese localization, selectable app icon styles, background mode with a StatusNotifierItem system tray, silent login autostart, plus a companion GNOME Shell Quick Settings extension (GNOME 45–51).

Installation

Arch Linux (AUR)

Users on Arch Linux and its derivatives can install wavetune-git from the AUR:

paru -S wavetune-git
# or with yay
yay -S wavetune-git

Or clone and build manually:

git clone https://aur.archlinux.org/wavetune-git.git
cd wavetune-git
makepkg -si

Before launching WaveTune, make sure the system bluetooth service is running and pair/connect your headset via your desktop's Bluetooth settings first (WaveTune attaches to already-connected headsets rather than handling OS-level pairing):

sudo systemctl enable --now bluetooth

GNOME Quick Settings Extension

A companion extension for GNOME 45–51 is included at gnome-shell/wavetune@onlymash.github.com (automatically installed to the system extensions directory by distribution packages).

For local installation from source:

./gnome-shell/install-local.sh
gnome-extensions enable wavetune@onlymash.github.com

In a Wayland session, if gnome-extensions does not recognize the UUID on first install, log out and back into your desktop session once before running the enable command.

When a supported headset is connected, a headset tile appears in the GNOME Quick Settings panel for toggling noise cancellation, checking live battery levels, switching noise-control sub-modes, or opening the main window. "Keep Running in Background" is enabled by default (closing the window hides it to the background; choose "Quit" from the main menu or press Ctrl+Q to exit completely), and "Start in Background on Login" can be toggled in Preferences.

System Tray

While WaveTune is running it exports a StatusNotifierItem and DBusMenu on the session bus, so the app remains reachable after its window is hidden to the background. The tray uses the monochrome io.github.onlymash.WaveTune-symbolic icon and offers opening the main window, live device/battery information, noise-mode switching (when the headset is worn and controls are available), and quitting.

GNOME does not provide a system tray by default; install the AppIndicator and KStatusNotifierItem Support extension. KDE Plasma, XFCE, Waybar (Sway/Hyprland/Niri), COSMIC, and other StatusNotifierItem hosts consume the same protocol without additional software. The implementation reuses the existing gio::DBusConnection, so it adds no runtime or build dependencies.

Building from Source

Requires bluez, gtk4, libadwaita (>= 1.9), pkgconf, and the Rust stable toolchain. On Arch Linux:

sudo pacman -S --needed bluez gtk4 libadwaita pkgconf rustup
rustup default stable

Build and run:

cargo build --release   # Release binary at target/release/wavetune
cargo test
cargo run

CLI options:

  • --background / -b: Start silently in the background without opening the main window.
  • --probe: Run a one-shot read-only diagnostic query against a connected headset and print a summary.

Packaging

Packaging scripts and templates live under packaging/:

packaging/package.sh            # Build Arch package if makepkg is available, otherwise deb
packaging/package.sh arch       # Build Arch package from working tree snapshot
packaging/package.sh git        # Build wavetune-git from local committed HEAD
packaging/package.sh deb        # Build Debian/Ubuntu .deb package (requires dpkg-deb and libadwaita >= 1.9)

Built packages are written to target/dist/. For AUR repository generation and publishing workflows, see packaging/arch/README.md.

Compatibility

The built-in compatibility catalog covers 130+ OPPO, OnePlus, and realme headset models, as well as EarFun Air Pro 4, Free Pro 3, Air S, Air Pro 4+/4+AI, Air Pro 5, Air Pro 3 variants, Free 2S, ATVEL Tune S5 ProX, Wave Pro X, and 11 EF-profile IDs. EarFun models without a known numeric Product ID use a strict model prefix in the firmware response when available; Bluetooth names are never used as model identifiers. For registered profiles, declared and implemented features are enabled without requiring prior real-device validation. EF support currently covers a subset of status, noise, game, prompt-volume, find, and spatial-audio controls; EF profile identification from firmware remains source-derived and unverified, so unmatched devices stay read-only. See the EarFun protocol notes for per-model scope and limitations.

License

GPL-3.0-only

About

A wireless headset control center for the Linux desktop

Topics

Resources

Stars

20 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages