home software gear music contact FAQ

CDJ2MIDI: turn any CDJ into a MIDI controller

CDJ2MIDI is a C++ application which converts an analog signal into a digital one, like commercial scratch interfaces such as Serato or Traktor Scratch for CDs. The main difference is that it's much more responsive and doesn’t require an expensive, proprietary audio hardware. CDJ2MIDI is pure software so it will work with any audio-in interface; even a $50 Edirol USB Audio interface will do, as the video below shows.

If you’re a DJ/producer performing with a decent audio card, chances are it already has built-in audio-in channels, so there’s zero additional hardware cost. Nor does CDJ2MIDI require you to purchase any physical timecode vinyl or CD; it will generate the timecode WAV files for you with the following parameters you can chose from:

Once the timecode WAVs are saved to your hard drive you just have to burn them on two CDRs.


Most vinyl-to-PC algorithms use Trellis-Coded Modulation (invented during the eighties) to encode binary timecode, using wide sine waves so that a certain amount of noise doesn’t degrade the signal to the point of breaking the entire system. This old form of encoding has been used on timecode CDs as well, so the same hardware can decode both vinyls and CDs.

However, if you burn a control wave on a CD and sample it back through a sound card, you’ll find that the signal degradation isn't quite as brutal as vinyls, voiding the need for sine-based logic, enabling much more effective encoding algorithms. The result is more reliable, way faster -- and doesn't require special signal-processing hardware.

Encoded timestamp:

Sampled timestamp:

(inverted phase gets flipped automatically)

Decoded timestamp:
stable signal lines in green (click to enlarge)


Most signal transmissions rely on finely-tuned clocks based on Quartz oscillations. But since a CDJ's speed can vary by +/- 10% (which is, after all, their whole point), their audio output can't be relied on for vanilla synchronisation. If you encoded the binary stream "1111111111" as-is, you'd quickly lose synchronisation.

Instead, CDJ2MIDI uses a protocol reminiscent of old floppy disks whose drives had flaky rotational speed. The trick was to convert the original, logical binary signal into an intermediate physical encoding that ensures no single bit (line level) can occur more than once in a row.

F.ex. a binary signal (square wave) could get multiplexed over 3 lines (say -5 volts, 0 volts and +5 volts) using a cycling look-up table. If the 1st bit starts on line -5, the next legitimate value is 0 or +5. If the following bit was 0, the next legit values are -5 or +5; but if it was +5, the next bit will be on 0 or -5, etc. The gatekeeper markers between timestamps detect phase inversion and auto-calibrate input volume as well as DC-offset.

CDJ2MIDI's timecode initially used 3 lines but my current version uses 5 lines to further shrink a timestamp (using a quad-bit for name-dropping purposes). Using more line levels, as well as distributing the signal among stereo channels (which are currently cloned mono) would further shrink latency but ~2 milliseconds is good enough and more packing could hurt resilliance.


  • 2.38 milliseconds input latency (length of one full timestamp)

  • uses strictly absolute timestamps, hence needle-drops, FF/REW, marker recalls and tightest loops work as expected

  • can send raw "scratch" timecode

  • needs only a single mono audio signal per CDJ, so lower-end audio cards with just one stereo input will work (in the movie demo only one stereo RCA cable is used and split in two)

  • decodes Track number, Tempo (often with better accuracy than a CDJ display), Pitch Bend, FF/REW, Play/Pause and Cues

  • outputs vanilla 7-bit MIDI, Open Sound Control (OSC) and custom, high-res SysEx-based MIDI messages with 64-bit user and timestamp values

  • accurate display of track timecode, including frames (*)

  • built-in/real-time normalization of input volume, phase and DC offset (you'll note in the video that the volumes on the M-Audio card are very different)

  • decoding algorithm is very fast; doesn't use memory allocation, FFT or other CPU-costly techniques

  • timestamps are processed directly in the sound input interrupt callback thread

  • built-in error detection with timestamp checksums

  • audio cables hot-plugging; no need for recalibration so any interruption would be very short

  • correction for "Red Book" variable CD rotational speed

  • the "virtual sensor's" variables can be edited on-the-fly

  • visual WAV debugger to identify potential hardware problems and help adjust variables to work around them

The short (and silent) video below shows CDJ2MIDI in action, first using a cheapo Edirol UA-1A audio card using USB 1.0, then with an M-Audio FastTrack Pro in USB 2.0. Tests also worked flawlessly with an Edirol UA-101 (10 in / 10 out), not shown here. CDJ2MIDI ran fine on a CDJ-1000 as well, of course with key-lock off and in CD, not vinyl mode.

You can also download the MPEG file. The first capture came out blurry, hence the funky magnifying glasses hovering over the CDJ displays.

(*) On a Pioneer CDJ-100 the timecode displays are exactly 9 frames off due the CDJ-100's well-known delay on a cue recall or resumed play

Until integrated with Mixxx, CDJ2MIDI is meant to run in the background, while in the foreground you’ll probably have Live or Traktor running in full-screen, which is why its GUI is minimalist.

Timecode debugger

The WAV browser supports 16x zoom in, scrubbable global view, user markers, virtual sensor display, tempo change markers (purple), pitch bend overlay (yellow), snap to markers:

Source code

Get the latest source code here. CDJ2MIDI Currently runs on Linux/Gtk & Windows using PortAudio, rtMIDI and wxWidgets but the core engine is pure C++ (possibly strict ISO). The project is built with CodeLite but can be compiled from other IDEs or command-line.


CDJ2MIDI is copyrighted by moi -- just ask me for a license if you'd like to redistribute it in any form -- I'll most likely give it out for free.