Browse by type
Use the motion sensors already inside compatible Sony headphones and earbuds as a real-time head tracker on Windows.
Unofficial open-source Windows bridge. Not affiliated with or endorsed by Sony.
Sony Head Tracker connects to the Android Head Tracker sensor exposed by supported Sony Bluetooth devices, reads live orientation and gyroscope data, and sends yaw, pitch, and roll to OpenTrack or your own applications.
No webcam, infrared tracker, additional hardware, firmware modification, or custom kernel driver is required.
Originally developed and tested for the Sony WH-1000XM5, the project now supports any compatible Sony headset that exposes the standard Android Head Tracker HID protocol.
If you arrived searching for Sony WH-1000XM5 head tracking on Windows, how to use WH-1000XM5 with OpenTrack, or an XM5 head tracker for Assetto Corsa or other sims, you are in the right place: the WH-1000XM5 is the reference device, and the same bridge now works across the wider Sony range.
sony-head-tracker.exe from the
latest release
(or build it yourself, it is one cl command).4242, then press Start. See OpenTrack.4243. See
docs/PROTOCOL.md.Hardware status: changing orientation reports have been received and parsed from a physical WH-1000XM5. Behaviour varies with Sony firmware and the Windows Bluetooth stack. This project never spoofs another headset, changes Bluetooth identities, or modifies firmware.
Compatibility is determined by the protocol exposed by the headset, not simply by
the Sony model name. A device is compatible when it exposes an Android Head
Tracker HID sensor with the expected #AndroidHeadTracker# descriptor (usage
0x0020:0x00E1).
The underlying engine is protocol-based, although the project is currently focused on testing and supporting Sony headphones. In practice that means compatible Sony headphones, with experimental support for other devices using the same protocol.
You can check any device in seconds, with zero risk. Pair the headphones, then run:
sony-head-tracker.exe probe
probe is read-only. It never writes to the device, changes drivers, or touches
firmware. If it finds a verified Android head tracker it prints the descriptor
and exits 0. If not, it lists what it saw and exits 2.
Reports for both working and non-working devices are welcome. Please
open an issue
with the probe output and your Windows and firmware versions, and the table
below will be updated.
| Device | Reported by |
|---|---|
| Sony WH-1000XM5 | maintainer, tested |
| Sony WH-1000XM6 | community confirmed |
| Sony WF-1000XM6 | community confirmed |
| Sony ULT WEAR (WH-ULT900N) | community confirmed |
Sony lists these models as supporting head tracking, but they still require community testing with this Windows implementation. Please do not assume they are already validated.
A candidate model may still need the latest firmware before the sensor appears. Install Sony's Sound Connect app, connect the headphones, and update before probing.
| Device | Status | Reported by |
|---|---|---|
| Sony WH-1000XM4 | Does not work | community confirmed |
| Sony WH-1000XM3 | Not expected to work | not on Sony's head-tracking list |
| Apple AirPods (all models, including AirPods Pro) | Not possible on Windows | see Why AirPods can't work |
Models that are not on Sony's head-tracking list almost certainly carry no usable sensor. Bose QuietComfort Ultra models do head-tracked spatial audio and might one day expose a compatible protocol, but that is unverified and out of scope for now.
AirPods absolutely have the motion sensors, but Apple does not implement the
Android Head Tracker HID protocol. Head tracking (and ANC control, ear detection,
and so on) travels over Apple's proprietary accessory protocol (AAP) on a raw
Bluetooth Classic L2CAP channel (PSM 0x1001). Two hard blockers follow:
What this bridge does instead: it recognises paired AirPods and tells you
exactly this, in probe, in bridge, and in the GUI, instead of failing
silently. If Windows ever exposes user-mode L2CAP, or a maintained open AAP bridge
appears, an AirPods backend becomes feasible and contributions are welcome.
In bridge mode (and while the GUI is open) head-tracking data is streamed over
UDP to loopback (127.0.0.1) on two adjacent ports:
| Port | Format | Consumer |
|---|---|---|
4242 (--port) |
Six little-endian doubles (x, y, z, yaw, pitch, roll) |
OpenTrack "UDP over network" |
4243 (--port + 1) |
UTF-8 JSON object (see below) | Your own apps and scripts |
Change the base port with --port N. The JSON port is always N + 1. The bridge
prints both destinations on startup, and the GUI shows them along the bottom edge.
Translation axes (x, y, z) are always zero, because this protocol reports
orientation only.
The JSON datagram (one per sample, version: 2):
{
"version": 2,
"device": "WH-1000XM5", // connected headset's Bluetooth name, or null
"rotationVector": [x, y, z], // axis-angle, radians
"quaternion": [w, x, y, z], // recentered orientation
"yprDegrees": [yaw, pitch, roll], // degrees
"gyroscope": [x, y, z], // rad/s, or null if unavailable
"accelerometer": [x, y, z], // m/s^2, or null if the device doesn't report it
"angularVelocity": [x, y, z], // deprecated alias of "gyroscope"
"resetCounter": 0,
"packetsPerSecond": 25.0,
"receiveLatencyMs": -1.0 // -1 when the device provides no timestamp
}
Security: UDP output is loopback-only by default and has no authentication. Do not bind or forward it to an untrusted network.
A full wire-format reference lives in docs/PROTOCOL.md.
Both inertial streams are exposed in full, in addition to orientation:
gyroscope
array (and shown live in the GUI). This is the connected headset's on-board gyro
as carried by the Android Head Tracker protocol.accelerometer array when the device reports it.The Android Head Tracker HID profile that supported Sony firmware advertises
defines only orientation and gyro fields, so on current firmware
accelerometer is typically null. The bridge nonetheless parses the standard
HID sensor-page acceleration usages (0x0453 to 0x0455, plus the vector form
0x0452) from every input report, so if your firmware exposes them they are
surfaced automatically, with no code change needed. Gyro is likewise parsed from
both the head-tracker custom field (0x0545) and the standard sensor-page
usages.
The default axis convention is YXZ order with the X and Z axes inverted, the mapping that produces correct head tracking on the WH-1000XM5. It is fully overridable:
--axis-map XYZ (any permutation) and --invert X (any axes). The
--invert flag is a complete override: --invert xz reproduces the default,
--invert z inverts Z only, and --invert none clears all inversions.The same axis convention is applied to the gyroscope and accelerometer vectors so all streams share one coordinate frame.
Requires a C++20-capable MSVC and a current Windows 11 SDK (install Desktop development with C++ in the Visual Studio Installer).
build.cmd
build.cmd locates the Visual Studio C++ tools automatically. Or build by hand
from a x64 Native Tools Command Prompt for VS:
rc /nologo app.rc
cl /std:c++latest /EHsc /permissive- /utf-8 /O2 /W4 /DUNICODE /D_UNICODE /I include src\*.cpp app.res /Fe:sony-head-tracker.exe
The code is split into a hardware-independent core under
include/sony_head_tracker/ +
src/ (quaternion maths, HID descriptor decoding, the orientation
filter, and protocol serialisation — all Windows-free) and a platform layer (HID
and Sensor API backends, Bluetooth repair, UDP output, and the GUI). Every backend
produces a normalized MotionSample, so recenter, smoothing, axis mapping, Euler
conversion, and serialisation are all unit-testable without a headset — see
tests/ and run them with build-tests.cmd. A small resource bundle
(app.rc: icon, version info, and the Common Controls manifest) is
embedded at build time; the icon is generated by
tools/make-icon.ps1 and committed as app.ico. All
required import libraries are pulled in via #pragma comment(lib, ...), so the
executable stays dependency-free with no extra linker arguments. The build is
warning-clean at /W4. Every push is built and unit-tested in CI on
windows-latest, and pushing a v* tag publishes the exe as a GitHub Release.
See .github/workflows/build.yml.
sony-head-tracker.exe probe. A usable collection shows usage
0x0020:0x00E1 and a feature description beginning with #AndroidHeadTracker#.```text sony-head-tracker.exe (no args -> diagnostics GUI) sony-head-tracker.exe probe [--include-disabled] sony-head-tracker.exe dump [--seconds N] sony-head-tracker.exe repair sony-head-tracker
$ claude mcp add sony-head-tracker \
-- python -m otcore.mcp_server <graph>