void MidiOutput::sendMessageNow (const MidiMessage& message) { #if JUCE_IOS const MIDITimeStamp timeStamp = mach_absolute_time(); #else const MIDITimeStamp timeStamp = AudioGetCurrentHostTime(); #endif HeapBlock<MIDIPacketList> allocatedPackets; MIDIPacketList stackPacket; MIDIPacketList* packetToSend = &stackPacket; const size_t dataSize = (size_t) message.getRawDataSize(); if (message.isSysEx()) { const int maxPacketSize = 256; int pos = 0, bytesLeft = (int) dataSize; const int numPackets = (bytesLeft + maxPacketSize - 1) / maxPacketSize; allocatedPackets.malloc ((size_t) (32 * (size_t) numPackets + dataSize), 1); packetToSend = allocatedPackets; packetToSend->numPackets = (UInt32) numPackets; MIDIPacket* p = packetToSend->packet; for (int i = 0; i < numPackets; ++i) { p->timeStamp = timeStamp; p->length = (UInt16) jmin (maxPacketSize, bytesLeft); memcpy (p->data, message.getRawData() + pos, p->length); pos += p->length; bytesLeft -= p->length; p = MIDIPacketNext (p); } } else if (dataSize < 65536) // max packet size { const size_t stackCapacity = sizeof (stackPacket.packet->data); if (dataSize > stackCapacity) { allocatedPackets.malloc ((sizeof (MIDIPacketList) - stackCapacity) + dataSize, 1); packetToSend = allocatedPackets; } packetToSend->numPackets = 1; MIDIPacket& p = *(packetToSend->packet); p.timeStamp = timeStamp; p.length = (UInt16) dataSize; memcpy (p.data, message.getRawData(), dataSize); } else { jassertfalse; // packet too large to send! return; } static_cast<CoreMidiHelpers::MidiPortAndEndpoint*> (internal)->send (packetToSend); }
/** Checksum processors */ void CtrlrSysexProcessor::checksumRolandJp8080(const CtrlrSysexToken token, MidiMessage &m) { /* Since +5 is parameter value 1DH, F0 41 10 00 06 (model id) 12 (command if) 01 00 10 03 (address) 1D (data) ?? (checksum) F7 Next we calculate the checksum. 01H + 00H + 10H + 03H + 1DH = 1 + 0 + 16 + 3 + 29 = 49 (sum) 49 (total) 128 ÷ 0 (quotient) ... 49 (remainder) checksum = 128 - 49 (quotient) = 79 = 4FH This means that the message transmitted will be F0 41 10 00 06 12 01 00 10 03 1D 4F F7 */ const int startByte = token.getPosition() - token.getAdditionalData(); double chTotal = 0.0; uint8 *ptr = (uint8 *)m.getRawData(); for (int i=startByte; i<token.getPosition(); i++) { chTotal = chTotal + *(ptr+i); } const double remainder = fmod(chTotal, 128); const uint8 ch = (uint8)(remainder ? (128 - remainder) : 0); *(ptr+token.getPosition()) = ch; }
void RecordControl::handleEvent(int eventType, MidiMessage& event, int) { const uint8* dataptr = event.getRawData(); int eventId = *(dataptr+2); int eventChannel = *(dataptr+3); //std::cout << "Received event with id=" << eventId << " and ch=" << eventChannel << std::endl; if (eventType == TTL && eventChannel == triggerChannel) { //std::cout << "Trigger!" << std::endl; const MessageManagerLock mmLock; if (eventId == 1) { getControlPanel()->setRecordState(true); } else { getControlPanel()->setRecordState(false); } } }
void PulsePalOutput::handleEvent(int eventType, MidiMessage& event, int sampleNum) { if (eventType == TTL) { // std::cout << "Received an event!" << std::endl; const uint8* dataptr = event.getRawData(); // int eventNodeId = *(dataptr+1); int eventId = *(dataptr+2); int eventChannel = *(dataptr+3); for (int i = 0; i < channelTtlTrigger.size(); i++) { if (eventId == 1 && eventChannel == channelTtlTrigger[i] && channelState[i]) { pulsePal.triggerChannel(i+1); } if (eventChannel == channelTtlGate[i]) { if (eventId == 1) channelState.set(i, true); else channelState.set(i, false); } } } }
static void RT_MIDI_send_msg_to_patch(struct Patch *patch, MidiMessage message, int64_t seq_time){ if (message.isNoteOn()) RT_PATCH_play_note(patch, message.getNoteNumber(), -1, message.getVelocity() / 127.0f, 0.0f, seq_time); else if (message.isNoteOff()) RT_PATCH_stop_note(patch, message.getNoteNumber(), -1, seq_time); else if (message.isAftertouch()) RT_PATCH_change_velocity(patch, message.getNoteNumber(), -1, message.getChannelPressureValue() / 127.0f, seq_time); else { const uint8_t *raw_data = message.getRawData(); int len = message.getRawDataSize(); R_ASSERT_RETURN_IF_FALSE(len>=1 && len<=3); uint32_t msg; if (len==3) msg = MIDI_msg_pack3(raw_data[0],raw_data[1],raw_data[2]); else if (len==2) msg = MIDI_msg_pack2(raw_data[0],raw_data[1]); else if (len==1) msg = MIDI_msg_pack1(raw_data[0]); else return; RT_PATCH_send_raw_midi_message(patch, msg, seq_time); } }
void SpikeDisplayNode::handleEvent(int eventType, MidiMessage& event, int samplePosition) { //std::cout << "Received event of type " << eventType << std::endl; if (eventType == SPIKE) { const uint8_t* dataptr = event.getRawData(); int bufferSize = event.getRawDataSize(); if (bufferSize > 0) { SpikeObject newSpike; bool isValid = unpackSpike(&newSpike, dataptr, bufferSize); if (isValid) { int electrodeNum = newSpike.source; Electrode& e = electrodes.getReference(electrodeNum); // std::cout << electrodeNum << std::endl; bool aboveThreshold = false; // update threshold / check threshold for (int i = 0; i < e.numChannels; i++) { e.detectorThresholds.set(i, float(newSpike.threshold[i])); // / float(newSpike.gain[i])); aboveThreshold = aboveThreshold | checkThreshold(i, e.displayThresholds[i], newSpike); } if (aboveThreshold) { // add to buffer if (e.currentSpikeIndex < displayBufferSize) { // std::cout << "Adding spike " << e.currentSpikeIndex + 1 << std::endl; e.mostRecentSpikes.set(e.currentSpikeIndex, newSpike); e.currentSpikeIndex++; } // save spike if (isRecording) { getProcessorGraph()->getRecordNode()->writeSpike(newSpike,e.recordIndex); } } } } } }
void sendMessageNow (const MidiMessage& message) { if (message.getRawDataSize() > maxEventSize) { maxEventSize = message.getRawDataSize(); snd_midi_event_free (midiParser); snd_midi_event_new (maxEventSize, &midiParser); } snd_seq_event_t event; snd_seq_ev_clear (&event); long numBytes = (long) message.getRawDataSize(); const uint8* data = message.getRawData(); while (numBytes > 0) { const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event); if (numSent <= 0) break; numBytes -= numSent; data += numSent; snd_seq_ev_set_source (&event, 0); snd_seq_ev_set_subs (&event); snd_seq_ev_set_direct (&event); snd_seq_event_output (seqHandle, &event); } snd_seq_drain_output (seqHandle); snd_midi_event_reset_encode (midiParser); }
void sendMessageNow (const MidiMessage& message) { if (message.getRawDataSize() > maxEventSize) { maxEventSize = message.getRawDataSize(); snd_midi_event_free (midiParser); snd_midi_event_new (maxEventSize, &midiParser); } snd_seq_event_t event; snd_seq_ev_clear (&event); snd_midi_event_encode (midiParser, message.getRawData(), message.getRawDataSize(), &event); snd_midi_event_reset_encode (midiParser); snd_seq_ev_set_source (&event, 0); snd_seq_ev_set_subs (&event); snd_seq_ev_set_direct (&event); snd_seq_event_output (seqHandle, &event); snd_seq_drain_output (seqHandle); }
void PhaseDetector::handleEvent(int eventType, MidiMessage& event, int sampleNum) { // MOVED GATING TO PULSE PAL OUTPUT! // now use to randomize phase for next trial //std::cout << "GOT EVENT." << std::endl; if (eventType == TTL) { const uint8* dataptr = event.getRawData(); // int eventNodeId = *(dataptr+1); int eventId = *(dataptr+2); int eventChannel = *(dataptr+3); //int eventTime = event.getTimeStamp(); // // std::cout << "Received event from " << eventNodeId << ", channel " // // << eventChannel << ", with ID " << eventId << std::endl; // if (eventId == 1 && eventChannel == 5) // { // canBeTriggered = true; // } if (eventId == 0 && eventChannel == 5) { triggerOnPeak = randomNumberGenerator.nextBool(); } } }
void PGMidiDevice::PGMidiInputCallback::handleIncomingMidiMessage(MidiInput *source, const MidiMessage &msg) { Logger::getCurrentLogger()->writeToLog("midiin: recv message:"); string dbg = ToHexString(msg.getRawData(), msg.getRawDataSize()); Logger::getCurrentLogger()->writeToLog(dbg); // currently, G1 should only send SysEx to app if (!msg.isSysEx()) return; const uint8 *buf = msg.getSysExData(); int size = msg.getSysExDataSize(); if (!PGSysExParser::IsPGSysEx(buf, size)) return; switch (PGSysExParser::GetOpMsb(buf, size)) { case REPLY_GRP: OwnerMidiDevice->MidiMessageBox.NotifyReply(msg); break; case ACK_GRP: case NAK_GRP: OwnerMidiDevice->MidiMessageBox.NotifyAck(msg); break; default: break; } }
void PhaseDetector::handleEvent(int eventType, MidiMessage& event, int sampleNum) { // MOVED GATING TO PULSE PAL OUTPUT! // now use to randomize phase for next trial //std::cout << "GOT EVENT." << std::endl; if (eventType == TTL) { const uint8* dataptr = event.getRawData(); // int eventNodeId = *(dataptr+1); int eventId = *(dataptr+2); int eventChannel = *(dataptr+3); for (int i = 0; i < modules.size(); i++) { DetectorModule& module = modules.getReference(i); if (module.gateChan == eventChannel) { if (eventId) module.isActive = true; else module.isActive = false; } } } }
void HDF5Recording::writeEvent(int eventType, const MidiMessage& event, int64 timestamp) { const uint8* dataptr = event.getRawData(); if (eventType == GenericProcessor::TTL) eventFile->writeEvent(0,*(dataptr+2),*(dataptr+1),(void*)(dataptr+3),timestamp); else if (eventType == GenericProcessor::MESSAGE) eventFile->writeEvent(1,*(dataptr+2),*(dataptr+1),(void*)(dataptr+6),timestamp); }
const MemoryBlock CtrlrMIDITransaction::getDataFromResponse(const MidiMessage &messageToExtractFrom) { MemoryBlock returnData; MemoryBlock temp(messageToExtractFrom.getRawData(), messageToExtractFrom.getRawDataSize()); returnData.copyFrom (temp.getData(), getResponsePrefixLength(), getResponseDataLength()); return (returnData); }
void HDF5Recording::writeEvent(int eventType, MidiMessage& event, int samplePosition) { const uint8* dataptr = event.getRawData(); if (eventType == GenericProcessor::TTL) mainFile->writeEvent(0,*(dataptr+2),*(dataptr+1),(void*)(dataptr+3),timestamp+samplePosition); else if (eventType == GenericProcessor::MESSAGE) mainFile->writeEvent(1,*(dataptr+2),*(dataptr+1),(void*)(dataptr+4),timestamp+samplePosition); }
const String getRawData(const MidiMessage &m, const bool rawInDecimal) { if (rawInDecimal) { String ret; uint8 *ptr = (uint8 *)m.getRawData(); for (int i=0; i<m.getRawDataSize(); i++) { ret << String::formatted ("%.3d", (int)*(ptr+i)); ret << " "; } return (" RAW:["+ret.trim()+"]"); } else { return (" RAW:["+String::toHexString (m.getRawData(), m.getRawDataSize())+"]"); } }
void SchemeThread::midiin(const MidiMessage &msg) { int op=(msg.getRawData()[0] & 0xf0)>>4; // change NoteOn with 0 amp to NoteOff if (op==MidiFlags::On && msg.getRawData()[2]==0) { op=MidiFlags::Off; msg.getRawData()[0] = (MidiFlags::Off << 4) | (msg.getRawData()[0] & 0xF); } MidiHook* hook=getMidiHook(op); if (hook) { //schemeNodes.lockArray(); schemeNodes.addSorted(comparator, new XMidiNode(0.0, msg, hook)); //schemeNodes.unlockArray(); notify(); } }
void MetronomeProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { const int numSamples = buffer.getNumSamples(); int channel; // convert special metronome bip and bop (0xf2 00 and 0xf2 01) into note on/off messages MidiBuffer metronomeMidiBuffer; MidiBuffer::Iterator iter(midiMessages); MidiMessage message; int pos; while (iter.getNextEvent(message,pos)) { if (message.getRawDataSize()==2 && message.isSongPositionPointer()) { char raw[4] = {0,0,0,0}; char* data = (char*)message.getRawData(); if (data[1]==0) { // bip MidiMessage b = MidiMessage::noteOn(1,80,64.0f); memcpy(raw,b.getRawData(),4); } else { // bop MidiMessage b = MidiMessage::noteOn(1,70,64.0f); memcpy(raw,b.getRawData(),4); } if (raw[0]) { MidiMessage m(raw[0],raw[1],raw[2]); //printf("m %d %d %d at %d\n",m.getRawData()[0],m.getRawData()[1],m.getRawData()[2],pos); metronomeMidiBuffer.addEvent(m,pos); } } } // and now get the synth to process these midi events and generate its output. synth.renderNextBlock (buffer, metronomeMidiBuffer, 0, numSamples); }
void CtrlrSysexProcessorOwned::sysexProcessPrograms(const Array<CtrlrSysexToken> &tokens, MidiMessage &m) { if (tokens.size() != m.getRawDataSize()) return; for (int i=0; i<m.getRawDataSize(); i++) { if (tokens.getReference(i).getType() == CurrentProgram) { uint8 *ptr = (uint8 *)m.getRawData(); *(ptr+tokens.getReference(i).getPosition()) = owner.getCurrentProgramNumber(); } if (tokens.getReference(i).getType() == CurrentBank) { uint8 *ptr = (uint8 *)m.getRawData(); *(ptr+tokens.getReference(i).getPosition()) = owner.getCurrentBankNumber(); } } }
void MidiOutput::sendMessageNow (const MidiMessage& message) { const MidiOutHandle* const handle = static_cast <const MidiOutHandle*> (internal); if (message.getRawDataSize() > 3 || message.isSysEx()) { MIDIHDR h = { 0 }; h.lpData = (char*) message.getRawData(); h.dwBufferLength = message.getRawDataSize(); h.dwBytesRecorded = message.getRawDataSize(); if (midiOutPrepareHeader (handle->handle, &h, sizeof (MIDIHDR)) == MMSYSERR_NOERROR) { MMRESULT res = midiOutLongMsg (handle->handle, &h, sizeof (MIDIHDR)); if (res == MMSYSERR_NOERROR) { while ((h.dwFlags & MHDR_DONE) == 0) Sleep (1); int count = 500; // 1 sec timeout while (--count >= 0) { res = midiOutUnprepareHeader (handle->handle, &h, sizeof (MIDIHDR)); if (res == MIDIERR_STILLPLAYING) Sleep (2); else break; } } } } else { midiOutShortMsg (handle->handle, *(unsigned int*) message.getRawData()); } }
StringTS::StringTS(MidiMessage& event) { const uint8* dataptr = event.getRawData(); int bufferSize = event.getRawDataSize(); len = bufferSize - 20; str = new uint8[len]; memcpy(str, dataptr+6, len); memcpy(×tamp, dataptr +6+ len, 8); }
bool MidiMessageBox::SendMessageAndWaitReply(MidiOutput *out, MidiMessage &msg, int msec) { if (!out) return false; Logger::getCurrentLogger()->writeToLog("midiout: send message and wait reply"); string dbg = ToHexString(msg.getRawData(), msg.getRawDataSize()); Logger::getCurrentLogger()->writeToLog(dbg); std::unique_lock<std::mutex> lck(_mutex); out->sendMessageNow(msg); return std::cv_status::no_timeout == _reply_cv.wait_for(lck, std::chrono::milliseconds(msec)); }
void RecordNode::handleEvent(int eventType, MidiMessage& event, int samplePosition) { if (eventType == TTL) { writeEventBuffer(event, samplePosition); } else if (eventType == TIMESTAMP) { const uint8* dataptr = event.getRawData(); memcpy(×tamp, dataptr, 8); } }
void RecordNode::handleEvent(int eventType, MidiMessage& event, int samplePosition) { if (isRecording && allFilesOpened) { if (isWritableEvent(eventType)) { if (*(event.getRawData()+4) > 0) // saving flag > 0 (i.e., event has not already been processed) { EVERY_ENGINE->writeEvent(eventType, event, samplePosition); } } } }
void MidiOutput::sendMessageNow (const MidiMessage& message) { CoreMidiHelpers::MidiPortAndEndpoint* const mpe = static_cast<CoreMidiHelpers::MidiPortAndEndpoint*> (internal); if (message.isSysEx()) { const int maxPacketSize = 256; int pos = 0, bytesLeft = message.getRawDataSize(); const int numPackets = (bytesLeft + maxPacketSize - 1) / maxPacketSize; HeapBlock <MIDIPacketList> packets; packets.malloc (32 * numPackets + message.getRawDataSize(), 1); packets->numPackets = numPackets; MIDIPacket* p = packets->packet; for (int i = 0; i < numPackets; ++i) { p->timeStamp = 0; p->length = jmin (maxPacketSize, bytesLeft); memcpy (p->data, message.getRawData() + pos, p->length); pos += p->length; bytesLeft -= p->length; p = MIDIPacketNext (p); } mpe->send (packets); } else { MIDIPacketList packets; packets.numPackets = 1; packets.packet[0].timeStamp = 0; packets.packet[0].length = message.getRawDataSize(); *(int*) (packets.packet[0].data) = *(const int*) message.getRawData(); mpe->send (&packets); } }
void CtrlrSysexProcessor::checksumWaldorfRackAttack(const CtrlrSysexToken token, MidiMessage &m) { const int startByte = token.getPosition() - token.getAdditionalData(); int chTotal = 0; uint8 *ptr = (uint8 *)m.getRawData(); for (int i=startByte; i<token.getPosition(); i++) { chTotal = chTotal + *(ptr+i); } *(ptr+token.getPosition()) = chTotal & 0x7f; }
static PyObject * MidiOut_sendMessage(MidiOut *self, PyObject *args) { PyObject *a0 = NULL; if(PyArg_ParseTuple(args, "O", &a0) == 0) return NULL; MidiMessage *created = NULL; // delete if set MidiMessage *midi = NULL; if(PyMidiMessage_Check(a0)) { midi = ((PyMidiMessage *) a0)->m; } else if(PyLong_Check(a0)) { PyErr_SetString(rtmidi_Error, "long ctor args not supported yet."); return NULL; /* int i0 = (int) PyLong_AsUnsignedLong(a0); printf("MidiOut_sendMessage: %i\n", i0); midi = created = new MidiMessage(i0); */ } else { PyErr_SetString(rtmidi_Error, "argument 1 must be of type MidiMessage or a number."); return NULL; } std::vector<unsigned char> outMessage; uint8 *data = midi->getRawData(); for(int i=0; i < midi->getRawDataSize(); ++i) outMessage.push_back((unsigned char) data[i]); try { self->rtmidi->sendMessage(&outMessage); } catch(RtMidiError &error) { PyErr_SetString(rtmidi_Error, error.what()); if(created) delete created; return NULL; } if(created) delete created; Py_RETURN_NONE; }
void CtrlrMIDIDevice::handleIncomingMidiMessage (MidiInput* /*source*/, const MidiMessage& message) { _MIN(getProperty(Ids::name), message, -1); #ifdef JUCE_LINUX uint8 *ptr = (uint8 *)message.getRawData(); if (!message.isSysEx() && *(ptr + (message.getRawDataSize() - 1)) == 0xf7) { dataCollector.append (ptr, message.getRawDataSize()); deviceListeners.call (&CtrlrMIDIDevice::Listener::handleMIDIFromDevice, MidiMessage (dataCollector.getData(), dataCollector.getSize())); return; } #endif if (message.isSysEx()) { #ifdef JUCE_LINUX if (*(ptr + (message.getRawDataSize() - 1)) == 0xf7) { deviceListeners.call (&CtrlrMIDIDevice::Listener::handleMIDIFromDevice, message); } else { dataCollector = MemoryBlock (ptr, message.getRawDataSize()); } #else deviceListeners.call (&CtrlrMIDIDevice::Listener::handleMIDIFromDevice, message); #endif } else { lastMessageWasSysex = false; for (int i=0; i<deviceListeners.size(); i++) { const int ch = deviceListeners.getListeners() [i]->getListenerInputMidiChannel(); if (ch == message.getChannel() || ch == 0 || message.getChannel() == 0) { deviceListeners.getListeners() [i]->handleMIDIFromDevice (message); } } } }
bool CtrlrMIDITransaction::compareMemoryWithWildcard(const MidiMessage &midi, const MemoryBlock &memory) { const uint8 *responsePtr = midi.getRawData(); for (size_t i=0; i<memory.getSize(); i++) { if (memory[i] == 0xff) continue; if (*(responsePtr+i) != memory[i]) return (false); } return (true); }
void RecordNode::handleEvent(int eventType, MidiMessage& event, int samplePosition) { if (isRecording) { if (isWritableEvent(eventType)) { if (*(event.getRawData()+4) > 0) // saving flag > 0 (i.e., event has not already been processed) { uint8 sourceNodeId = event.getNoteNumber(); int64 timestamp = timestamps[sourceNodeId] + samplePosition; m_eventQueue->addEvent(event, timestamp, eventType); } } } }
void CtrlrSysexProcessor::sysExProcess (const Array<CtrlrSysexToken> &tokens, MidiMessage &m, const int value, const int channel) { if (tokens.size() != m.getRawDataSize()) return; uint8 *dataPtr = (uint8 *)m.getRawData(); for (int i=0; i<m.getRawDataSize(); i++) { sysExProcessToken (tokens.getReference(i), dataPtr+i, value, channel); } sysexProcessPrograms(tokens, m); sysexProcessChecksums(tokens, m); }