void CoreMidiOutputDevice::writeSysEx(QByteArray message)
{
    if(message.isEmpty())
        return;

    if (isOpen() == false)
        return;

    int bufferSize = message.count() + 100; // Todo this is not correct

    Byte buffer[bufferSize];    // osx max=65536
    MIDIPacketList* list = (MIDIPacketList*) buffer;
    MIDIPacket* packet = MIDIPacketListInit(list);

    /* Add the MIDI command to the packet list */
    packet = MIDIPacketListAdd(list, bufferSize, packet, 0, message.count(), (Byte *)message.data());
    if (packet == 0)
    {
        qWarning() << "MIDIOut buffer overflow";
        return;
    }

    /* Send the MIDI packet list */
    OSStatus s = MIDISend(m_outPort, m_destination, list);
    if (s != 0)
        qWarning() << Q_FUNC_INFO << "Unable to send MIDI data to" << name();
}
void CoreMidiOutputDevice::writeFeedback(uchar cmd, uchar data1, uchar data2)
{
    if (isOpen() == false)
        return;

    Byte buffer[128]; // Should be enough for 1 message
    MIDIPacketList* list = (MIDIPacketList*) buffer;
    MIDIPacket* packet = MIDIPacketListInit(list);

    Byte message[3];
    message[0] = cmd;
    message[1] = data1;
    message[2] = data2;

    /* Add the MIDI command to the packet list */
    packet = MIDIPacketListAdd(list, sizeof(buffer), packet, 0, sizeof(message), message);
    if (packet == 0)
    {
        qWarning() << "MIDIOut buffer overflow";
        return;
    }

    /* Send the MIDI packet list */
    OSStatus s = MIDISend(m_outPort, m_destination, list);
    if (s != 0)
        qWarning() << Q_FUNC_INFO << "Unable to send MIDI data to" << name();
}
Example #3
0
File: midi.c Project: huangjs/cl
int mus_midi_write(int line, unsigned char *buffer, int bytes)
{
  MIDIPacketList *list = (MIDIPacketList *)bb;
  MIDIPacket *pk;
  if ((line < 1) || (buffer == NULL) || (outp == NULL)) return(-1);
  /* create the packetlist and packet */
  pk = MIDIPacketListInit(list);
  MIDIPacketListAdd(list, sizeof(bb), pk, 0, bytes, (Byte *)buffer);  /* 0 is the time stamp = now? */
  MIDISend(outp, MIDIGetDestination(0), list);
  return(0);
}
Example #4
0
void MIDIOut_Send(MIDIPortRef port, MIDIEndpointRef dest, UInt8 *buffer, unsigned length)
{
    Byte packetBuff[512];
    MIDIPacketList *packetList = (MIDIPacketList *)packetBuff;

    MIDIPacket *packet = MIDIPacketListInit(packetList);

    packet = MIDIPacketListAdd(packetList, sizeof(packetBuff), packet, mach_absolute_time(), length, buffer);
    if (packet)
        MIDISend(port, dest, packetList);
}
void sendmidi(int port, MIDIEndpointRef dest, int length, int hiStatus, int loStatus, int aval, int bval, float late)
{
	MIDIPacketList mpktlist;
	MIDIPacketList * pktlist = &mpktlist;
	MIDIPacket * pk = MIDIPacketListInit(pktlist);
	ByteCount nData = (ByteCount) length;
	pk->data[0] = (Byte) (hiStatus & 0xF0) | (loStatus & 0x0F);
	pk->data[1] = (Byte) aval;
	pk->data[2] = (Byte) bval;
	pk = MIDIPacketListAdd(pktlist, sizeof(struct MIDIPacketList) , pk, midiTime(late), nData, pk->data);
	/*OSStatus error =*/ MIDISend(gMIDIOutPort[port],  dest, pktlist );
}
void hal_plot_led(u8 type, u8 index, u8 red, u8 green, u8 blue)
{
	// send this up the MIDI.  Construct sysex:
	unsigned char data[] = {0xF0, 0x00, 0x20, 0x29, 0x02, 0x10, 0x0B, index, red, green, blue, 0xF7};
	
	static const int MAX_OUTPUT_BUFFER_SIZE = 256;
	
	MIDIPacketList packetLst;
	MIDIPacket *packet = MIDIPacketListInit(&packetLst);
	MIDIPacketListAdd(&packetLst, MAX_OUTPUT_BUFFER_SIZE, packet, 0, sizeof(data), data);
	
	MIDISend(g_outDevPort, g_outDevEndpoint, &packetLst);
}
Example #7
0
/* appends a packetlist with saved cc button messages */
MIDIPacket*
convBtnDumpSaved(MIDIPacket *pkt, MIDIPacketList *pktList, int *count)
{
    int packetcount = 1;	/* a multiplier for the interval */

    for (unsigned int i = 0 ; i < number_of_button_params; i++) {
        if (btn_conv_buf[i].last_cc_value != 231) {
            /* if this buffer member has been used at all */
            MIDIPacket pktToAdd;
            pktToAdd.length = 3;
            pktToAdd.data[0] = CC_MSG_BYTE + (defs->recvchannel - 1);
            pktToAdd.data[1] = btn_conv_buf[i].cc_param_number;
            pktToAdd.data[2] = btn_conv_buf[i].last_cc_value;
	    /* this needs to be set on an interval * count */
            pktToAdd.timeStamp = mach_absolute_time();

            /* to convert mach_absolute_time to nanos */
            mach_timebase_info_data_t info;
            mach_timebase_info(&info);

            /* convert to nanos */
            pktToAdd.timeStamp *= info.numer;
            pktToAdd.timeStamp /= info.denom;

            /* calculate the scheduling based on interval */
            pktToAdd.timeStamp = pktToAdd.timeStamp
		+ ((5 NS_TO_MS) * packetcount)
		+ (number_of_fader_params
		   * (5 NS_TO_MS)
		   + (5 NS_TO_MS)
		   + 30 NS_TO_MS); /* replace w/ defs->dump_interval */
            /* this is correct calculation though */
            packetcount++;

            printf("Dumping %02X %02d %02d\n",
		   pktToAdd.data[0],
		   pktToAdd.data[1],
		   pktToAdd.data[2]);

            pkt = MIDIPacketListAdd(pktList,
                                    sizeof(*pktList),
                                    pkt,
                                    pktToAdd.timeStamp,
                                    pktToAdd.length,
                                    &pktToAdd.data[0]);
            /* add it to the packetList */
            *count = *count++;
        }
    }
    return pkt;
}
void MIDIOutputCallbackHelper::FireAtTimeStamp(const AudioTimeStamp &inTimeStamp) 
{
	if (!mMIDIMessageList.empty())
	{
		if (mMIDICallbackStruct.midiOutputCallback) 
		{
			// synthesize the packet list and call the MIDIOutputCallback
			// iterate through the vector and get each item
			MIDIPacketList *pktlist = PacketList();

			MIDIPacket *pkt = MIDIPacketListInit(pktlist);
			
			for (MIDIMessageList::iterator iter = mMIDIMessageList.begin(); iter != mMIDIMessageList.end(); iter++) 
			{
				const MIDIMessageInfoStruct & item = *iter;
								
				Byte midiStatusByte = item.status + item.channel;
				const Byte data[3] = { midiStatusByte, item.data1, item.data2 };
				UInt32 midiDataCount = ((item.status == 0xC || item.status == 0xD) ? 2 : 3);
				pkt = MIDIPacketListAdd (pktlist, 
											kSizeofMIDIBuffer, 
											pkt, 
											item.startFrame, 
											midiDataCount, 
											data);
				if (!pkt)
				{
						// send what we have and then clear the buffer and then go through this again
					// issue the callback with what we got
					OSStatus result = (*mMIDICallbackStruct.midiOutputCallback) (mMIDICallbackStruct.userData, &inTimeStamp, 0, pktlist);
					if (result != noErr)
						printf("error calling output callback: %d", (int) result);
					
					// clear stuff we've already processed, and fire again
					mMIDIMessageList.erase (mMIDIMessageList.begin(), iter);
					FireAtTimeStamp(inTimeStamp);
					return;
				}
			}
			
			// fire callback
			OSStatus result = (*mMIDICallbackStruct.midiOutputCallback) (mMIDICallbackStruct.userData, &inTimeStamp, 0, pktlist);
			if (result != noErr)
				printf("error calling output callback: %d", (int) result);
		}
		mMIDIMessageList.clear();
	}
}
Example #9
0
static void _macosx_send(struct midi_port *p, const unsigned char *data,
				unsigned int len, unsigned int delay)
{
	struct macosx_midi *m;

	m = (struct macosx_midi *)p->userdata;
	if (!m->x) {
		m->x = MIDIPacketListInit(m->pl);
	}

	/* msec to nsec? */
	m->x = MIDIPacketListAdd(m->pl, sizeof(m->packet),
			m->x, (MIDITimeStamp)AudioConvertNanosToHostTime(
			AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) + (1000000*delay)),
			len, data);
}
Example #10
0
//_________________________________________________________
static void SendSmallEv(SlotPtr slot, MidiEvPtr e, sendState* state)
{ 
	MIDIPacketList* pktlist = (MIDIPacketList*)state->packetBuffer;
	MIDIPacket* packet = MIDIPacketListInit(pktlist);
	unsigned char * ptr = state->evBuffer;
	OSErr err;
	int n = 0;
  	 
	e = MidiStreamPutEvent (&state->outsmall, e);
	if (e) MidiTask (KOffTask, Date(e), gRefNum, (long)e, (long)slot, 0); // typeNote
	
	while (MidiStreamGetByte (&state->outsmall, ptr++)) {n++;}
	
	MIDIPacketListAdd(pktlist,sizeof(state->packetBuffer),packet,MIDIGetCurrentHostTime(),n,state->evBuffer);
	err = MIDISend(slot->port,slot->dest,pktlist);
	if (err != noErr) fprintf(stderr, "MIDISend : error %ld\n", err);
}
Example #11
0
void CoreMidiManager::SendMIDI(char actionType, int noteNum, int value)
{
  uint8_t buffer[PACKET_BUF_SIZE];
  uint8_t msg[3];
  
  MIDIPacketList *packetList = (MIDIPacketList*) buffer;
  MIDIPacket *curPacket = MIDIPacketListInit(packetList);
  
  curPacket = MIDIPacketListAdd(packetList,
				PACKET_BUF_SIZE,
				curPacket,
				AudioGetCurrentHostTime(),
				actionType == 'C' ? 2 : 3,
				msg);
  if (!curPacket)
    midimsg_die("packet list allocation failed");
  
  midimsg_attempt(MIDIReceived(m_midiendpoint, packetList), "error sending midi");
}
void MIDIOutputCallbackHelper::FireAtTimeStamp(const AudioTimeStamp &inTimeStamp) {
	if (!mMIDIMessageList.empty() && mMIDICallbackStruct.midiOutputCallback != 0) {
		// synthesize the packet list and call the MIDIOutputCallback
		// iterate through the vector and get each item
				
		std::vector<MIDIMessageInfoStruct>::iterator myIterator;
		MIDIPacketList *pktlist = PacketList();

		for (myIterator = mMIDIMessageList.begin(); myIterator != mMIDIMessageList.end(); myIterator++) {
			MIDIMessageInfoStruct item = *myIterator;
			
			MIDIPacket *pkt = MIDIPacketListInit(pktlist);
			bool tooBig = false;
			
			Byte midiStatusByte = (item.status << 4) | item.channel;
			Byte data[3] = { midiStatusByte, item.data1, item.data2 };
			if ((pkt = MIDIPacketListAdd(pktlist, sizeof(mBuffersAllocated), pkt, item.startFrame, 4, const_cast<Byte*>(data))) == NULL)
				tooBig = true;
				
			if (tooBig) {	// send what we have and then clear the buffer and send again
				// issue the callback with what we got
				OSStatus result = mMIDICallbackStruct.midiOutputCallback(mMIDICallbackStruct.userData, &inTimeStamp, 0, pktlist);
				if (result != noErr)
					printf("error calling output callback: %d", (int) result);
				
				// clear stuff we've already processed, and fire again
				mMIDIMessageList.erase(mMIDIMessageList.begin(), myIterator);
				this->FireAtTimeStamp(inTimeStamp);
				return;
			}
		}
		
		// fire callback
		OSStatus result = mMIDICallbackStruct.midiOutputCallback(mMIDICallbackStruct.userData, &inTimeStamp, 0, pktlist);
		if (result != noErr)
			printf("error calling output callback: %d", (int) result);

		mMIDIMessageList.clear();
	}
}
/**** Rings *****/
void TraktorMixMode::leftRingSpun(DM2USBMIDIDriver * dm2){
	int accel;
	//range of 62 instead of 127, about half
	accel = dm2->status.accel_left;
	if(accel == 0)
		accel = 64;
	else
		accel = accel > 0 ? (int)(63 - (accel * .5)) : (int)(accel * -.48 + 66);
	//Note CC 24
	if(dm2->status.left)//scratching left
	{
		dm2->noteBuf[0] = 0xB0; //shift the channel up 8 if holding the round button in the center thingy
		dm2->noteBuf[1] = kCC_TRAKTOR_SCRATCH;
		dm2->noteBuf[2] = accel;
		
		//makeCCNote(0xB0,kCC_TRAKTOR_SCRATCH,accel,dm2);
	}
	else if(dm2->status.middle) // pitch bending left
	{
		dm2->noteBuf[0] = 0xB0; 
		dm2->noteBuf[1] = kCC_TRAKTOR_PITCH;
		dm2->noteBuf[2] = accel;
		//makeCCNote(0xB0,kCC_TRAKTOR_PITCH,accel,dm2);
	}
	else if( accel == 64 || abs(accel - 64) > 1)  //To stop 'needle jumps' that small tap might cause, should only be done on 'transport critical' modes
	{				
		dm2->noteBuf[0] = 0xB0; 
		dm2->noteBuf[1] = kCC_TRAKTOR_DECKWIND; //deck wind left
		dm2->noteBuf[2] = accel;
	}
	else
		return;
	
	dm2->pkt = MIDIPacketListAdd(dm2->pktlist, sizeof(dm2->pbuf), dm2->pkt, dm2->timeStamp, 3, dm2->noteBuf );
#ifdef DEBUG
	//	printf("Sending Loop left ring: %x %i %i\n",dm2->noteBuf[0],dm2->noteBuf[1],dm2->noteBuf[2]);
#endif
}
void TraktorMixMode::rightRingSpun(DM2USBMIDIDriver * dm2){
	int accel;
	//range of 62 instead of 127, about half
	accel = dm2->status.accel_right;
	if(accel == 0)
		accel = 64;
	else
		accel = accel > 0 ? (int)(63 - (accel * .5)) : (int)(accel * -.48 + 66);
	//Note CC 24
	if(dm2->status.right)//scratching right
	{
		dm2->noteBuf[0] = 0xB1; //When Scrach button is held, send CC 22, chan 1(left) and 2(right)
		dm2->noteBuf[1] = kCC_TRAKTOR_SCRATCH;
		dm2->noteBuf[2] = accel;
		//makeCCNote(0xB1,kCC_TRAKTOR_SCRATCH,accel,dm2);
	}
	else if(dm2->status.middle) // pitch bending left
	{
		dm2->noteBuf[0] = 0xB1; 
		dm2->noteBuf[1] = kCC_TRAKTOR_PITCH;
		dm2->noteBuf[2] = accel;
		//makeCCNote(0xB1,kCC_TRAKTOR_PITCH,accel,dm2);
	}
	else if( accel == 64 || abs(accel - 64) > 1)  //To stop 'needle jumps' that small tap might cause, should only be done on 'transport critical' modes
	{				
		dm2->noteBuf[0] = 0xB1;
		dm2->noteBuf[1] = kCC_TRAKTOR_DECKWIND; //CC 26, deck wind
		dm2->noteBuf[2] = accel;
	}
	else
		return;
	
	dm2->pkt = MIDIPacketListAdd(dm2->pktlist, sizeof(dm2->pbuf), dm2->pkt, dm2->timeStamp, 3, dm2->noteBuf );
#ifdef DEBUG
	//	printf("Sending Loop right ring: %x %i %i\n",dm2->noteBuf[0],dm2->noteBuf[1],dm2->noteBuf[2]);
#endif
}
Example #15
0
void MIDIDevice::outputDMX(const QByteArray& universe)
{
    /* If there's no output port or a destination, the endpoint probably
       doesn't have a MIDI OUT port. */
    if (m_outPort == 0 || m_destination == 0)
        return;

    Byte buffer[512]; // Should be enough for 128 channels
    MIDIPacketList* list = (MIDIPacketList*) buffer;
    MIDIPacket* packet = MIDIPacketListInit(list);

    /* Since MIDI devices can have only 128 real channels, we don't
       attempt to write more than that */
    for (Byte channel = 0; channel < MAX_MIDI_DMX_CHANNELS; channel++)
    {
        Byte cmd[3];

        cmd[1] = channel;
        cmd[2] = DMX2MIDI(universe[channel]);

        /* Since MIDI is so slow, we only send values that are
           actually changed. */
        if (m_values[channel] == cmd[2])
            continue;

        /* Store the changed MIDI value. */
        m_values[channel] = cmd[2];

        if (m_mode == Note)
        {
            if (cmd[2] == 0)
            {
                /* Zero is sent as a note off command */
                cmd[0] = MIDI_NOTE_OFF;
            }
            else
            {
                /* 1-127 is sent as note on command */
                cmd[0] = MIDI_NOTE_ON;
            }
        }
        else
        {
            /* Control change */
            cmd[0] = MIDI_CONTROL_CHANGE;
        }

        /* Encode MIDI channel to the command */
        cmd[0] |= (Byte) midiChannel();

        /* Add the MIDI command to the packet list */
        packet = MIDIPacketListAdd(list, sizeof(buffer), packet, 0,
                                   sizeof(cmd), cmd);
        if (packet == 0)
        {
            qWarning() << "MIDIOut buffer overflow";
            break;
        }
    }

    /* Send the MIDI packet list */
    OSStatus s = MIDISend(m_outPort, m_destination, list);
    if (s != 0)
        qWarning() << "Unable to send MIDI data to" << name();
}
void CoreMidiOutputDevice::writeUniverse(const QByteArray& universe)
{
    if (isOpen() == false)
        return;

    Byte buffer[512]; // Should be enough for 128 channels
    MIDIPacketList* list = (MIDIPacketList*) buffer;
    MIDIPacket* packet = MIDIPacketListInit(list);

    /* Since MIDI devices can have only 128 real channels, we don't
       attempt to write more than that */
    for (Byte channel = 0; channel < MAX_MIDI_DMX_CHANNELS &&
                           channel < universe.size(); channel++)
    {
        Byte cmd[3];
        cmd[1] = channel;
        cmd[2] = DMX2MIDI(uchar(universe[channel]));

        /* Since MIDI is so slow, we only send values that are
           actually changed. */
        if (uchar(m_universe[channel]) == cmd[2])
            continue;

        /* Store the changed MIDI value. */
        m_universe[channel] = cmd[2];

        if (mode() == Note)
        {
            if (cmd[2] == 0)
            {
                /* Zero is sent as a note off command */
                cmd[0] = MIDI_NOTE_OFF;
            }
            else
            {
                /* 1-127 is sent as note on command */
                cmd[0] = MIDI_NOTE_ON;
            }
        }
        else if (mode() == ProgramChange)
        {
            /* Program change */
            cmd[0] = MIDI_PROGRAM_CHANGE;
        }
        else
        {
            /* Control change */
            cmd[0] = MIDI_CONTROL_CHANGE;
        }

        /* Encode MIDI channel to the command */
        cmd[0] |= (Byte) midiChannel();

        /* Add the MIDI command to the packet list */
        packet = MIDIPacketListAdd(list, sizeof(buffer), packet, 0, sizeof(cmd), cmd);
        if (packet == 0)
        {
            qWarning() << "MIDIOut buffer overflow";
            break;
        }
    }

    /* Send the MIDI packet list */
    OSStatus s = MIDISend(m_outPort, m_destination, list);
    if (s != 0)
        qWarning() << Q_FUNC_INFO << "Unable to send MIDI data to" << name();
}
// _________________________________________________________________________________________
// USBMIDIDriverBase::USBMIDIHandleInput
//
void	USBMIDIDriverBase::USBMIDIHandleInput(	USBMIDIDevice *	usbmDev, 
												MIDITimeStamp	when, 
												Byte *			readBuf,
												ByteCount		bufSize)
{
	Byte *src = readBuf, *srcend = src + bufSize;
	Byte pbuf[512];
	MIDIPacketList *pktlist = (MIDIPacketList *)pbuf;
	MIDIPacket *pkt = MIDIPacketListInit(pktlist);
	int prevCable = -1;	// signifies none
	bool insysex = false;

	for ( ; src < srcend; src += 4) {
		int cin = src[0] & 0x0F;
		
		if (cin < 2)
			// skip over reserved cin's before doing any more work
			continue;
		
		int cable = src[0] >> 4;
		int msglen;
		// support single-entity devices that seem to use an arbitrary cable number
		// (besides which, it's good to have range-checking)
		if (cable < 0) cable = 0;
		else if (cable >= usbmDev->mNumEntities) cable = usbmDev->mNumEntities - 1;
		
		if (prevCable != -1 && cable != prevCable) {
			MIDIReceived(usbmDev->mSources[prevCable], pktlist);
			pkt = MIDIPacketListInit(pktlist);
			insysex = false;
		}
		prevCable = cable;
		
		#if SYSEX_DEBUG_LEVEL >= 2
			if (gSysExTraceCount >= 0)
				gSysExTraceBuf[gSysExTraceCount++] = *(UInt32 *)src;
		#endif

		switch (cin) {
		case 0x0:		// reserved
		case 0x1:		// reserved
			break;
		case 0xF:		// single byte
			msglen = 1;
AddMessage:
			while (true) {
				pkt = MIDIPacketListAdd(pktlist, sizeof(pbuf), pkt, when, msglen, src + 1);
				if (pkt != NULL) break;
				if (prevCable != -1)
					MIDIReceived(usbmDev->mSources[prevCable], pktlist);
				pkt = MIDIPacketListInit(pktlist);
				insysex = false;
			}
			break;
		case 0x2:		// 2-byte system common
		case 0xC:		// program change
		case 0xD:		// mono pressure
			msglen = 2;
			goto AddMessage;
		case 0x4:		// sysex starts or continues			
			#if SYSEX_DEBUG_LEVEL >= 2
				if (gSysExCount == -1) {
					gSysExTraceCount = 0;
					gSysExCount = 0;
					gSysExTraceBuf[gSysExTraceCount++] = *(UInt32 *)src;
				}
				gSysExCount += 3;
			#elif SYSEX_DEBUG_LEVEL >= 1
				if (gSysExCount == -1)
					gSysExCount = 0;
				gSysExCount += 3;
			#endif
			if (insysex) {
				// MIDIPacketListAdd will make a separate packet unnecessarily,
				// so do our own concatentation onto the current packet
				msglen = 3;
AddSysEx:
				Byte *dest = &pkt->data[pkt->length];
				if (dest + msglen > pbuf + sizeof(pbuf)) {
					if (prevCable != -1)
						MIDIReceived(usbmDev->mSources[prevCable], pktlist);
					pkt = MIDIPacketListInit(pktlist);
					insysex = false;
					goto AddMessage;
				}
				memcpy(dest, src + 1, msglen);
				pkt->length += msglen;
				break;
			}
			insysex = true;
			// --- fall ---
		case 0x3:		// 3-byte system common
		case 0x8:		// note-off
		case 0x9:		// note-on
		case 0xA:		// poly pressure
		case 0xB:		// control change
		case 0xE:		// pitch bend
			msglen = 3;
			goto AddMessage;
		case 0x5:		// single byte system-common, or sys-ex ends with one byte
			if (src[1] != 0xF7) {
				msglen = 1;
				goto AddMessage;
			}
			// --- fall ---
		case 0x6:		// sys-ex ends with two bytes
		case 0x7:		// sys-ex ends with three bytes
			msglen = cin - 4;

			#if SYSEX_DEBUG_LEVEL >= 1
				if (gSysExCount > 0) {
					gSysExCount += msglen;
					
					#if SYSEX_DEBUG_LEVEL >= 2
						char fname[64];
						sprintf(fname, "/tmp/sysx%d", ++gSysExMessages);
						FILE *f = fopen(fname, "w");
						for (int i = 0; i < gSysExTraceCount; ++i) {
							if (gSysExTraceBuf[i] == 0)
								fprintf(f, "\n");
							else
								fprintf(f, "%08x\n", gSysExTraceBuf[i]);
						}
						fclose(f);
						gSysExTraceCount = -1;
					#endif
					
					printf("=== driver: sysex end, %d bytes ===\n", gSysExCount);
					
					gSysExCount = -1;
				}
			#endif
			
			if (insysex) {
				insysex = false;
				goto AddSysEx;
			}
			goto AddMessage;
		}
	}
	#if SYSEX_DEBUG_LEVEL >= 2
		gSysExTraceBuf[gSysExTraceCount++] = 0;
		//syscall(180, 0xd0000000 + (src - readBuf), src-readBuf, 0, 0, 0);
	#endif
	
	if (pktlist->numPackets > 0 && prevCable != -1)
		MIDIReceived(usbmDev->mSources[prevCable], pktlist);
}