Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .claude/re/open_questions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

## Open Questions

### Interrupt output path has the same half-packet bug as bulk (UNFIXED)
`ploytec_int_subpackets[]` covers 40 frames / 1928 bytes, but
`PLOYTEC_INT_OUT_PKT_SIZE` is 3856 (= 2 x 1928) and
`ploytec_process_out_int()` reports `PLOYTEC_FRAMES_PER_PKT` (80) frames
consumed per packet. So half of every interrupt packet's audio is pulled
from the ALSA ring and dropped, exactly as the bulk path did before it was
fixed. Affects Xone:DB4 on firmware 1.4.1+ (which exposes interrupt
endpoints instead of bulk).

The layout repeats every 1928 bytes / 40 frames, so the fix is mechanical:
duplicate the five groups and four MIDI slots at +1928 bytes / +40 frames
and bump `PLOYTEC_INT_NUM_SUBPACKETS` to 10 and
`PLOYTEC_INT_NUM_MIDI_SLOTS` to 8. Left undone because no interrupt-mode
hardware was available to verify it.


### Sample rate change: 5-call dance vs official driver
Our driver sends SET_CUR 5 times alternating 0x86/0x05 (from Windows USB capture). The official
macOS driver only calls `setFrequency` once per pipe (2 total: input + output). The 5-call
Expand All @@ -28,6 +44,23 @@ related to level metering or some control protocol. Has its own pipe assignment

## Resolved (moved from questions)

- ~~Junction encoder vs our bit-interleaved codec~~ — The bit-interleaved
codec in `ploytec_codec.c` is correct for bulk devices. Confirmed by
playing tones through a Reloop DJ2 ME (200c:1009) from userspace: plain
3-byte packing produces noise, the bit-interleaved 48-byte frame produces
a clean tone. The `pcmTo24Junction*` encoders belong to the **isoc** path
(`chooseISOOutEncoder`), which bulk devices never execute — an easy trap
when reading the Windows driver.
- ~~Bulk output packet coverage~~ — `ploytec_bulk_subpackets[]` and
`ploytec_bulk_midi_slots[]` only described 4 sub-packets (40 frames /
2048 bytes) while `PLOYTEC_FRAMES_PER_PKT` is 80 and
`PLOYTEC_BULK_OUT_PKT_SIZE` is 4096. `ploytec_process_out_bulk()` reported
80 frames consumed per packet, so half of every packet's audio was pulled
from the ALSA ring and silently dropped, and bytes 2048-4095 were never
filled. Heard as broadband distortion at all frequencies. Both tables now
cover all 8 sub-packets. **This affected the Xone devices too, not just
the Reloop.**

- ~~Vendor request 'A'~~ — Now understood: ESU clock config (wIndex=0x101) and Wolfson codec (wIndex=0x102/0x106)
- ~~Index 2 digital output selector~~ — Write-only, `AjExtData[4] & 0xFFFF`, only for devices with `this[0x7AC]`
- ~~setEsuCpldByte~~ — Writes to 'I' wIndex=1 with `| 0xE7` mask
Expand Down
52 changes: 45 additions & 7 deletions .claude/re/ploytec_device_table.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,51 @@ The `setFrequency` function retries the SET_CUR request up to 200 times for thes
|---------|-------------|-------|
| 0x0019 | ? | `setFreqOnOutPipe` support only |

## VID 0x200C (unknown vendor)

| USB PID | Device Name | Notes |
|---------|-------------|-------|
| 0x1007–0x1027 | ? | Range with bitmask in `setFreqOnOutPipe` |
| 0x1019 | ? | Returns early from `updateAjInputSelector` with status 0x12 |
| 0x1030 | ? | Uses SET_INTERFACE (bRequest 0x0B) in `configurationDone` |
## VID 0x200C (Reloop / Hanpin)

| USB PID | Device Name | Channels | Rate | Notes |
|---------|-------------|----------|------|-------|
| 0x1005 | ? | 4 in / 4 out | 96000 | From `findInterfacesInConfig` fallback table |
| 0x1006 | ? | 6 in / 6 out | 44100 | HS=6in+6out, FS=2in+2out |
| 0x1009 | **Reloop Digital Jockey 2 Master Edition** | **6 in / 4 out** | **44100** | Confirmed on hardware, see below |
| 0x1019 | ? | 6 in / 4 out | 44100 | Same config block as 0x1009. Returns early from `updateAjInputSelector` with status 0x12 |
| 0x1037 | ? | 6 in / 4 out | 44100 | Same config block as 0x1009 |
| 0x100A | ? | 2 in / 10 out | 44100 | |
| 0x103E | ? | 4 in / 4 out | 44100 | 16-bit (`0x10`), not 24 |
| 0x1007–0x1027 | ? | | | Range with bitmask in `setFreqOnOutPipe` |
| 0x1030 | ? | | | Uses SET_INTERFACE (bRequest 0x0B) in `configurationDone` |

