DJM-REC is never coming to Android, so I built an alternative from scratch

Hi folks, brand new to this forum, but not to DJing. I have been a DJ in one form or another for 30 years, and been playing on House in Portland on Pioneer gear for the last 15 years or so.

It’s always bothered me how Pioneer has said they won’t support Android. I started writing code a few years ago and early last year started tinkering with reading USB descriptors from Pioneer my V10. Fast forward to now and countless hours later, I finally am ready to talk about something I am very proud of: Set Recorder Pro. It’s not vibe coded, however I have used AI to help me parse the USB data and to help me troubleshoot bugs. As far as I know, its the only Android app compatible with Pioneer mixers. This is the build log.

What it does first: it records off the mixer’s USB port to an Android phone, each source as its own track, and it works across Pioneer / AlphaTheta DJMs and class-compliant USB mixers. Here it is pulling 6 stereo pairs, 12 channels at once, live, off a DJM-V10: setrecorderpro.com/assets/hero.mp4

The wall everyone hits. USB audio is isochronous. Android’s standard USB host API gives you control and bulk transfers, and that is it. There is no isochronous support in UsbDeviceConnection, so with the stock API you cannot pull an audio stream off the mixer at all. That is the real reason this has been iPhone-only for so long. Android can do it. The friendly API just stops right before the part you need.

Going around it. So the app does not use the stock API for capture. It opens the device, then talks to the kernel’s usbfs layer directly, submitting and reaping isochronous URBs through USBDEVFS_SUBMITURB and USBDEVFS_REAPURB ioctls on the raw file descriptor. It is a small USB-audio capture driver living inside the app. It manages its own URB pool, keeps the isochronous stream primed, and hands the raw PCM up to the app. Timestamps are taken in nanoseconds the instant a URB is reaped, so the timing stays honest.

Not hardcoded to Pioneer. I did not want a Pioneer/AlphaTheta-only hack. Before capture, it reads the device’s own USB audio descriptors, UAC1 and UAC2, to find the streaming interface, the channel count across the input terminals, and the sample rates the device actually supports. It captures whatever the mixer exposes. That is why the same code path handles a DJM and a class-compliant Behringer or Midas board without me writing a separate profile for each one. It works the way an audio interface driver works, off the descriptors rather than a lookup table.

One bug that took me a while to find. The URB reap queue is per file descriptor, and a reap hands you the next completed URB from any endpoint on that device. I added a loopback playback path for a diagnostic, and suddenly capture and playback were reaping each other’s URBs off the same queue and losing them. The fix was to let exactly one thread own the reap call, tag every URB at submit time so I know whether it is a capture buffer or a playback buffer, and route each one to the right handler. Most of this project has been small, sharp problems like that.

What comes out. Recording writes WAV through a native writer straight to a file descriptor, so a set survives even if the app gets killed mid-recording. Each source lands as its own track. After that you can export to FLAC, AAC or MP3. FLAC and MP3 encode with libFLAC and LAME compiled into the app, AAC uses the platform encoder.

Where it is at. Honest beta. I have tested it thin, mostly on the V10 I own, and built the rest from descriptor data for the A9, 900NXS2 and NXS2. It should work on other DJMs, and some may need changes. I ship fixes almost every day, and I would not trust it for a set you have to keep yet.

What I would love from this forum. This is the crowd that would actually poke holes in the USB approach, and I want that. If you are on Android with a DJM or a class-compliant mixer, I would love help testing it on gear I cannot get to. It is in beta at setrecorderpro.com, and you can reach me there or here.

Cheers folks and thank you!

TSB

I don’t have an Android phone, so I can’t test it. It looks cool though and I appreciate the technical nuances of what you’re trying to do.