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(); }
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); }
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); }
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); }
int lp_send_midi_msg(lp_device_t device, uint8_t data[256], size_t len) { uint8_t buf[256]; bzero(buf, 256); MIDIPacketList *list = (MIDIPacketList *)buf; (void)MIDIPacketListInit(list); list->numPackets = 1; list->packet[0].length = len; list->packet[0].timeStamp = 0; memcpy(list->packet[0].data, data, len); return MIDISend(_lp_ctx.outport, device->dest, (const MIDIPacketList *)list); }
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(); } }
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); }
//_________________________________________________________ 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); }
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(); } }
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(); }
// _________________________________________________________________________________________ // 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); }
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(); }