### 0x1009 — Reloop Digital Jockey 2 ME (confirmed on hardware)

Supported in Ozzy via `linux/devices/reloop_dj2.c`.

- **6 in / 4 out, 24-bit, 44100 Hz only.** Every 200c:1009 branch in
`findInterfacesInConfig` hardcodes `0xAC44`; only the sibling 0x1005 gets
96 kHz. Running this DAC at 96 kHz audibly distorts playback, so the rate
list is restricted to a single entry.
- **Bulk transport**, standard Ploytec framing: EP 0x05 out, 0x86 in,
0x83 MIDI in. 48-byte bit-interleaved wire frames, MIDI embedded one
byte per sub-packet at offset 480 with 0xFF sync at 481.
- **USB pacing is NOT required** (earlier belief retracted). 25+ userspace
iterations with no delay anywhere — between the two alt-setting changes,
before the first control request, or between handshake requests — all
completed cleanly, in either SET_CUR order. The one kernel probe that hung
the machine ran with an invalid `clear_halt` on the isochronous endpoint
0x02 and a 96 kHz default rate, both since fixed; those are the likely
cause. The driver keeps a short precautionary delay inside its own init
path only, costing ~1 s at probe and touching no shared code.
- **Capture channel map** (matches the manual's "Input Routing"), verified
by loopback: in 0/1 = Line In 1, in 2/3 = Line In 2, in 4/5 = Mic,
in 6/7 = unused/silent.
- **MIDI output requires explicit status bytes.** The firmware silently
ignores messages sent with MIDI running status. Mixxx emits one 0x90 and
then dozens of bare note/velocity pairs; confirmed by logging the
outbound stream (149 bytes, exactly one status byte). Symptom is MIDI
input working perfectly while no LED ever lights. The driver reassembles
running-status messages before embedding them.
- Analogue channel strips only reach the digital side when the front-panel
MIDI/Phono-Line switch is in the MIDI position; in Phono/Line the fader,
gain and EQ stay in the analogue path and emit no MIDI.

## Creative Technology (VID 0x041E)

Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Ozzy fixes that.
This is an open-source, reverse-engineered driver supporting non-class compliant USB audio interfaces—high-end DJ mixers and audio processors that were left behind when official driver support ended.

**Currently Supported Devices:**
* **Allen & Heath Xone:DB4, DB2, DX, 4D** (Ploytec-based protocol)
* **Allen & Heath Xone:DB4, DB2, DX, 4D, Wizard 4** (Ploytec-based protocol)
* **Reloop Digital Jockey 2 Master Edition** (same Ploytec protocol, DJ controller with integrated 6-in/4-out audio interface)

More devices can be added—the architecture separates the audio engine from device protocols.

Expand Down Expand Up @@ -38,6 +39,8 @@ Ozzy reverses the protocol and provides modern drivers—so your equipment keeps
| **Allen & Heath Xone:DB2** | 8×8 | 44.1/48/88.2/96 kHz | ✅ Perfect |
| **Allen & Heath Xone:DX** | 8×8 | 44.1/48/88.2/96 kHz | ✅ Perfect |
| **Allen & Heath Xone:4D** | 8×8 | 44.1/48/88.2/96 kHz | ✅ Perfect |
| **Allen & Heath Wizard 4** | 8×8 | 44.1/48/88.2/96 kHz | ✅ Perfect |
| **Reloop Digital Jockey 2 ME** | 6×4 | 44.1 kHz | ✅ Perfect (audio, MIDI in/out, LEDs) |

---

Expand Down
1 change: 1 addition & 0 deletions linux/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ $(MODULE_NAME)-y := ozzy_core.o \
ozzy_pcm.o \
ozzy_midi.o \
devices/ploytec.o \
devices/reloop_dj2.o \
../common/devices/ploytec/ploytec_codec.o

# To add a new device family, append:
Expand Down
Loading