Open tools for the Sony WH-1000XM4 over Bluetooth on Linux: back up and inspect the headset's NVDM settings store, flash official Sony firmware (including downgrades), switch ANC modes, apply EQ presets, and an experimental spatial-audio prototype. The goal is to grow this into a toolkit for other Sony headphones built on the same Airoha-based platform.
Unofficial project. Not affiliated with, endorsed by or supported by Sony. Use at your own risk: writing to a headset can damage it and may void your warranty.
Every claim in this repository is graded by evidence in docs/STATUS.md (device-verified, user-reported, simulation only, unverified, contradicted). Read it before you write anything to a device.
| Feature | Command | Status |
|---|---|---|
| Back up the 512 KiB NVDM store over Bluetooth | python3 tools/backup_nvdm.py |
Device-verified |
| Parse a dump (all items, checksums, name hashes) | python3 -m xm4_optimizer parse <dump.bin> |
Device-verified on a real dump |
| Flash official Sony firmware, e.g. downgrade 3.0.1 → 2.5.0 | python3 tools/flash_firmware.py --mac <MAC> --firmware <file.bin> |
Device-verified in both directions between 2.5.0 and 3.0.1 (test record) |
| Read firmware version, battery and ANC mode | python3 -m xm4_optimizer status |
Device-verified |
| Switch noise cancelling / ambient / wind / off | python3 -m xm4_optimizer anc nc|ambient [--level 1-20] [--voice]|wind|off|status |
Device-verified, with readback |
| EQ presets for EasyEffects and Equalizer APO | presets/ |
Ready to use |
| ANC filter synthesis and dry-run | python3 -m xm4_optimizer --mock --dry-run |
Simulation only |
inject / verify / rollback of ANC filters |
— | Disabled on hardware. Their storage model is contradicted by a real dump (details). They run with --mock only. |
| Spatial audio (AeroSpatial: PipeWire + Steam Audio) | see aerospatial/pipewire/README.md | Experimental; failed its first listening test |
| Custom voice prompt packs | — | Planned (Roadmap) |
- Linux with BlueZ (
bluetoothctl), Python 3.10+,numpy. - The headset paired and connected.
- At least 50% battery, the headset within about 1 m of the adapter, and audio playback paused before long transfers. Do not power off the headset during a write.
git clone https://github.com/randwardatake/wh1000xm4-anc-optimizer.git
cd wh1000xm4-anc-optimizer
pip install numpy
bluetoothctl devices | grep -i "WH-1000XM4" # note the MAC addresspython3 tools/backup_nvdm.py --mac <MAC> --out my_xm4_nvdm.bin
python3 -m xm4_optimizer parse my_xm4_nvdm.binThe backup writes a .sha256 file next to the dump. Keep both.
Do not post your dump publicly. It contains your headset's Bluetooth address and serial number, and the pairing records of your phones and computers (BT/paired_*). See privacy.
The flasher sends an official, Sony-signed firmware image over RFCOMM using the Airoha FOTA sequence. The headset checks the image (0x1C01) before it commits and reboots. This project does not host Sony firmware.
Where to get v2.5.0. The image used on the test device comes from the community archive lzghzr/MDR_Proxy, which mirrors files from Sony's update server (info.update.sony.net):
firmware/2943/MDRID294300/UPG_2.5.0_20210413_enc.97529f0f6630238e77ce76bfc6766aa5616e78e7.bin
SHA-1 97529f0f6630238e77ce76bfc6766aa5616e78e7
SHA-256 ee2a4b60c5f322d56fd9e6ea51778cbbc847f816781c385f40d45959555ac508
The flasher checks the file's SHA-256 against the five known official WH-1000XM4 images (2.5.0, 2.6.0, 2.7.1, 2.9.0, 3.0.1, listed in xm4_optimizer/firmware.py) and refuses anything else. You can also check it yourself:
sha256sum UPG_2.5.0_20210413_enc.*.bin
python3 tools/flash_firmware.py --mac <MAC> --firmware UPG_2.5.0_20210413_enc.97529f0f6630238e77ce76bfc6766aa5616e78e7.binMDRID294300 is the WH-1000XM4. Do not flash it onto any other model. The owner reported stronger ANC and no hiss after downgrading to 2.5.0; that is a listening report, not a measurement.
| File | Use |
|---|---|
presets/Sony WH-1000XM4 (ANC on) ParametricEq_EASYEFFECTS.txt |
AutoEq parametric EQ for the WH-1000XM4 with ANC on, EasyEffects import format |
presets/Sony WH-1000XM4 (ANC on) ParametricEq_EQAPO.txt |
The same EQ for Equalizer APO (Windows) |
presets/Sony_WF-1000XM4_SuperReview_3D_Spatial.json |
EasyEffects preset (EQ + crossfeed + stereo tools) built on the WF-1000XM4 Super Review target, which the owner preferred by ear on the WH-1000XM4 |
presets/Sony_WF-1000XM4_ANC_on_SuperReview_EQ.txt |
The WF-target EQ for Equalizer APO |
EasyEffects (Flatpak):
cp presets/Sony_WF-1000XM4_SuperReview_3D_Spatial.json ~/.var/app/com.github.wwmm.easyeffects/data/easyeffects/output/
flatpak run --command=easyeffects com.github.wwmm.easyeffects -l Sony_WF-1000XM4_SuperReview_3D_SpatialAeroSpatial places the left and right channels on two virtual speakers using an HRTF (Valve Steam Audio). It is stereo virtualization: it cannot recover instrument positions or height from a stereo recording, and it does not decode Sony 360 Reality Audio or Dolby Atmos. The first live Spotify test sounded muffled and collapsed to the center. Fixes are in place but have not passed a new listening test. See the Linux notes, the roadmap and the literature review.
| Document | Content |
|---|---|
| docs/STATUS.md | Evidence ledger for every claim |
| docs/HARDWARE_AND_NVDM.md | NVDM format verified against a real dump |
| docs/WIRE_PROTOCOLS.md | Sony MDR (RFCOMM 11) and Airoha RACE (RFCOMM 21) framing |
| docs/DSP_ACOUSTIC_THEORY.md | Filter math behind the simulator |
| docs/SPATIAL_ROADMAP.md | Spatial audio plan and acceptance gates |
| docs/research/ | Linux, Windows, Android, Sony 360RA and literature notes |
xm4_optimizer/ Python package and CLI (python3 -m xm4_optimizer)
transport/ MDR and RACE framing, RFCOMM sockets, in-memory device emulator
nvdm/ NVDM parser (validated on a real dump); cxd90050.py holds the unverified biquad model
dsp/ Q4.28 fixed point, biquad synthesis, stability checks, frequency response
safety/ dry-run, injector, verifier, rollback (emulator only, see STATUS)
tools/ backup_nvdm.py, flash_firmware.py, Steam Audio download and PipeWire scripts
aerospatial/ C++ spatial audio prototype (Steam Audio + PipeWire)
presets/ EQ presets
tests/ 430 Python tests (emulator, parser fuzzing, DSP); C++ tests live in aerospatial/tests
docs/ Documentation
pip install pytest numpy
python3 -m pytestThe tests run against an in-memory emulator. Passing tests do not show that a write path works on a real headset.
- Repository hygiene (done 2026-10-26): English documentation, evidence ledger, write commands disabled on hardware, licence fixed.
- Device-proven tools into the package: move the tested backup and flash code paths into the library, check firmware files against known hashes, and add voice-pack commands (extract, build, install) using the same upload sequence as Sony's app (fix-whxm4-voice documents it).
- More Sony models: per-model profiles, a dump → partition extraction → redaction workflow so owners can share data safely, and a contributor guide for forks.
- Apps: Linux, Windows and Android front ends on a shared core. On Android, features that need root are listed in the normal app and marked "root only".
GPL-3.0-or-later, see LICENSE. Third-party components keep their own licences: Valve Steam Audio (Apache-2.0) is downloaded separately by tools/download_steamaudio.py and is not part of this repository.