Skip to main content

VantaDSP: safe JBL Portable Bluetooth protocol, EQ, CLI, and TUI toolkit

Project description

VantaDSP

VantaDSP is a safety-first Python toolkit and monochrome terminal interface for inspecting and controlling EQ on speakers supported by JBL Portable. It was built from static analysis of JBL Portable 6.9.12 and hardware validation, without modifying the original APK.

Independent interoperability project. Not affiliated with or endorsed by JBL or Harman. All trademarks belong to their owners. Do not commit or redistribute APK or firmware files with this repository.

VantaDSP monochrome Bluetooth EQ control TUI

Highlights

  • Clean monochrome TUI with device discovery, model-aware EQ, live status, packet preview, and activity logs
  • BLE scan, advertisement/manufacturer-data inspection, and full GATT service discovery
  • Automatic JBL model/PID detection from Harman advertisement bytes, service UUIDs, names, and Windows paired metadata
  • Harman/JBL BLE GATT and Bluetooth Classic SPP transports
  • Legacy simple, advanced-level, and parametric EQ codecs
  • Protocol 4 0E02 parametric and Grip-style 0E7F quantized EQ codecs
  • PID-based automatic protocol routing across 37 catalogued models
  • 24 curated sound profiles mapped to each model's band layout and quantization
  • Read-only multi-generation probing, raw packet capture/decoding, and expert packet transmission
  • Verified writes with protocol acknowledgement, automatic EQ read-back, per-band comparison, and detailed transaction logs
  • CLI dry-run by default, direct TUI apply, target hashing, and JSONL audit logs

Install

Install the latest release from PyPI:

python -m pip install vantadsp

PyPI installations check for updates in the background when vantatui starts. A newer release is installed with the same Python interpreter, and Activity reports that a restart is required. Editable development installs are never overwritten automatically. Manual commands are also available:

vantactl check-update
vantactl update

To install from a cloned repository instead:

python -m pip install .

For development, use an editable installation with the QA toolchain:

py -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"

Launch the TUI:

vantatui

The interface provides DEVICE, EQUALIZER, and ACTIVITY workspaces, plus a detailed SYSTEM / DEVICE / PROTOCOL status strip. APPLY TO SPEAKER reads the state before writing, writes after model and gain validation, checks the acknowledgement, reads the EQ again, and reports WRITE VERIFIED only when the acknowledgement is accepted and every decoded band matches. It distinguishes CHANGED + VERIFIED from ALREADY MATCHED + VERIFIED. Activity opens automatically and records the transaction ID, route, target fingerprint, before/write/after TX/RX frames, decoded responses, requested and actual gains, per-band deltas, elapsed time, and failure stage. Audit records store a hash of the target instead of its Bluetooth address.

Runtime configuration and audit files are stored under %LOCALAPPDATA%\vantadsp\ on Windows. Bluetooth must be enabled, and Windows must permit desktop apps to use Bluetooth and location. For SPP, pair the speaker first and locate its outgoing COM port in Device Manager.

Safe workflow

Close JBL Portable on nearby phones first so it does not compete for the connection.

vantactl scan
vantactl services --address DEVICE_FROM_SCAN
vantactl probe --address DEVICE_FROM_SCAN
vantactl models
vantactl models 20e3
vantactl check-update

Known default BLE values extracted from the APK:

service  65786365-6C70-6F69-6E74-2E636F6D0000
RX       65786365-6C70-6F69-6E74-2E636F6D0001
TX       65786365-6C70-6F69-6E74-2E636F6D0002

Some products derive a service UUID from PID/MID. Use services to discover it, then pass --service, --rx, and --tx overrides if necessary.

Read legacy and Protocol 4 EQ without changing the speaker:

vantactl get-simple --address DEVICE
vantactl get-advanced --address DEVICE
vantactl get-p4-eq --address DEVICE

EQ and sound profiles

Mutating commands only print the encoded TX packet unless --apply is supplied. The recommended path is PID-aware routing:

vantactl set-auto --pid 20e3 5 3 -2.5 -3 -2 -.5 1
vantactl set-profile --pid 20e3 bass
vantactl set-profile --pid 20e3 clear --address DEVICE --apply
vantactl profiles

set-auto chooses legacy simple, advanced-level, legacy parametric, Protocol 4 0E02, or Grip-style 0E7F from the APK-derived model profile. It refuses products for which the APK does not declare EQ support.

Included profiles cover Flat, Balanced, Bass Heavy, Deep Bass, Punch Bass, Warm, Loudness, Crystal Clear, Bright, Detail Monitor, Vocal, Podcast, Acoustic, Rock, Metal, Hip-Hop, EDM, Pop, Jazz, Classical, Cinema, Gaming, Outdoor, and Night. See Sound profiles.

Examples for direct codec control:

# Legacy 3-band signed levels
vantactl set-simple --bass 4 --mid 1 --treble -1

# Legacy advanced signed levels
vantactl set-levels 3 2 1 0 -1 -2 -3

# Legacy parametric bands: type,frequency,gain,q
vantactl set-parametric `
  "low-shelf,125,3,0.7" `
  "peaking,250,2,2" `
  "peaking,500,0,2" `
  "peaking,1000,-1,2" `
  "peaking,2000,0,2" `
  "peaking,4000,1,2" `
  "high-shelf,8000,2,0.7"

# Charge 6 custom-band order: 125, 250, 500, 1k, 2k, 4k, 8kHz
vantactl set-charge6 5 3 -2.5 -3 -2 -.5 1

Filter types are low-shelf, peaking, high-shelf, low-pass, and high-pass. Charge 6 custom band 1 supports -9..+6 dB with asymmetric negative quantization; bands 2-7 support -6..+6 dB in 0.5 dB steps, matching the APK UI mapping.

Capture, decode, and expert mode

vantactl listen --address DEVICE --seconds 15 --log capture.log
vantactl decode "AA9800"
vantactl raw "AA6C00"
vantactl raw "AA6C00" --address DEVICE --apply --i-understand

Raw transmission requires both --apply and --i-understand. No OTA, authentication bypass, factory reset, destructive command, or amplifier/limiter overclock path is implemented.

For Bluetooth Classic SPP, use an outgoing COM port instead of a BLE address:

vantactl raw "AA6C00" --port COM7 --apply --i-understand

Python API

from vantadsp.protocol import build_simple_eq_set, parse_legacy_frame

packet = build_simple_eq_set(bass=4, mid=1, treble=-1)
frame = parse_legacy_frame(packet)
print(packet.hex(), frame)

Protocol builders perform no Bluetooth I/O, so they are deterministic and reusable. Real transmission is isolated in vantadsp.transport; applications should retain an explicit safety confirmation layer.

Documentation

Quality assurance

ruff format --check .
ruff check .
mypy src/vantadsp
pytest
bandit -q -c pyproject.toml -r src/vantadsp
pip-audit .
python -m build
twine check dist/*

GitHub Actions tests Windows and Linux on Python 3.10 and 3.12 with coverage, linting, typing, security, and package validation. APK/XAPK files, decompilation output, captures, local configuration, and audit logs are excluded from version control.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vantadsp-0.2.2.tar.gz (63.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vantadsp-0.2.2-py3-none-any.whl (48.0 kB view details)

Uploaded Python 3

File details

Details for the file vantadsp-0.2.2.tar.gz.

File metadata

  • Download URL: vantadsp-0.2.2.tar.gz
  • Upload date:
  • Size: 63.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for vantadsp-0.2.2.tar.gz
Algorithm Hash digest
SHA256 ba3f51dfe017f073526c28616f8d844360bb783331e24c6b6a99d11af4adf26a
MD5 9564bb463c2884a3ca95f522e91c1681
BLAKE2b-256 d33b8ad6fa760f668a5de0d3757685574c04b5fe62daefe6dce302dd62888898

See more details on using hashes here.

File details

Details for the file vantadsp-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: vantadsp-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 48.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for vantadsp-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f38c69db4e98ed5f4448ad95a8df123e534d629cc5ec254dad206bcf29604c8b
MD5 4a50eb665124c0d79e22d47d73dfa0ce
BLAKE2b-256 53a20d5d54ebc9a1111151a4544a4d2a8746e6f9e378b67b3bc5d59fab93e90f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page