Skip to content

Fix DB2 audio output: 48kHz, 512-byte interrupt sub-packets, 7× SET_CUR#70

Draft
soulcheck wants to merge 1 commit intomischa85:mainfrom
soulcheck:fix/db2-48khz-512b-subpackets
Draft

Fix DB2 audio output: 48kHz, 512-byte interrupt sub-packets, 7× SET_CUR#70
soulcheck wants to merge 1 commit intomischa85:mainfrom
soulcheck:fix/db2-48khz-512b-subpackets

Conversation

@soulcheck
Copy link
Copy Markdown

@soulcheck soulcheck commented Apr 18, 2026

Summary

Fixes audio output on Allen & Heath Xone:DB2 (PID 0xFFD2). Three mismatches vs the working Windows driver were found via USB traffic analysis, plus two HAL correctness fixes discovered during debugging.

1. Sample rate: 96kHz → 48kHz

The DB2 requires 48kHz (0x00BB80). The device's power-on default is 44100Hz. Sending 96kHz causes the device to accept the rate at the USB level but run its DAC at 48kHz regardless, producing audio at half speed.

2. Interrupt sub-packet format: 482 bytes → 512 bytes

The previous format split 10 samples around the MIDI bytes: [432 PCM][2 MIDI][48 PCM] = 482 bytes. The correct format — confirmed by observing Windows driver URBs (14 × 512 = 7168 bytes on interrupt EP 0x05) — is identical to bulk: [480 PCM][2 MIDI][30 pad] = 512 bytes. All 10 samples are contiguous before MIDI.

3. SET_CUR sequence: 2 calls → 7 calls

We sent one SET_CUR to EP 0x86 and one to EP 0x05. The Windows driver sends 7 alternating calls — IN, OUT, IN, OUT, IN, OUT, IN (4× EP 0x86, 3× EP 0x05). Without the full sequence the device's PLL does not lock and produces no output.

4. Channel layout: UseChannelDescriptions → MPEG_7_1_A

kAudioChannelLayoutTag_UseChannelDescriptions with kAudioChannelLabel_Unknown descriptors caused CoreAudio to silence stereo sources — no label matched. kAudioChannelLayoutTag_MPEG_7_1_A assigns standard L/R labels to the first two channels, allowing stereo playback to route correctly.

5. WriteMix willDoInPlace: true → false

With willDoInPlace=true, CoreAudio mixed audio into its own internal buffer and passed that pointer to our operation — leaving zeros in the ring buffer. Setting willDoInPlace=false tells CoreAudio to provide a separate pre-mixed float PCM buffer.

6. Timestamp hostTime initialisation

The timestamp struct was only zeroing sampleTime on start. Left uninitialised, hostTime=0 caused CoreAudio to treat the clock as starting at boot and flood the ring buffer trying to catch up. Now initialised to the current host time via mBus->GetTime().

Test plan

  • Plug in Allen & Heath Xone:DB2
  • Load kext and HAL, verify device appears in System Preferences → Sound
  • afplay a stereo file — audio should play through the mixer's main output at the correct pitch and speed
  • Confirm no startup beep (was caused by the wrong sample rate)

USB traffic analysis of the working Windows driver reveals three
mismatches between our driver and the device's requirements:

1. Sample rate: we sent 96kHz; device requires 48kHz (0x00BB80).
   The device accepts the rate at the USB level but runs its DAC
   at 48kHz regardless, producing audio at half speed.
   Fixed in PloytecEngine::Start() and OzzyHAL nominal rate.

2. Interrupt sub-packet format: we used 482-byte sub-packets
   (432 PCM + 2 MIDI + 48 PCM, split around MIDI). The device
   expects 512-byte sub-packets identical to bulk format
   (480 PCM contiguous + 2 MIDI + 30 pad). Confirmed by Windows
   URBs: 14 × 512 = 7168 bytes on interrupt EP 0x05.
   Fixed PLOYTEC_INT_OUT_SUBPKT_SIZE/PKT_SIZE and the interrupt
   encoder/clear functions in PloytecCodec.mm.

3. SET_CUR sequence: we sent 2 calls (1× IN, 1× OUT); Windows sends
   7 calls alternating IN/OUT starting with IN (4× EP 0x86, 3× EP
   0x05). Without the full sequence the device's PLL does not lock.
   Fixed in PloytecEngine::SetHardwareFrameRate().

Also add LogPloytec/LogOzzyKext stubs to the userspace branch of
OzzyLog.h so clangd can resolve the macros in PloytecEngine.cpp.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@soulcheck soulcheck force-pushed the fix/db2-48khz-512b-subpackets branch from 45bff6a to c2c3ccc Compare April 18, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant