Repository navigation
Conversation
Replace the fixed, captured packets with an implementation of the protocol the headset actually speaks: requests are built from command, key and value, split into HID reports, and matched against the reply the headset sends back. Errors reported by the headset now reach the user instead of being ignored. Maxwell and Maxwell 2 share this code through a new AudezeMaxwellDevice base class, so each device file only holds what differs between them. Add custom equalizer support for the original Maxwell. The ten band gains (-12 to 12 dB, whole steps) are written to the selected custom preset, applied immediately and stored on the headset. Also: - fix sidetone being toggled on every call instead of set - report the current sidetone level - round inactive time up to the nearest value the headset supports - add protocol tests, including EQ coefficient reference vectors
|
With the help of AI, I reverse-engineered the protocol used by the Audeze app and reimplemented it here, replacing the previous captured packets. I could only test on my own original Maxwell, so I'd appreciate help validating: @MonsterBagels, could you please check that nothing broke on the Maxwell 2? It now shares the protocol code with the original Maxwell, and I have no Maxwell 2 to test on. @Nallebeorn, could you please test on your Maxwell as a second confirmation? What to try:
|
Removed information about original Audeze Maxwell EQ edits.
|
I can't help unfortunately, as I've sold my Maxwell 2 but good luck! |
|
@AdrianKuriata could you please check that nothing broke on the Maxwell 2? |
|
Tested with my own (original) Maxwell (I don't have the 2 either), seems good!
I did have to unplug and reinsert my dongle after installing this commit before any command worked (otherwise every operation timed out). |
Sapd
left a comment
There was a problem hiding this comment.
Checked the #577 packet: gone. The whole init sequence is removed and nothing writes key 0x25, so the imbalance can't come back. Setter bodies are byte-identical to master.
On Maxwell 2 - master's two device files differ by exactly one command, the volume limiter (0x28, 0x88/0x8e), which the 2 doesn't advertise anyway. The old file was a copy, so keeping it isn't the safety it looks like. Also worth knowing: master's battery read only worked because hid_get_input_report picked up the reply to the previous request. That was timing luck. Sharing the base is the right call, just say in the description that the 2 is untested.
Two things before merge:
-
request() doesn't drain the input queue. If a state read times out and is retried, both replies land and the stale one gets consumed by the next read - setSidetoneEnabled then toggles twice and still reports success, leaving sidetone off. Needs a >400 ms reply so it's unlikely, but it's silently wrong. Read until len 0 before sending.
-
The writeKey ack predicate checks the family byte and key but not byte 4, so a queued read-key reply passes as the write ack. The comment says Audeze.exe is equally loose - do you have evidence that's needed, or can we tighten it?
Cosmetic, and it explains @Nallebeorn's report: the level write silently enables sidetone, so setSidetoneEnabled(true) reads back "on" and never sends the toggle that plays the prompt. Enable before writing the level and "sidetone on" fires. The replug he needed isn't explained by anything in the driver.
Pre-existing: -s 1 maps to device level 0 and switches sidetone off.
Build, tests, clang-format 18 and the README generator are all clean.
Thanks for the review. Changes:
On the "sidetone on" prompt: I tested the primitives on hardware. The level write always switches sidetone on (even with an unchanged level), and every write to param 07 toggles regardless of value. Audeze.exe treats them as two independent controls and sends a single request per action. So setSidetone now does the same: a level > 0 is one level write, and 0 reads the state and toggles once only if it's on, with no read-back loop, since a re-toggle on a late state read was what turned it back off. The trade-off is no "sidetone on" prompt when it's enabled through the level, which matches using the app's slider. Agreed on the replug; nothing in the driver explains it. I'll note in the description that the Maxwell 2 is untested on hardware. |
Writing the sidetone level always switches sidetone on, and every write to the on/off parameter toggles it whatever value is sent. Setting a level now sends only the level write, and level 0 reads the state and toggles once if sidetone is on. The old read-back and retry loop could toggle twice on a late reply, switching sidetone back off and reporting an error. Also: - discard replies still queued in the dongle before each request, so a late reply is not taken for the answer to the next one - accept only a write-key reply for the same key as a write ack - map any non-zero level to at least device level 1 instead of off
|
Hey, I've tested this on Maxwells 2. Everything seems to work except turning sidetone on. Once it's enabled via the headset then changing it's volume behaves correctly. Of course until Some details about the observed behavior (steps executed):
|
…uests like the Audeze app Writing the sidetone level switches an original Maxwell on, but leaves a Maxwell 2 silent. Like the Audeze app, whose level slider is disabled while sidetone is off, a level above 0 now reads the state, switches sidetone on with one toggle if it is off, and then writes the level. Sending the toggle and the level write back to back crashed the original Maxwell's firmware. Requests are now paced like the Audeze app: 50 ms before each read, up to 1.25 s for a reply, and a write is never sent twice. Without resent writes, the drain before each request is no longer needed.
|
Hey @Michsior14. Tks for testing. Fixed in 2aded04. On the original Maxwell, writing the sidetone level also switches sidetone on. On the Maxwell 2 it apparently only sets the "on" flag without enabling the audio, which is why the first button press announced "sidetone off". The Audeze app never relies on this: its level slider is disabled while sidetone is off, so it always switches sidetone on first.
While testing, my Maxwell's firmware crashed when the toggle and the level write were sent back to back, so I also changed the pacing to match Audeze.exe: 50 ms before every read, up to ~1.25 s for a reply, and writes are never resent (only reads are). With that, 30 on/off cycles ran cleanly. Since writes are no longer resent, I dropped the drain before each request again. Could you test again on the Maxwell 2? If your headset is still in the "on but silent" state, run |
|
@ModoloDev Everything looks good now, thx :) |
Changes made
Replace the fixed, captured packets with an implementation of the protocol the headset actually speaks: requests are built from command, key and value, split into HID reports, and matched against the reply the headset sends back. Errors reported by the headset now reach the user instead of being ignored.
Maxwell and Maxwell 2 share this code through a new AudezeMaxwellDevice base class, so each device file only holds what differs between them.
Add custom equalizer support for the original Maxwell. The ten band gains (-12 to 12 dB, whole steps) are written to the selected custom preset, applied immediately and stored on the headset.
Checklist
Related to #460
The Maxwell 2 is untested on hardware. It uses the same shared code, but I don't own one.