Skip to content

jurf/fairbuds

Repository files navigation

Fairbuds EQ Tool

Test tool for the reverse-engineered Fairbuds GATT protocol.

At least subjectively, the expanded EQ capabilities significantly improve the sound compared to what's possible with the app itself, especially in the high end.

Now available as a web app (thanks @zyberspace).

Features

  • Set EQ presets (Main, Bass, Flat, Studio)
  • More EQ control
    • −12 to +13.5 dB per band (vs. app limited ±10 dB)
    • Customisable Q-factor (vs. app hardcoded 0.7)
  • Load parametric EQ files generated by AutoEQ
  • Battery level monitoring
  • Interactive CLI with command history

Quick start

Clone the repository

git clone --recurse-submodules https://github.com/user/fairbuds.git
cd fairbuds

If you already cloned without --recurse-submodules:

git submodule update --init --recursive

Install with uv

This project uses the uv Python package manager. To install it, run:

# Linux/macOS
curl -LsSf https://astral.sh/uv/install.sh | sh

# macOS with brew
brew install uv

# Or with pipx
pipx install uv

Then install the dependencies:

uv sync

Finding Your Fairbuds BLE Address

The BLE address might be different to the audio (BR/EDR) address shown in Bluetooth settings.

# Start BLE scan
uv run fairbuds --scan

# Look for your Fairbuds in the list, e.g.:
#   00:11:22:33:44:55    -96 dBm  Fairbuds
# macOS:
#   A1F7C2D9-4B8E-9A3F-16D2-7C5B8E0F4A12    ?? dBm  Fairbuds

Usage

uv run fairbuds 00:11:22:33:44:55   # Replace with your Fairbuds BLE address

Type help in the interactive CLI for more details on available commands. If you just want to try the best preset, type:

load rtings_treble

Command-line options

uv run fairbuds --help              # Show help
uv run fairbuds --version           # Show version
uv run fairbuds --scan              # Scan and list BLE devices
uv run fairbuds --list-presets      # List available AutoEQ presets

Project structure

  • AutoEq/ – AutoEQ (submodule)
  • notebooks/ – Jupyter notebooks for data analysis and visualisation
  • pex/ – Parametric EQ configs for AutoEQ
    • fairbuds.yaml – uses the full EQ capabilities
    • fairbuds-app.yaml – equivalent to the official app
  • presets/ – Parametric EQ presets
  • presets_app/ – App-compatible versions of the presets
  • measurements/ – Useful Fairbuds response curve measurements
  • src/ – Source code for this project
  • targets/ – Useful target curves for AutoEQ

Please keep in mind that this project is a quick-and-dirty experiment and most of the Python code was vibe-coded. There is not much point in making it more robust; it served only to test the protocol before attempting Gadgetbridge support.

Don't read too much into the code. The AI reads a bit too much into instructions and is very eager to change them into code with even more helpful comments. But the core implementation (EQ switching, custom EQ's battery info) should be correct.

Measurements

RTINGS (main eq, ANC Off).csv contains RTINGS measurement of the “Main” preset on the 5128. SoundGuys (main eq, ANC Off).csv contains SoundGuys measurement on the same preset and sim. These seem to be the best base for experimentation. Use the “JM-1 with Harman treble filter” target for best results with the reconstructed.csv signature to account for the Studio EQ.

The rest are from DHRME on the 711 for use with the “AutoEq in-ear” target. I had mixed results even though they also measured the “Studio” EQ, possibly due to differences in the firmware.

Some of these measurements are from AutoEq's database, the missing ones I preprocessed myself from the raw CSV files.

Presets

My current favourite one is presets/soundguys.txt. I recommend you experiment with others, as it might depend on your firmware or hardware specifics.

Q-values

The Q-values in the app are hardcoded to 7.

The actual interpretation is undocumented (if any calculations were present, they were most likely optimised out). This tool assumes the final Q-value is n/10.

This would mean the default is 0.7 with a range of 0.1–25.5, which is reasonable. It would also match the Fairbuds XL's 2023 default value (which is directly visible in the decompiled code).

Changing this value manually seems to affect the sound seemingly linearly, with the full range affecting the sound, and seems to match a software emulation with the same settings. But ultimately, it results in a meaningful improvement to the sound, so for now it's good enough.

It is worth mentioning though that manually calculating the value for the given bands would bring it closer to 1.2.

Generating AutoEQ presets

Follow the setup in the AutoEq README. Then use the parametric equalizer presets in pex/.

cd AutoEq
uv pip install -U -e .
. .venv/bin/activate
python -m autoeq \
    --input-file="../measurements/RTINGS (main eq, ANC Off).csv" \
    --output-dir="../results" \
    --target="targets/JM-1 with Harman treble filter.csv" \
    --max-gain=16 \
    --parametric-eq \
    --parametric-eq-config=../pex/fairbuds.yaml \
    --fs=44100 \
    --bass-boost=6.5 \
    --preamp=-4

For bass boost, I use the default on the AutoEq web app for the given target – 6.5 dB for the JM-1 target and 8 dB for the AutoEq in-ear target.

The max gain and preamp settings significantly affect the output of the optimiser. I got best results by brute-forcing all reasonable values and keeping the one with the lowest loss reported by the optimiser; see preamp_optimiser.py.

Regenerating built-in presets

Modify AutoEq based on the comment on PATCHED_AUTOEQ in preamp_optimiser.py, then run:

python scripts/preamp_optimiser.py

Protocol

TBD

About

Tool for the reverse-engineered Fairbuds GATT protocol with AutoEq presets

Topics

Resources

License

Stars

Watchers

Forks

Contributors