Skip to content

Instantly share code, notes, and snippets.

@RaphaelWimmer
Last active June 28, 2024 05:34
Show Gist options
  • Save RaphaelWimmer/0d0aab0bb361f6ca721de1896bc26876 to your computer and use it in GitHub Desktop.
Save RaphaelWimmer/0d0aab0bb361f6ca721de1896bc26876 to your computer and use it in GitHub Desktop.
Switch Creative BT-W5 between AptX Adaptive Low Latency and High Quality modes
#!/usr/bin/env python3
# Simple tool to switch the Creative BT-W5 Bluetooth Audio dongle between AptX Adaptive **Low Latency** or **High Quality** mode.
# Of course, only works with Bluetooth headphones that support AptX Adaptive, such as the Tranya X3
# Reverse engineered based on communication between Creative's desktop app for Windows and the BT-W5.
# Might also accidentally overwrite other settings as a whole config data array is sent without taking into account the existing config.
#
# Usage: sudo ./btw5-switch.py ll (for low-latency mode)
# sudo ./btw5-switch.py hq (for high-quality mode)
#
# requires either sudo or adjusting the permissions on the /dev/bus/usb/... device
import sys
import usb.core # requires PyUSB (e.g. via `apt install python3-usb` on Debian)
dev = usb.core.find(idVendor=0x041e, idProduct=0x3130)
if dev is None:
raise ValueError('Device not found')
cfg = dev[0]
intf = cfg[(0, 0)]
ep = intf[0]
i = intf.bInterfaceNumber
if dev.is_kernel_driver_active(i):
dev.detach_kernel_driver(i)
data_hq = [0x03, 0x5a, 0x6b, 0x03, 0x0a, 0x03, 0x40] # HQ
data_ll = [0x03, 0x5a, 0x6b, 0x03, 0x0a, 0x03, 0x20] # LL
if len(sys.argv) > 1 and sys.argv[1] == "hq":
data = data_hq
print("Enabling AptX Adaptive High Quality mode")
else:
data = data_ll
print("Enabling AptX Adaptive Low Latency mode")
data += [0x00] * (65 - len(data))
result = dev.ctrl_transfer(0x21, 0x09, wValue=0x203, wIndex=0x00, data_or_wLength=data)
@Atomique
Copy link

Hey, love your script, as it helps me out to get this thing working on Linux without an app. Do you know the data of the "call mode" with the red LED and could maybe add it here? That would be pretty neat!
Regards atomique

@RaphaelWimmer
Copy link
Author

Do you know the data of the "call mode" with the red LED and could maybe add it here?

Not right now, unfortunately. I will try to check this next weekend.

@Atomique
Copy link

How did you reverse engineer this? Maybe I can help you out to extend it!

@RaphaelWimmer
Copy link
Author

Sorry for the late reply and thanks for the offer. I don't own a BT-W5 at the moment (it belongs to my son), so I have limited opportunity to refine the script. However, I have logged and annotated the USB traffic for switching to/from HFP mode.
I have also added some limited information on how to add support for it and other features to the script.
It should be relatively straightforward - but I'm not sure when I'll find the time to implement/test it.
Feel free to try it!

See here: https://github.com/RaphaelWimmer/btw5-switch

@Atomique
Copy link

No stress! Thanks a lot for your commit! If I have some sparetime I will try to find out more and hopefully can contribute somethingwith value here!

@JanProchy
Copy link

By any chance - can this work on windows? :)

@RaphaelWimmer
Copy link
Author

By any chance - can this work on windows? :)

It should, as long as you install pyusb and libusb (see installation instructions at https://github.com/pyusb/pyusb).
Haven't tested it there, however.
Why would you want to do this, given that there is an official app for Windows?

@JanProchy
Copy link

My goal is to make an auto-switch so when you start some game, it will auto switch to LL, and after exit back to HQ.. And also i would love to make some hotkeys fot it..

I was trying to convert the script to power shell, but it is such a pain. I will try the python and let you know.. Ty :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment