BCD2000 Technical 
I have only figured out the MIDI part of the BCD2000 so far. I have some pretty good ideas about the audio part but I so far haven't found the time to write an audio driver so I can't be certain.
The information below is all from the top of my head since I can't seem to find my notes at the moment.


The MIDI interface is handled by two interrupt endpoints. The addresses of which I'm not 100% certain about.

MIDI Input

The BCD2000 sends it MIDI commands over the input interrupt endpoint (0x81 I think). The BCD2K chops the MIDI data stream up into several USB interrupt packets. Each interrupt packet starts with a byte indicating how many MIDI bytes that packet contains, followed by those bytes. If you stitch those fragments together you get a MIDI stream. The rest of the packet seems to be garbage, except for this one counter byte which really isn't that very useful.
The BCD2000 uses 2- and 3-byte MIDI packets, meaning that when two consecutive MIDI packets are triggered by the same control (or note, in MIDI terms) it may skip the note byte. It doesn't always do that though.
Here's the code that handles MIDI input in my driver:

void BCD2000USBMIDIDriver::HandleInput(USBMIDIDevice *usbmDev, MIDITimeStamp when, Byte *readBuf, ByteCount readBufSize)

Byte* data = readBuf + 1;
ByteCount size = readBuf[0];

Byte* src = (Byte*) &usbmDev->mPacketBuffer;

Byte pbuf[512];
MIDIPacketList *pktlist = (MIDIPacketList *)pbuf;
MIDIPacket *pkt = MIDIPacketListInit(pktlist);

UInt32 i;

for(i = 0; i < size; i++) {
if( usbmDev->mPacketRead == 0 ) {
if ( (data[0] != (Byte)0x90) && (data[0] != (Byte)0xb0) ) {
// stitched data
usbmDev->mPacketRead++; // keep first byte from previous packet
usbmDev->mPacketBuffer[usbmDev->mPacketRead++] = data[ i ];
if(usbmDev->mPacketRead == kBCDPacketSize) {
usbmDev->mPacketRead = 0;

if(src[0]==0xb0 && (src[1] == 0x13 || src[1] == 0x12)) {
if(src[2] == 0x40) src[2] = 0x01;
if(src[2] == 0x41) src[2] = 0x7f;

MIDIPacketListAdd(pktlist, sizeof(pbuf), pkt, when, kBCDPacketSize, usbmDev->mPacketBuffer);

MIDIReceived(usbmDev->mSources[0], pktlist);


The TRANSLATE_BCD_COMMANDS constant can be used to turn on MIDI command translation so the jogwheels can be used with Traktor (without messing about with MIDI Rules).

MIDI Output

MIDI Output can be used to toggle the LEDs on the BCD2000. Multiple MIDI commands can be sent in a single USB packet, as long as you don't exceed the packet size of 64 bytes. Each packet that is sent to the BCD2000 must start with 0x03 00 followed by a byte indicating the MIDI message length, followed by the actual MIDI data. This is my (really, really ugly) OS X driver code:

ByteCount USBMIDIDriverBase::USBMIDIPrepareOutput( USBMIDIDevice * usbmDev,
WriteQueue & writeQueue,
Byte * destBuf,
ByteCount bufSize)
Byte *dest = destBuf + 3, *destend = dest + bufSize;
destBuf[0] = 0x03;
destBuf[1] = 0x00;
destBuf[2] = 0x00;

if (!writeQueue.empty()) {
WriteQueue::iterator wqit = writeQueue.begin();
WriteQueueElem *wqe = &(*wqit);
Byte *dataStart = wqe->packet.Data();
Byte *src = dataStart + wqe->bytesSent;
Byte *srcend = dataStart + wqe->packet.Length();
int srcLeft;

if ((srcLeft = srcend - src) > 0 && dest <= destend - 4) {
Byte c = *src++;

switch (c >> 4) {
case 0xB: // control change
*dest++ = c;
*dest++ = *src++;
*dest++ = *src++;
destBuf[2] += 3;

if (src >= srcend) {
// source packet completely sent
//if (writeQueue.empty())
// break;
} else
wqe->bytesSent = src - dataStart;
} // ran out of source data or filled buffer

//if (dest > destend - 4)
// destBuf completely filled

// we didn't fill the output buffer, loop around to look for more
// source data in the write queue

} // while walking writeQueue
return dest - destBuf;

I'm sure you can tell from the code I'm not a C++ developer, at all :)