void Synthesiser::handleMidiEvent (const MidiMessage& m) { if (m.isNoteOn()) { noteOn (m.getChannel(), m.getNoteNumber(), m.getFloatVelocity()); } else if (m.isNoteOff()) { noteOff (m.getChannel(), m.getNoteNumber(), true); } else if (m.isAllNotesOff() || m.isAllSoundOff()) { allNotesOff (m.getChannel(), true); } else if (m.isPitchWheel()) { const int channel = m.getChannel(); const int wheelPos = m.getPitchWheelValue(); lastPitchWheelValues [channel - 1] = wheelPos; handlePitchWheel (channel, wheelPos); } else if (m.isController()) { handleController (m.getChannel(), m.getControllerNumber(), m.getControllerValue()); } }
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 SoftSynthAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { MidiBuffer processedMidi; int time; MidiMessage m; for (MidiBuffer::Iterator i(midiMessages); i.getNextEvent(m, time);) { if (m.isNoteOn()) { m = MidiMessage::noteOn(m.getChannel(), m.getNoteNumber(), m.getVelocity()); synth.keyPressed(m.getNoteNumber(), m.getVelocity()); } else if (m.isNoteOff()) { m = MidiMessage::noteOff(m.getChannel(), m.getNoteNumber(), m.getVelocity()); synth.keyReleased(m.getNoteNumber()); } processedMidi.addEvent(m, time); } auto synthBuffer = synth.getNextBuffer(buffer.getNumSamples()); float *leftData = buffer.getWritePointer(0); float *rightData = buffer.getWritePointer(1); for (int i = 0; i < buffer.getNumSamples(); ++i) { leftData[i] = synthBuffer[i]; rightData[i] = synthBuffer[i]; } midiMessages.swapWith(processedMidi); }
bool MidiControlAction::processIncomingMessage(const MidiMessage& message) { if (isLearning) { isLearning = false; messageTemplate = message; return true; } else if (message.isForChannel(messageTemplate.getChannel())) { if (messageTemplate.isNoteOnOrOff() && message.isNoteOnOrOff() && message.getNoteNumber() == messageTemplate.getNoteNumber()) { // toggle! if (message.isNoteOn() && message.getNoteNumber() == messageTemplate.getNoteNumber()) { getMappedComponent()->setValue(getMappedComponent()->getValue() >= 0.5f?0.f:1.f); getMappedComponent()->triggerAsyncUpdate(); } return true; } else if (messageTemplate.isController() && message.isController() && messageTemplate.getControllerNumber() == message.getControllerNumber()) { //setValue(message.getControllerValue() / 127.0f); getMappedComponent()->setValue(message.getControllerValue() / 127.0f); getMappedComponent()->triggerAsyncUpdate(); return true; } } return false; }
void RubberbandAudioSource::processNextAudioBlock() { const int numRequired = m_stretcher->getSamplesRequired(); if ( numRequired > 0 ) { AudioSourceChannelInfo info; info.buffer = &m_inSampleBuffer; info.startSample = 0; info.numSamples = qMin( m_inSampleBuffer.getNumFrames(), numRequired ); m_source->getNextAudioBlock( info, m_midiBuffer ); if ( m_midiBuffer.isEmpty() ) { m_stretcher->process( m_inSampleBuffer.getArrayOfReadPointers(), info.numSamples, false ); } else { MidiBuffer::Iterator iterator( m_midiBuffer ); MidiMessage message; int startFrame = info.startSample; int numFramesLeftToGo = info.numSamples; while ( numFramesLeftToGo > 0 ) { int eventPos; const bool isEventValid = iterator.getNextEvent( message, eventPos ) && message.isNoteOn() && eventPos < info.numSamples; const int numFramesToProcess = isEventValid ? eventPos - startFrame : numFramesLeftToGo; if ( numFramesToProcess > 0 ) { for ( int chanNum = 0; chanNum < m_numChans; chanNum++ ) { m_inFloatBuffer[ chanNum ] = m_inSampleBuffer.getReadPointer( chanNum, startFrame ); } m_stretcher->process( m_inFloatBuffer, numFramesToProcess, false ); } if ( isEventValid ) { m_noteTimeRatio = m_noteTimeRatioTable.value( message.getNoteNumber(), 1.0 ); m_stretcher->setTimeRatio( m_globalTimeRatio * m_noteTimeRatio ); } startFrame += numFramesToProcess; numFramesLeftToGo -= numFramesToProcess; } } } else // numRequired == 0 { m_stretcher->process( m_inSampleBuffer.getArrayOfReadPointers(), 0, false ); } }
void MidiKeyboardState::processNextMidiEvent (const MidiMessage& message) { if (message.isNoteOn()) { noteOnInternal (message.getChannel(), message.getNoteNumber(), message.getFloatVelocity()); } else if (message.isNoteOff()) { noteOffInternal (message.getChannel(), message.getNoteNumber(), message.getFloatVelocity()); } else if (message.isAllNotesOff()) { for (int i = 0; i < 128; ++i) noteOffInternal (message.getChannel(), i, 0.0f); } }
void MIDIMostRecentNoteInternal::handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message) throw() { if(port_ != 0 && port_ != source) return; if(message.isForChannel(midiChannel_) == false) return; if(message.isNoteOn() == false) return; setNormalisedValue(message.getNoteNumber() / 127.f); }
void MidiManager::processMidiMessage(const MidiMessage& midi_message, int sample_position) { if (midi_message.isProgramChange()) { current_patch_ = midi_message.getProgramChangeNumber(); File patch = LoadSave::loadPatch(current_bank_, current_folder_, current_patch_, synth_, *gui_state_); PatchLoadedCallback* callback = new PatchLoadedCallback(listener_, patch); callback->post(); return; } if (midi_message.isNoteOn()) { engine_->noteOn(midi_message.getNoteNumber(), midi_message.getVelocity() / (mopo::MIDI_SIZE - 1.0), 0, midi_message.getChannel() - 1); } else if (midi_message.isNoteOff()) engine_->noteOff(midi_message.getNoteNumber()); else if (midi_message.isAllNotesOff()) engine_->allNotesOff(); else if (midi_message.isSustainPedalOn()) engine_->sustainOn(); else if (midi_message.isSustainPedalOff()) engine_->sustainOff(); else if (midi_message.isAftertouch()) { mopo::mopo_float note = midi_message.getNoteNumber(); mopo::mopo_float value = (1.0 * midi_message.getAfterTouchValue()) / mopo::MIDI_SIZE; engine_->setAftertouch(note, value); } else if (midi_message.isPitchWheel()) { double percent = (1.0 * midi_message.getPitchWheelValue()) / PITCH_WHEEL_RESOLUTION; double value = 2 * percent - 1.0; engine_->setPitchWheel(value, midi_message.getChannel()); } else if (midi_message.isController()) { int controller_number = midi_message.getControllerNumber(); if (controller_number == MOD_WHEEL_CONTROL_NUMBER) { double percent = (1.0 * midi_message.getControllerValue()) / MOD_WHEEL_RESOLUTION; engine_->setModWheel(percent, midi_message.getChannel()); } else if (controller_number == BANK_SELECT_NUMBER) current_bank_ = midi_message.getControllerValue(); else if (controller_number == FOLDER_SELECT_NUMBER) current_folder_ = midi_message.getControllerValue(); midiInput(midi_message.getControllerNumber(), midi_message.getControllerValue()); } }
void VoicerUGenInternal::handleIncomingMidiMessage (MidiInput* /*source*/, const MidiMessage& message) throw() { if(message.isForChannel(midiChannel_) == false) return; if(message.isNoteOnOrOff()) { const ScopedLock sl(lock); sendMidiNote(message.getChannel(), message.getNoteNumber(), message.getVelocity()); } else if(message.isController()) { if((message.getControllerNumber() == 123) && (message.getControllerValue() == 0)) { const ScopedLock sl(lock); initEvents(); } getController(message.getControllerNumber()) = (message.getControllerValue() * (1.f / 127.f)); } else if(message.isPitchWheel()) { getPitchWheel() = (jlimit(-8191, 8191, message.getPitchWheelValue() - 8192) * (1.f / 8191.f)); } else if(message.isChannelPressure()) { getChannelPressure() = (message.getChannelPressureValue() * (1.f / 127.f)); } else if(message.isAftertouch()) { getKeyPressure(message.getNoteNumber()) = (message.getAfterTouchValue() * (1.f / 127.f)); } else if(message.isProgramChange()) { getProgram() = (message.getProgramChangeNumber()); } else if(message.isAllNotesOff()) { const ScopedLock sl(lock); initEvents(); } }
void Loop::sendCurrentNoteToBuffer(MidiBuffer& buffer, int sample_number, int velocity) { MidiMessage m = this->getEventPointer(currentIndex)->message; //playingNote[m.getNoteNumber()][m.getChannel()-1][0] = jlimit(0,127,m.getNoteNumber()+getTransposition()); m.setNoteNumber(jlimit(0,127,m.getNoteNumber()+getTransposition())); m.setVelocity((((float)velocity*midiScaler * velocitySensitivity) + (1.f-velocitySensitivity))); if (outChannel>0) m.setChannel(outChannel); buffer.addEvent(m,sample_number); indexOfLastNoteOn=currentIndex; }
void Tunefish4AudioProcessor::processEvents(MidiBuffer &midiMessages, eU32 messageOffset, eU32 frameSize) { MidiBuffer::Iterator it(midiMessages); MidiMessage midiMessage; int samplePosition; it.setNextSamplePosition(messageOffset); while (it.getNextEvent(midiMessage, samplePosition)) { if (samplePosition >= messageOffset + frameSize) break; if (midiMessage.isNoteOn()) { eU8 velocity = midiMessage.getVelocity(); eU8 note = midiMessage.getNoteNumber(); eTfInstrumentNoteOn(*tf, note, velocity); } else if (midiMessage.isNoteOff()) { eU8 note = midiMessage.getNoteNumber(); eTfInstrumentNoteOff(*tf, note); } else if (midiMessage.isAllNotesOff()) { eTfInstrumentAllNotesOff(*tf); } else if (midiMessage.isPitchWheel()) { eS32 bend_lsb = midiMessage.getRawData()[1] & 0x7f; eS32 bend_msb = midiMessage.getRawData()[2] & 0x7f; eTfInstrumentPitchBend(*tf, ((eF32(bend_msb) / 127.0f) - 0.5f) * 2.0f, ((eF32(bend_lsb) / 127.0f) - 0.5f) * 2.0f); } } }
void Synthesiser::handleMidiEvent (const MidiMessage& m) { const int channel = m.getChannel(); if (m.isNoteOn()) { noteOn (channel, m.getNoteNumber(), m.getFloatVelocity()); } else if (m.isNoteOff()) { noteOff (channel, m.getNoteNumber(), m.getFloatVelocity(), true); } else if (m.isAllNotesOff() || m.isAllSoundOff()) { allNotesOff (channel, true); } else if (m.isPitchWheel()) { const int wheelPos = m.getPitchWheelValue(); lastPitchWheelValues [channel - 1] = wheelPos; handlePitchWheel (channel, wheelPos); } else if (m.isAftertouch()) { handleAftertouch (channel, m.getNoteNumber(), m.getAfterTouchValue()); } else if (m.isChannelPressure()) { handleChannelPressure (channel, m.getChannelPressureValue()); } else if (m.isController()) { handleController (channel, m.getControllerNumber(), m.getControllerValue()); } else if (m.isProgramChange()) { handleProgramChange (channel, m.getProgramChangeNumber()); } }
const String getMidiNumber(const MidiMessage &m) { if (m.isAftertouch()) { return (String::formatted (" No:[%4d]", m.getNoteNumber())); } if (m.isController()) { return (String::formatted (" No:[%4d]", m.getControllerNumber())); } if (m.isNoteOnOrOff()) { return (String::formatted (" No:[%4d]", m.getNoteNumber())); } if (m.isProgramChange()) { return (String::formatted (" No:[%4d]", m.getProgramChangeNumber())); } return (" No:[----]"); }
String ZenMidiVisualiserComponent::getMidiMessageDescription(const MidiMessage& m) { if (m.isNoteOn()) return "Note on: " + S(m.getNoteNumber()) + " (" + MidiMessage::getMidiNoteName(m.getNoteNumber(), true, true, 3) + ") Vel: " + S(m.getVelocity()); if (m.isNoteOff()) return "Note off: " + S(m.getNoteNumber()) + " (" + MidiMessage::getMidiNoteName(m.getNoteNumber(), true, true, 3) + ")"; if (m.isProgramChange()) return "Program change (Number): " + String(m.getProgramChangeNumber()); if (m.isPitchWheel()) return "Pitch wheel: " + String(m.getPitchWheelValue()); if (m.isAftertouch()) return "After touch: " + MidiMessage::getMidiNoteName(m.getNoteNumber(), true, true, 3) + ": " + String(m.getAfterTouchValue()); if (m.isChannelPressure()) return "Channel pressure: " + String(m.getChannelPressureValue()); if (m.isAllNotesOff()) return "All notes off"; if (m.isAllSoundOff()) return "All sound off"; if (m.isMetaEvent()) return "Meta event"; if (m.isController()) { String temp = MidiMessage::getControllerName(m.getControllerNumber()); String name = "Controller [" + S(m.getControllerNumber()) + "]"; if (!temp.isEmpty()) name += " " + temp; return name + ": " + String(m.getControllerValue()); } return String::toHexString(m.getRawData(), m.getRawDataSize()); }
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 RecordNode::writeEventBuffer(MidiMessage& event, int samplePosition) //, int node, int channel) { // find file and write samples to disk // std::cout << "Received event!" << std::endl; if (eventChannel->file == NULL) return; const uint8* dataptr = event.getRawData(); if (event.getNoteNumber() > 0) // processor ID > 0 { uint64 samplePos = (uint64) samplePosition; int64 eventTimestamp = timestamp + samplePos; // add the sample position to the buffer timestamp diskWriteLock.enter(); fwrite(&eventTimestamp, // ptr 8, // size of each element 1, // count eventChannel->file); // ptr to FILE object fwrite(&samplePos, // ptr 2, // size of each element 1, // count eventChannel->file); // ptr to FILE object // write 1st four bytes of event (type, nodeId, eventId, eventChannel) fwrite(dataptr, 1, 4, eventChannel->file); // write recording number fwrite(&recordingNumber, // ptr 2, // size of each element 1, // count eventChannel->file); // ptr to FILE object diskWriteLock.exit(); } }
static PyObject * PyMidiMessage_str(PyObject *self) { MidiMessage *m = ((PyMidiMessage*)self)->m; static char s[256]; if(m->isNoteOn()) { sprintf(s, "<NOTE ON, note: %d (%s), velocity: %d, channel: %d>", m->getNoteNumber(), m->getMidiNoteName(m->getNoteNumber(), true, true, 3), m->getVelocity(), m->getChannel()); } else if(m->isNoteOff()) { sprintf(s, "<NOTE OFF, note: %d (%s), channel: %d>", m->getNoteNumber(), m->getMidiNoteName(m->getNoteNumber(), true, true, 3), m->getChannel()); } else if(m->isProgramChange()) { sprintf(s, "<PROGRAM CHANGE: program: %d, channel: %d>", m->getProgramChangeNumber(), m->getChannel()); } else if(m->isPitchWheel()) { sprintf(s, "<PITCH WHEEL: value: %d, channel: %d>", m->getPitchWheelValue(), m->getChannel()); } else if(m->isAftertouch()) { sprintf(s, "<AFTERTOUCH: note: %d (%s) value: %d, channel: %d>", m->getNoteNumber(), m->getMidiNoteName(m->getNoteNumber(), true, true, 3), m->getAfterTouchValue(), m->getChannel()); } else if(m->isChannelPressure()) { sprintf(s, "<CHANNEL PRESSURE: pressure: %d, channel: %d>", m->getChannelPressureValue(), m->getChannel()); } else if(m->isController()) { const char *name = m->getControllerName(m->getControllerNumber()); if(strlen(name) > 0) { sprintf(s, "<CONTROLLER: %d (\"%s\"), value: %d, channel: %d>", m->getControllerNumber(), m->getControllerName(m->getControllerNumber()), m->getControllerValue(), m->getChannel()); } else { sprintf(s, "<CONTROLLER: %d, value: %d, channel: %d>", m->getControllerNumber(), m->getControllerValue(), m->getChannel()); } } else { sprintf(s, "<MidiMessage (misc type)>"); } return PK_STRING(s); }
void LyrebirdAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { // Do Midi things buffer.clear(); int time; MidiMessage m; for (MidiBuffer::Iterator i (midiMessages); i.getNextEvent (m, time);) { sawGenerator->setWavelength(currentSampleRate, m.getMidiNoteInHertz(m.getNoteNumber())); if (m.isNoteOff()) { sawGenerator->setWavelength(currentSampleRate, 0); } } // In case we have more outputs than inputs, this code clears any output // channels that didn't contain input data, (because these aren't // guaranteed to be empty - they may contain garbage). // I've added this to avoid people getting screaming feedback // when they first compile the plugin, but obviously you don't need to // this code if your algorithm already fills all the output channels. for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i) buffer.clear (i, 0, buffer.getNumSamples()); float* leftData = buffer.getWritePointer (0); float* rightData = buffer.getWritePointer(1); for (int sample = 0; sample < buffer.getNumSamples(); sample++) { leftData[sample] = sawGenerator->getCurrentAmplitude(); rightData[sample] = sawGenerator->getCurrentAmplitude(); sawGenerator->incrementSaw(); } }
const int getMidiNumberFromMidiMessage (const MidiMessage &m) { switch (midiMessageToType(m)) { case CC: return (m.getControllerNumber()); break; case NoteOn: case NoteOff: case Aftertouch: return (m.getNoteNumber()); break; case PitchWheel: case ProgramChange: case ChannelPressure: case SysEx: default: break; } return (-1); }
static String getMidiMessageDescription (const MidiMessage& m) { if (m.isNoteOn()) return "Note on " + MidiMessage::getMidiNoteName (m.getNoteNumber(), true, true, 3); if (m.isNoteOff()) return "Note off " + MidiMessage::getMidiNoteName (m.getNoteNumber(), true, true, 3); if (m.isProgramChange()) return "Program change " + String (m.getProgramChangeNumber()); if (m.isPitchWheel()) return "Pitch wheel " + String (m.getPitchWheelValue()); if (m.isAftertouch()) return "After touch " + MidiMessage::getMidiNoteName (m.getNoteNumber(), true, true, 3) + ": " + String (m.getAfterTouchValue()); if (m.isChannelPressure()) return "Channel pressure " + String (m.getChannelPressureValue()); if (m.isAllNotesOff()) return "All notes off"; if (m.isAllSoundOff()) return "All sound off"; if (m.isMetaEvent()) return "Meta event"; if (m.isController()) { String name (MidiMessage::getControllerName (m.getControllerNumber())); if (name.isEmpty()) name = "[" + String (m.getControllerNumber()) + "]"; return "Controler " + name + ": " + String (m.getControllerValue()); } return String::toHexString (m.getRawData(), m.getRawDataSize()); }
void InstanceProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { for(int i = getTotalNumInputChannels(); i < getTotalNumOutputChannels(); ++i) { buffer.clear(i, 0, buffer.getNumSamples()); } bool infos = false; AudioPlayHead* playhead = getPlayHead(); if(playhead && m_patch_tie) { infos = playhead->getCurrentPosition(m_playinfos); } lock(); { m_midi.clear(); if(infos) { m_playing_list.setFloat(0, m_playinfos.isPlaying); m_playing_list.setFloat(1, m_playinfos.timeInSeconds); sendMessageAnything(m_patch_tie, s_playing, m_playing_list); m_measure_list.setFloat(0, m_playinfos.bpm); m_measure_list.setFloat(1, m_playinfos.timeSigNumerator); m_measure_list.setFloat(2, m_playinfos.timeSigDenominator); m_measure_list.setFloat(3, m_playinfos.ppqPosition); m_measure_list.setFloat(4, m_playinfos.ppqPositionOfLastBarStart); sendMessageAnything(m_patch_tie, s_measure, m_measure_list); } for(size_t i = 0; i < m_parameters.size() && m_parameters[i].isValid(); ++i) { sendMessageFloat(m_parameters[i].getTie(), m_parameters[i].getValueNonNormalized()); } MidiMessage message; MidiBuffer::Iterator it(midiMessages); int position = midiMessages.getFirstEventTime(); while(it.getNextEvent(message, position)) { if(message.isNoteOnOrOff()) { sendMidiNote(message.getChannel(), message.getNoteNumber(), message.getVelocity()); } else if(message.isController()) { sendMidiControlChange(message.getChannel(), message.getControllerNumber(), message.getControllerValue()); } else if(message.isPitchWheel()) { sendMidiPitchBend(message.getChannel(), message.getPitchWheelValue()); } else if(message.isChannelPressure()) { sendMidiAfterTouch(message.getChannel(), message.getChannelPressureValue()); } else if(message.isAftertouch()) { sendMidiPolyAfterTouch(message.getChannel(), message.getNoteNumber(), message.getAfterTouchValue()); } else if(message.isProgramChange()) { sendMidiProgramChange(message.getChannel(), message.getProgramChangeNumber()); } } } midiMessages.clear(); performDsp(buffer.getNumSamples(), getTotalNumInputChannels(), buffer.getArrayOfReadPointers(), getTotalNumOutputChannels(), buffer.getArrayOfWritePointers()); midiMessages.swapWith(m_midi); unlock(); }
void PianoRoll::mouseUp (const MouseEvent& e) { int highnote,lownote; if (lasso.getWidth()>0) { lownote = (int)((float)(getHeight()-lasso.getY())*128.f/(float)getHeight()); highnote = (int)((float)(getHeight()-(lasso.getY()+lasso.getHeight()))*128.f/(float)getHeight()); if (lownote>highnote) swapVariables(lownote,highnote); for (int index=0;index<(sequence->getNumEvents());index++) { MidiMessage m = sequence->getEventPointer(index)->message; DBG("eventtime=" + String(sequence->getEventTime(index))); if (m.isNoteOn()) {DBG("note=" + String(m.getNoteNumber()));} DBG("lassostart=" + String(pixelsToPpq((float)lasso.getX(),false))); DBG("lassoend=" + String(pixelsToPpq((float)(lasso.getX()+lasso.getWidth()),false))); if (m.isNoteOn() && sequence->getEventTime(index)>=pixelsToPpq((float)lasso.getX(),false) && sequence->getEventTime(index)<=pixelsToPpq((float)(lasso.getX()+lasso.getWidth()),false) && m.getNoteNumber()>=lownote && m.getNoteNumber()<=highnote) { addToSelection(sequence->getEventPointer(index)); } } lasso.setSize(0,0); repaint(); noteLayer->repaint(); } if (hoveringNoteIndex != No_Note) { if (hoveringNoteIndex<-2) hoveringNoteIndex+=9999; if (e.mods.isPopupMenu() && hoveringNoteIndex!=-2) { //right click, delete notes plugin->getCallbackLock().enter(); for (int i=selectedNotes.size();--i>=0;) sequence->deleteEvent(sequence->getIndexOf(selectedNotes.getUnchecked(i)),true); sequence->updateMatchedPairs(); plugin->getCallbackLock().exit(); clearSelection(); } else { if (draggingNoteTimeDelta!=0 || draggingNoteTransposition!=0) { plugin->getCallbackLock().enter(); if (draggingNoteTimeDelta!=0.0) { for (int i=0;i<selectedNotes.size();i++) { selectedNotes.getUnchecked(i)->message.addToTimeStamp(draggingNoteTimeDelta); selectedNotes.getUnchecked(i)->noteOffObject->message.addToTimeStamp(draggingNoteTimeDelta); //sequence->moveEvent(sequence->getIndexOf(selectedNotes.getUnchecked(i)),draggingNoteTimeDelta,true); } draggingNoteTimeDelta=0.0; } if (draggingNoteTransposition!=0) { for (int i=0;i<selectedNotes.size();i++) sequence->transposeEvent(sequence->getIndexOf(selectedNotes.getUnchecked(i)),draggingNoteTransposition); draggingNoteTransposition=0; } sequence->updateMatchedPairs(true); plugin->getCallbackLock().exit(); } else if (wasResizing || e.mods.isAltDown()) { //resize notes wasResizing=false; for (int i=selectedNoteLengths.size();--i>=0;) { if (selectedNotes.getUnchecked(i)!=0 && selectedNotes.getUnchecked(i)->noteOffObject!=0) { selectedNoteLengths.getReference(i).updateLength(); } else { selectedNotes.remove(i); selectedNoteLengths.remove(i); } } plugin->getCallbackLock().enter(); sequence->updateMatchedPairs(true); plugin->getCallbackLock().exit(); } } hoveringNoteIndex = No_Note; hoveringNote=0; sendChangeMessage(); noteLayer->repaint(); } }
void MIDIReceiver::handleIncomingMidiMessage (MidiInput *source, const MidiMessage &message) { DBG("midi in"); // is this midi input source enabled if(_MidiDeviceManager->isMidiInputEnabled(source->getName())) { DBG(source->getName()); if(message.isController() && _MidiDeviceManager->isCcEnabled(source->getName(), true) && appProperties->getUserSettings()->getIntValue("midiInputChannel") == message.getChannel()) { DBG(message.getControllerNumber() ); // reference counted Signal ( string command, string origin ) Signal::SignalP ledStateSignal = new Signal("SEND_OSC", "RCV_MIDI"); ledStateSignal->addStringArg("/nomestate/grid/led/set"); // get the x position: LED bumber % 8 ledStateSignal->addIntArg(message.getControllerNumber() % 8); // get the y position: LED number / 8 ledStateSignal->addIntArg(message.getControllerNumber() / 8); // get the LED state: toggleState int ledState; if (message.getControllerValue() > 0) { ledState = 1; } ledStateSignal->addIntArg(ledState); _mCenter->handleSignal(*ledStateSignal); } else if (message.isNoteOn() && _MidiDeviceManager->isNoteEnabled(source->getName(), true) && appProperties->getUserSettings()->getIntValue("midiInputChannel") == message.getChannel()) { // lets set the color based off MIDI note Velocity int MIDIVelocity = message.getVelocity(); int r = 0; int g = 0; int b = 0; if (MIDIVelocity > 0) { // red if (MIDIVelocity <= 22) { r = 127; } // yellow else if (MIDIVelocity <= 43) { r = 127; g = 127; } // green else if (MIDIVelocity <= 64) { g = 127; } // teal else if (MIDIVelocity <= 85) { g = 127; b = 127; } // blue else if (MIDIVelocity <= 106) { b = 127; } // purple else { b = 127; r = 127; } } // reference counted Signal ( string command, string origin ) Signal::SignalP ledColourSignal = new Signal("SEND_OSC", "RCV_MIDI"); ledColourSignal->addStringArg("/nomestate/grid/led/color"); // get the x position: LED bumber % 8 ledColourSignal->addIntArg(message.getNoteNumber() % 8); // get the y position: LED number / 8 ledColourSignal->addIntArg(message.getNoteNumber() / 8); // get the LED RED: ledColourSignal->addIntArg(r); // get the LED GREEN: ledColourSignal->addIntArg(g); // get the LED BLUE: ledColourSignal->addIntArg(b); _mCenter->handleSignal(*ledColourSignal); // reference counted Signal ( string command, string origin ) Signal::SignalP ledStateSignal = new Signal("SEND_OSC", "RCV_MIDI"); ledStateSignal->addStringArg("/nomestate/grid/led/set"); // get the x position: LED bumber % 8 ledStateSignal->addIntArg(message.getNoteNumber() % 8); // get the y position: LED number / 8 ledStateSignal->addIntArg(message.getNoteNumber() / 8); // get the LED state: toggleState ledStateSignal->addIntArg(1); _mCenter->handleSignal(*ledStateSignal); } else if (message.isNoteOff() && _MidiDeviceManager->isNoteEnabled(source->getName(), true) && appProperties->getUserSettings()->getIntValue("midiInputChannel") == message.getChannel()) { // reference counted Signal ( string command, string origin ) Signal::SignalP ledStateSignal = new Signal("SEND_OSC", "RCV_MIDI"); ledStateSignal->addStringArg("/nomestate/grid/led/set"); // get the x position: LED bumber % 8 ledStateSignal->addIntArg(message.getNoteNumber() % 8); // get the y position: LED number / 8 ledStateSignal->addIntArg(message.getNoteNumber() / 8); // get the LED state: toggleState ledStateSignal->addIntArg(0); _mCenter->handleSignal(*ledStateSignal); } } }
void JenSx1000AudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { int time; MidiMessage m; for (MidiBuffer::Iterator i (midiMessages); i.getNextEvent (m, time);) { if (m.isNoteOn()) { int lastMidiNote = m.getNoteNumber(); DBG("MIDI note triggered : " << lastMidiNote << "\n"); heldNotes.insert(lastMidiNote); } else if (m.isNoteOff()) { int releasedNote = m.getNoteNumber(); DBG("MIDI note released : " << releasedNote << "\n"); heldNotes.erase(releasedNote); } else if (m.isAftertouch()) { } else if (m.isPitchWheel()) { } } int highestHeldNote; if (heldNotes.empty()){ if (currentNote > 0){ DBG("Note released"); ampEnvelope.release(); vcf.release(); currentNote = -1000; nextNote = -2000; } } else { highestHeldNote = *heldNotes.rbegin(); if (nextNote != highestHeldNote){ nextNote = highestHeldNote; noClick.start(); } } std::vector<float*> ChannelData; for (int i = 0; i < getNumOutputChannels(); i++){ ChannelData.push_back(buffer.getWritePointer(i)); } for (int sample = 0; sample < buffer.getNumSamples(); ++sample){ if (!heldNotes.empty() && currentNote != nextNote && noClick.fadingIn()){ currentNote = nextNote; freqControl.setNote(currentNote); ampEnvelope.begin(); vcf.begin(); } float nextLFOSample = lfo.getNextSample(); freqControl.setNextVibratoOscSample(nextLFOSample); vcf.setNextLFOSample(nextLFOSample); oscillator.setNextPWMSample(nextLFOSample); float nextNoClickSample = noClick.getNextSample(); oscillator.updateFrequency(freqControl.getNextFrequency()); float nextOscSample = oscillator.getNextSample(); float nextNoiseSample = noise.getNextSample(); float nextAmpSample = ampEnvelope.getNextSample(); float nextSample = (vcf.processNextSample((nextOscSample * vcoLevel) + (nextNoiseSample * noiseLevel)) * nextAmpSample) * ampLevel *nextNoClickSample; for (float* channel : ChannelData){ channel[sample] = nextSample; } } }
void RemoteGoatVstAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { //if (!midiMessages.isEmpty()) //{ // String trace; // trace << "MIDI:"; // for (int i = 0; i < midiMessages.data.size(); ++i) // { // trace << String::formatted(" %02X", midiMessages.data[i]); // } // writeTrace(trace); //} // For each sample name, // a sorted collection of "note on" event sample positions. std::map<String, std::set<std::pair<int, bool>>> noteOnSets; MidiBuffer::Iterator it(midiMessages); MidiMessage midiMessage; int samplePosition; while (it.getNextEvent(midiMessage, samplePosition)) { // Check note number, map to sample name. int note = midiMessage.getNoteNumber(); auto itt = _noteNumberSampleNameMap.find(note); if (itt != _noteNumberSampleNameMap.end()) { String sampleName = itt->second; if (midiMessage.isNoteOn()) // Save note on sample position for sample. noteOnSets[sampleName].insert(std::make_pair(samplePosition, true)); else if (midiMessage.isNoteOff()) noteOnSets[sampleName].insert(std::make_pair(samplePosition, false)); } } midiMessages.clear(); buffer.clear(0, 0, buffer.getNumSamples()); buffer.clear(1, 0, buffer.getNumSamples()); for (auto& samplePair : _samples) { Sample& sample = samplePair.second; auto noteOnSetsIterator = noteOnSets.find(sample.getName()); if (noteOnSetsIterator != noteOnSets.end()) { const std::set<std::pair<int, bool>>& noteOns = noteOnSetsIterator->second; int offset = noteOns.begin()->first; sample.read(buffer, 0, offset, false); for (auto noteOnIterator = noteOns.begin(); noteOnIterator != noteOns.end(); ++noteOnIterator) { int noteOn = noteOnIterator->first; bool onOrOff = noteOnIterator->second; writeTrace(String() << "Triggered " << sample.getName() + " (" << (int)onOrOff << ")"); auto nextNoteOnIterator = noteOnIterator; ++nextNoteOnIterator; if (nextNoteOnIterator != noteOns.end()) { int nextNoteOn = nextNoteOnIterator->first; int diff = nextNoteOn - noteOn; if (onOrOff) sample.read(buffer, offset, diff, true); else sample.noteOff(); offset += diff; } else { if (onOrOff) sample.read(buffer, offset, buffer.getNumSamples() - offset, true); else sample.noteOff(); } } } else { sample.read(buffer, 0, buffer.getNumSamples(), false); } } }
int main(int argc, char **argv) { if (argc < 2) { printf("Usage %s file.mid\n", argv[0]); return(-1); } const char *l_pszFileName = argv[1]; File file(l_pszFileName); const double mm_per_second = 1000.0 / 60.0; // How fast does the tape move through the music box? (1 meter per minute - by observation) const double distance_between_notes_in_mm = 2.0; // across the paper. const double min_distance_between_notes = 7.0; // Cannot have two consecutive notes appear less than this distance between each other. std::list<std::string> gcode; std::list<std::string> heeks; int id=1; typedef std::vector<std::string> Keys_t; Keys_t keys, legal_keys; Keys_t::size_type middle_c_key; // Which integer tells us it's the 'C' in the middle or the 'C' in the // octave above or below. const int middle_c_octave = 5; for (int octave=2; octave <= 8; octave++) { for (char key='A'; key<='G'; key++) { std::ostringstream l_ossKey; // l_ossKey << key << middle_c_octave - 0; l_ossKey << key << octave; keys.push_back( l_ossKey.str() ); if ((key == 'C') && (octave == middle_c_octave)) middle_c_key = keys.size()-1; } } // Setup our scale of notes that will work with the music box. It covers from 'C' to 'C' over two octaves. // Octave below middle C for (char key='C'; key<='G'; key++) { std::ostringstream l_ossKey; l_ossKey << key << middle_c_octave - 1; legal_keys.push_back( l_ossKey.str() ); } // Octave that includes middle C for (char key='A'; key<='G'; key++) { std::ostringstream l_ossKey; l_ossKey << key << middle_c_octave - 0; legal_keys.push_back( l_ossKey.str() ); } // Octave above middle C for (char key='A'; key<='C'; key++) { std::ostringstream l_ossKey; l_ossKey << key << middle_c_octave + 1; legal_keys.push_back( l_ossKey.str() ); } const double track_width = distance_between_notes_in_mm * keys.size(); const double space_between_tracks = track_width * 0.75; MidiFile midi_file; FileInputStream midi_input_stream(file); if (! midi_file.readFrom( midi_input_stream )) { fprintf(stderr,"Could not open '%s' for reading\n", l_pszFileName); return(-1); } midi_file.convertTimestampTicksToSeconds(); std::set<int> notes; double time_scale = 1.0; bool time_scale_changed = false; do { std::map<std::string, double> key_position; time_scale_changed = false; gcode.clear(); heeks.clear(); key_position.clear(); std::ostringstream l_ossGCode; for (int track = 0; track<midi_file.getNumTracks(); track++) { int number_of_notes_included = 0; int number_of_notes_ignored = 0; const MidiMessageSequence *pMessageSequence = midi_file.getTrack(track); double start_time = pMessageSequence->getStartTime(); double end_time = pMessageSequence->getEndTime(); double duration = end_time - start_time; if (duration <= 0.0001) continue; l_ossGCode.str(""); l_ossGCode << "(Duration of track " << track << " is " << duration << " seconds)"; gcode.push_back( l_ossGCode.str() ); printf("%s\n", l_ossGCode.str().c_str()); // printf("Duration of track %d is %lf seconds\n", track, duration); for (int event = 0; event < pMessageSequence->getNumEvents(); event++) { MidiMessageSequence::MidiEventHolder *pEvent = pMessageSequence->getEventPointer(event); MidiMessage message = pEvent->message; double time_stamp = message.getTimeStamp(); if (message.isTextMetaEvent()) { String text = message.getTextFromTextMetaEvent(); char buf[1024]; memset( buf, '\0', sizeof(buf) ); text.copyToBuffer( buf, sizeof(buf)-1 ); // printf("Track %d is %s\n", track, buf ); l_ossGCode.str(""); l_ossGCode << "(Text track " << track << " is " << buf << ")"; gcode.push_back(l_ossGCode.str()); printf("%s\n", l_ossGCode.str().c_str()); std::ostringstream l_ossHeeks; l_ossHeeks << "<Text text=\"" << buf << "\" font=\"OpenGL\" col=\"0\" m0=\"-0.0443342566\" m1=\"-0.999016753\" m2=\"0\" m3=\"" << (double) (time_stamp * mm_per_second) << "\" m4=\"0.999016753\" m5=\"-0.0443342566\" m6=\"0\" m7=\"" << (double) ((track_width + space_between_tracks) * track) << "\" m8=\"0\" m9=\"0\" ma=\"1\" mb=\"0\" id=\"" << id++ << "\" />"; heeks.push_back( l_ossHeeks.str() ); } if (message.isTrackNameEvent()) { String text = message.getTextFromTextMetaEvent(); char buf[1024]; memset( buf, '\0', sizeof(buf) ); text.copyToBuffer( buf, sizeof(buf)-1 ); printf("Track %d is %s\n", track, buf ); } if (message.isNoteOn()) { char note_name[256]; memset( note_name, '\0', sizeof(note_name) ); message.getMidiNoteName(message.getNoteNumber(), true, true, middle_c_octave).copyToBuffer( note_name, sizeof(note_name)-1 ); notes.insert( message.getNoteNumber() ); // printf("time %lf note %s\n", time_stamp, note_name ); std::string l_ssNoteName(note_name); std::string::size_type offset; bool sharp_found = false; while ((offset = l_ssNoteName.find("#")) != std::string::npos) { l_ssNoteName = l_ssNoteName.erase(offset,1); sharp_found = true; } strncpy( note_name, l_ssNoteName.c_str(), sizeof(note_name)-1 ); const int blue = 16711680; const int black = 0; const int red = 255; int colour = blue; Keys_t::iterator l_itLegalKey = std::find( legal_keys.begin(), legal_keys.end(), note_name ); if (l_itLegalKey == legal_keys.end()) { colour = red; } // Find the note name in the keys we're interested in. Keys_t::iterator l_itKey = std::find( keys.begin(), keys.end(), note_name ); if (l_itKey != keys.end()) { double x = time_stamp * mm_per_second * time_scale; double y = double(double(std::distance( keys.begin(), l_itKey )) - double(middle_c_key)) * distance_between_notes_in_mm; y += ((track_width + space_between_tracks) * track); if (sharp_found) { y += (distance_between_notes_in_mm / 2.0); colour = red; } // Check to see if we have two notes that are too close to each other for the mechanism to play them. if (key_position.find(note_name) == key_position.end()) { key_position[note_name] = x; } // Measure the distance between this note and the previous equivalent note. If we need to expand our // time scale to ensure consecutive notes are not too close together, do it now. if ((dist(x, key_position[note_name]) < min_distance_between_notes) && (dist(x, key_position[note_name]) > 0.0)) { // Need to scale the whole piece up. double increase_in_time_scale = double(double(min_distance_between_notes) / double(dist(x, key_position[note_name]))); if (increase_in_time_scale > 1.0) { time_scale = increase_in_time_scale * time_scale; time_scale_changed = true; } } key_position[note_name] = x; // It's a key we have to play. Generate the GCode. l_ossGCode.str(""); l_ossGCode << "G83 X " << x << " Y " << y << "\t(" << note_name << ")"; gcode.push_back( l_ossGCode.str() ); if (sharp_found) { std::ostringstream l_ossHeeks; l_ossHeeks << "<Circle col=\"" << colour << "\" r=\"" << (distance_between_notes_in_mm / 2.0) * 0.85 << "\" cx=\"" << x << "\" cy=\"" << y << "\" cz=\"0\" ax=\"0\" ay=\"0\" az=\"1\" id=\"" << id++ << "\">\n"; l_ossHeeks << " <Point col=\"" << colour << "\" x=\"" << x << "\" y=\"" << y << "\" z=\"0\" id=\"" << id++ << "\" />\n"; l_ossHeeks << "</Circle>\n"; heeks.push_back( l_ossHeeks.str() ); } else { std::ostringstream l_ossHeeks; l_ossHeeks << "<Point col=\"" << colour << "\" x=\"" << x << "\" y=\"" << y << "\" z=\"0\" id=\"" << id++ << "\" />"; heeks.push_back( l_ossHeeks.str() ); } // printf("G83 Want hole for key %s at %lf,%lf\n", note_name, x, y ); number_of_notes_included++; } else { // This key doesn't fall exactly on our scale. Ignore it. number_of_notes_ignored++; printf("Missed note %s\n", note_name); } } // End if - then } // End for l_ossGCode.str(""); l_ossGCode << "(" << (double(number_of_notes_included)/double(number_of_notes_included + number_of_notes_ignored)) * 100.0 << " % utilisation of notes)"; gcode.push_back(l_ossGCode.str()); printf("%s\n", l_ossGCode.str().c_str()); l_ossGCode.str(""); l_ossGCode << "(Of the " << (number_of_notes_included + number_of_notes_ignored) << " notes, we are using " << number_of_notes_included << " (whole notes) and ignoring " << number_of_notes_ignored << " (sharps and flats))"; gcode.push_back(l_ossGCode.str()); printf("%s\n", l_ossGCode.str().c_str()); printf("At %lf mm per second (%lf mm per minute), we will need %lf mm of paper for this tune\n", mm_per_second, mm_per_second * 60.0 * time_scale, (end_time - start_time) * mm_per_second * time_scale ); printf("We have had to scale the tune %lf times to ensure no two consecutive notes were less than %lf mm apart\n", time_scale, min_distance_between_notes); // Draw a line for each possible note. for (Keys_t::iterator l_itKey = keys.begin(); l_itKey != keys.end(); l_itKey++) { double y = double(double(std::distance( keys.begin(), l_itKey )) - double(middle_c_key)) * distance_between_notes_in_mm; y += ((track_width + space_between_tracks) * track); if (std::find(legal_keys.begin(), legal_keys.end(), *l_itKey) != legal_keys.end()) { std::ostringstream l_ossHeeks; l_ossHeeks.str(""); l_ossHeeks << "<Sketch title=\"Sketch\" id=\"" << id++ << "\">\n"; l_ossHeeks << "<Line col=\"0\" id=\"" << id++ << "\">\n"; l_ossHeeks << "<Point col=\"0\" x=\"" << (double) (start_time * mm_per_second * time_scale) << "\" y=\"" << y << "\" z=\"0\" id=\"" << id++ << "\" />\n"; l_ossHeeks << "<Point col=\"0\" x=\"" << (double) (end_time * mm_per_second * time_scale) << "\" y=\"" << y << "\" z=\"0\" id=\"" << id++ << "\" />\n"; l_ossHeeks << "</Line>\n"; l_ossHeeks << "</Sketch>\n"; heeks.push_back(l_ossHeeks.str()); } } // End for } } while (time_scale_changed == true); /* for (std::set<int>::const_iterator l_itNote = notes.begin(); l_itNote != notes.end(); l_itNote++) { char note_name[256]; memset( note_name, '\0', sizeof(note_name) ); MidiMessage::getMidiNoteName(*l_itNote, true, true, 5).copyToBuffer( note_name, sizeof(note_name)-1 ); printf("Note %d %s\n", *l_itNote, note_name); } */ { String gcode_file_name(l_pszFileName); gcode_file_name = gcode_file_name.dropLastCharacters(4); gcode_file_name << ".ngc"; char buf[1024]; memset( buf, '\0', sizeof(buf) ); gcode_file_name.copyToBuffer(buf,sizeof(buf)-1); FILE *fp = fopen( buf, "w+t"); if (fp == NULL) { fprintf(stderr,"Could not open %s for writing\n", buf); return(-1); } for (std::list<std::string>::const_iterator l_itLine = gcode.begin(); l_itLine != gcode.end(); l_itLine++) { fprintf(fp,"%s\n", l_itLine->c_str()); } fclose(fp); } { String gcode_file_name(l_pszFileName); gcode_file_name = gcode_file_name.dropLastCharacters(4); gcode_file_name << ".heeks"; char buf[1024]; memset( buf, '\0', sizeof(buf) ); gcode_file_name.copyToBuffer(buf,sizeof(buf)-1); FILE *fp = fopen( buf, "w+t"); if (fp == NULL) { fprintf(stderr,"Could not open %s for writing\n", buf); return(-1); } for (std::list<std::string>::const_iterator l_itLine = heeks.begin(); l_itLine != heeks.end(); l_itLine++) { fprintf(fp,"%s\n", l_itLine->c_str()); } fclose(fp); } return 0; }
//============================================================================== void MidiTransform::processEvents (MidiBuffer& midiMessages, const int blockSize) { int timeStamp; MidiMessage message (0xf4, 0.0); MidiBuffer::Iterator it (midiMessages); MidiBuffer midiOutput; switch (command) { case MidiTransform::KeepEvents: break; case MidiTransform::DiscardEvents: { midiMessages.clear (); break; } case MidiTransform::RemapChannel: { while (it.getNextEvent (message, timeStamp)) { message.setChannel (channelNumber); midiOutput.addEvent (message, timeStamp); } midiMessages = midiOutput; break; } case MidiTransform::ScaleNotes: { while (it.getNextEvent (message, timeStamp)) { if (message.isNoteOnOrOff ()) { message.setNoteNumber (roundFloatToInt (message.getNoteNumber () * noteScale)); midiOutput.addEvent (message, timeStamp); } } midiMessages = midiOutput; break; } case MidiTransform::InvertNotes: { while (it.getNextEvent (message, timeStamp)) { if (message.isNoteOnOrOff ()) { message.setNoteNumber (127 - message.getNoteNumber ()); midiOutput.addEvent (message, timeStamp); } } midiMessages = midiOutput; } case MidiTransform::TransposeNotes: { while (it.getNextEvent (message, timeStamp)) { if (message.isNoteOnOrOff ()) { message.setNoteNumber (jmax (0, jmin (127, message.getNoteNumber () - noteTranspose))); midiOutput.addEvent (message, timeStamp); } } midiMessages = midiOutput; break; } case MidiTransform::ScaleVelocity: { while (it.getNextEvent (message, timeStamp)) { if (message.isNoteOn ()) { message.setVelocity ((message.getVelocity () / 127.0f) * velocityScale); midiOutput.addEvent (message, timeStamp); } } midiMessages = midiOutput; break; } case MidiTransform::InvertVelocity: { while (it.getNextEvent (message, timeStamp)) { if (message.isNoteOn ()) { message.setVelocity ((uint8) (127 - message.getVelocity ())); midiOutput.addEvent (message, timeStamp); } } midiMessages = midiOutput; break; } case MidiTransform::TransposeVelocity: { while (it.getNextEvent (message, timeStamp)) { if (message.isNoteOn ()) { message.setVelocity (jmax (0, jmin (127, message.getVelocity () - velocityTranspose))); midiOutput.addEvent (message, timeStamp); } } midiMessages = midiOutput; break; } case MidiTransform::TriggerCC: { break; } case MidiTransform::TriggerNote: { break; } } }
void PatternRecording::recordPattern(MidiBuffer &midiMessages, const int &numSamples) { // if we are recording the pattern, just rip the // MIDI messages from the incoming buffer if (isPatternRecording) { // get the iterator for the incoming buffer // so we can check through the messages MidiBuffer::Iterator i(midiMessages); MidiMessage message (0xf4, 0.0); int time; // if we are still during the precount, do nothing if (patternPrecountPosition > numSamples) patternPrecountPosition -= numSamples; // if the precount finishes during this buffer else if (patternPrecountPosition > 0) { // TODO: overdub could be option here? midiPattern.clear(); const int numSamplesToAdd = numSamples - patternPrecountPosition; // DBG("#1 recording " << numSamplesToAdd << " of midi, pos: " << patternPrecountPosition); // get messages from the main MIDI message queue while(i.getNextEvent(message, time)) { // and add them if they occur after the precount runs out if (time > patternPrecountPosition) { midiPattern.addEvent(message, time - patternPrecountPosition); // store noteOffs to fire at end if (message.isNoteOn()) { MidiMessage tempNoteOff = MidiMessage::noteOff(message.getChannel(), message.getNoteNumber(), message.getVelocity()); noteOffs.addEvent(tempNoteOff, 0); } } } // the precount has finished patternPrecountPosition = 0; // we are now numSamplesToAdd into the buffer patternPosition = numSamplesToAdd; } else { // if we are during recording (and not near the end), just // add the current input into the record buffer if (numSamples + patternPosition < patternLengthInSamples) { // DBG("#2 recording " << numSamples << " of midi, pos: " << patternPosition); // get messages from the main MIDI message queue while(i.getNextEvent(message, time)) { midiPattern.addEvent(message, time + patternPosition); // store noteOffs to fire at end if (message.isNoteOn()) { MidiMessage tempNoteOff = MidiMessage::noteOff(message.getChannel(), message.getNoteNumber(), message.getVelocity()); noteOffs.addEvent(tempNoteOff, 0); } } //midiPattern.addEvents(midiMessages, 0, numSamples, -patternPosition); patternPosition += numSamples; } // otherwise we are finishing up else { const int numSamplesLeftToRecord = patternLengthInSamples - patternPosition; // add remaining messages from the main MIDI message queue while(i.getNextEvent(message, time)) { if (time < numSamplesLeftToRecord) midiPattern.addEvent(message, time + patternPosition); // store noteOffs to fire at end if (message.isNoteOn()) { MidiMessage tempNoteOff = MidiMessage::noteOff(message.getChannel(), message.getNoteNumber(), message.getVelocity()); noteOffs.addEvent(tempNoteOff, 0); } } // add the note offs to clear any "phantom notes" midiPattern.addEvents(noteOffs, 0, 1, patternLengthInSamples - 1); // we are no longer recording isPatternRecording = false; // if we finish recording, let any listeners know // so they can redraw representations of the pattern sendChangeMessage(); DBG("pattern " << patternBank << " finished recording."); // start playing back from the start straight away isPatternStopping = false; isPatternPlaying = true; patternPosition = 0; // fill the remaining buffer with the newly recorded sequence const int samplesRemaining = numSamples - numSamplesLeftToRecord; if (patternPosition + samplesRemaining < patternLengthInSamples) { midiMessages.addEvents(midiPattern, patternPosition, samplesRemaining, numSamplesLeftToRecord); patternPosition += samplesRemaining; } } // Let the PatternStripControl know to recache pattern sendChangeMessage(); } } }
//============================================================================== void MidiMonitorEditor::timerCallback () { MidiBuffer tmpBuffer; int hours, minutes, seconds, frames; MidiMessage::SmpteTimecodeType timeCode; MidiMessageCollector* collector = owner->getMessageCollector (); collector->removeNextBlockOfMessages (tmpBuffer, 1024); if (! tmpBuffer.isEmpty()) { String midiLine; int samplePos = 0; MidiMessage msg (0xf4, 0.0); MidiBuffer::Iterator eventIterator (tmpBuffer); while (eventIterator.getNextEvent (msg, samplePos)) { midiLine.printf (T("[CH: %d] "), msg.getChannel()); if (msg.isNoteOnOrOff ()) { midiLine += MidiMessage::getMidiNoteName (msg.getNoteNumber(), true, true, 0); midiLine += " "; midiLine += String ((int) msg.getVelocity ()); if (msg.isNoteOn()) { midiLine += " ON"; } else { midiLine += " OFF"; } } else if (msg.isAllNotesOff()) { midiLine += "ALL NOTES OFF"; } else if (msg.isAllSoundOff()) { midiLine += "ALL SOUND OFF"; } else if (msg.isPitchWheel()) { midiLine += "PITCHWEEL: "; midiLine += String (msg.getPitchWheelValue()); } else if (msg.isAftertouch()) { midiLine += "AFTERTOUCH: "; midiLine += String (msg.getAfterTouchValue()); } else if (msg.isChannelPressure()) { midiLine += "CHANNELPRESSURE: "; midiLine += String (msg.getChannelPressureValue()); } else if (msg.isSysEx()) { midiLine += "SYSEX: "; midiLine += String (msg.getSysExDataSize()); midiLine += " bytes"; } else if (msg.isProgramChange()) { midiLine += "PROGRAM CHANGE: "; midiLine += String (msg.getProgramChangeNumber()); midiLine += " ("; midiLine += MidiMessage::getGMInstrumentName (msg.getProgramChangeNumber()); midiLine += ")"; } else if (msg.isController()) { midiLine += "CC: #"; midiLine += String (msg.getControllerNumber()); midiLine += " ("; midiLine += MidiMessage::getControllerName (msg.getControllerNumber()); midiLine += ") = "; midiLine += String (msg.getControllerValue()); } else if (msg.isTimeSignatureMetaEvent ()) { int newNumerator, newDenominator; msg.getTimeSignatureInfo (newNumerator, newDenominator); midiLine += "TIME SIGNATURE: "; midiLine += String (newNumerator); midiLine += " / "; midiLine += String (newDenominator); } else if (msg.isTempoMetaEvent ()) { midiLine += "TEMPO: "; midiLine += String (msg.getTempoSecondsPerQuarterNote ()); //midiLine += " "; //midiLine += String (msg.getTempoMetaEventTickLength (ticksPerQuarterNote)); } else if (msg.isMidiMachineControlMessage()) { midiLine += "MIDI CONTROL: "; switch (msg.getMidiMachineControlCommand()) { case MidiMessage::mmc_stop: midiLine += "stop"; break; case MidiMessage::mmc_play: midiLine += "play"; break; case MidiMessage::mmc_deferredplay: midiLine += "deferredplay"; break; case MidiMessage::mmc_fastforward: midiLine += "fastforward"; break; case MidiMessage::mmc_rewind: midiLine += "rewind"; break; case MidiMessage::mmc_recordStart: midiLine += "recordStart"; break; case MidiMessage::mmc_recordStop: midiLine += "recordStop"; break; case MidiMessage::mmc_pause: midiLine += "pause"; break; } } else if (msg.isMidiStart ()) { midiLine += "MIDI START: "; } else if (msg.isMidiContinue ()) { midiLine += "MIDI CONTINUE: "; } else if (msg.isMidiStop ()) { midiLine += "MIDI STOP: "; } else if (msg.isSongPositionPointer ()) { midiLine += "SONG POSITION: "; midiLine += String (msg.getSongPositionPointerMidiBeat ()); } else if (msg.isQuarterFrame ()) { midiLine += "QUARTER FRAME: "; midiLine += String (msg.getQuarterFrameSequenceNumber ()); midiLine += " "; midiLine += String (msg.getQuarterFrameValue ()); } else if (msg.isFullFrame ()) { midiLine += "FULL FRAME: "; msg.getFullFrameParameters (hours, minutes, seconds, frames, timeCode); midiLine += String (hours); midiLine += ":"; midiLine += String (minutes); midiLine += ":"; midiLine += String (seconds); midiLine += ":"; midiLine += String (frames); midiLine += " timecode: "; switch (timeCode) { case MidiMessage::fps24: midiLine += "fps24"; break; case MidiMessage::fps25: midiLine += "fps25"; break; case MidiMessage::fps30drop: midiLine += "fps30drop"; break; case MidiMessage::fps30: midiLine += "fps30"; break; } } else if (msg.isMidiMachineControlGoto (hours, minutes, seconds, frames)) { midiLine += "MIDI CONTROL GOTO: "; midiLine += String (hours); midiLine += ":"; midiLine += String (minutes); midiLine += ":"; midiLine += String (seconds); midiLine += ":"; midiLine += String (frames); } midiOutputEditor->insertTextAtCursor (midiLine + T("\n")); } } }
void MiditoOscAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { static float cv[8], shiftcv[8]; static bool _calibMode; MidiBuffer processedMidi; MidiMessage m; int time; char oscBuffer[IP_MTU_SIZE]; osc::OutboundPacketStream p(oscBuffer, IP_MTU_SIZE); if (calibMode) // Calibration Mode A440Hz(MIDI number 69) { p << osc::BeginBundleImmediate << osc::BeginMessage( "/fader1" ) << calibMap[69] << osc::EndMessage << osc::BeginMessage( "/fader2" ) << calibMap[69] << osc::EndMessage << osc::BeginMessage( "/fader3" ) << calibMap[69] << osc::EndMessage << osc::BeginMessage( "/fader4" ) << calibMap[69] << osc::EndMessage << osc::BeginMessage( "/fader5" ) << calibMap[69] << osc::EndMessage << osc::BeginMessage( "/fader6" ) << calibMap[69] << osc::EndMessage << osc::BeginMessage( "/fader7" ) << calibMap[69] << osc::EndMessage << osc::BeginMessage( "/fader8" ) << calibMap[69] << osc::EndMessage << osc::BeginMessage( "/gate1" ) << 1 << osc::EndMessage << osc::BeginMessage( "/gate2" ) << 1 << osc::EndMessage << osc::EndBundle; sendOSCData(p); _calibMode = true; return; } else { if (_calibMode) { p << osc::BeginBundleImmediate << osc::BeginMessage( "/gate1" ) << 0 << osc::EndMessage << osc::BeginMessage( "/gate2" ) << 0 << osc::EndMessage << osc::EndBundle; sendOSCData(p); _calibMode = false; } } for (MidiBuffer::Iterator i (midiMessages); i.getNextEvent (m, time);) { p.Clear(); usleep(30); if (m.isNoteOn()) { if (monoMode) // mono Mode { uint32_t midiCh = m.getChannel(); if (midiCh == 0 || midiCh > 7) { midiCh = 1; } cv[midiCh - 1] = calibMap[m.getNoteNumber()]; switch (midiCh) { case 1: p << osc::BeginMessage("/fader1") << cv[0] << osc::EndMessage; break; case 2: p << osc::BeginMessage("/fader2") << cv[1] << osc::EndMessage; break; case 3: p << osc::BeginMessage("/fader3") << cv[2] << osc::EndMessage; break; case 4: p << osc::BeginMessage("/fader4") << cv[3] << osc::EndMessage; break; case 5: p << osc::BeginMessage("/fader5") << cv[4] << osc::EndMessage; break; case 6: p << osc::BeginMessage("/fader6") << cv[5] << osc::EndMessage; break; case 7: p << osc::BeginMessage("/fader7") << cv[6] << osc::EndMessage; break; case 8: p << osc::BeginMessage("/fader8") << cv[7] << osc::EndMessage; break; default: break; } sendOSCData(p); } else if (shiftMode) { // shift Mode cv[0] = calibMap[m.getNoteNumber()]; for (int i = 7; i > 0; i--) { shiftcv[i] = shiftcv[i-1]; } p << osc::BeginBundleImmediate << osc::BeginMessage( "/fader1" ) << cv[0] << osc::EndMessage << osc::BeginMessage( "/fader2" ) << shiftcv[1] << osc::EndMessage << osc::BeginMessage( "/fader3" ) << shiftcv[2] << osc::EndMessage << osc::BeginMessage( "/fader4" ) << shiftcv[3] << osc::EndMessage << osc::BeginMessage( "/fader5" ) << shiftcv[4] << osc::EndMessage << osc::BeginMessage( "/fader6" ) << shiftcv[5] << osc::EndMessage << osc::BeginMessage( "/fader7" ) << shiftcv[6] << osc::EndMessage << osc::BeginMessage( "/fader8" ) << shiftcv[7] << osc::EndMessage << osc::BeginMessage( "/gate1" ) << 1 << osc::EndMessage << osc::BeginMessage( "/gate2" ) << 1 << osc::EndMessage << osc::EndBundle; sendOSCData(p); shiftcv[0] = cv[0]; } else { // poly Mode cv[ch] = calibMap[m.getNoteNumber()]; if (currentMaxPoly == 1) { cv[1] = cv[0]; } p << osc::BeginBundleImmediate << osc::BeginMessage( "/fader1" ) << cv[0] << osc::EndMessage << osc::BeginMessage( "/fader2" ) << cv[1] << osc::EndMessage << osc::BeginMessage( "/fader3" ) << cv[2] << osc::EndMessage << osc::BeginMessage( "/fader4" ) << cv[3] << osc::EndMessage << osc::BeginMessage( "/fader5" ) << cv[4] << osc::EndMessage << osc::BeginMessage( "/fader6" ) << cv[5] << osc::EndMessage << osc::BeginMessage( "/fader7" ) << m.getFloatVelocity() << osc::EndMessage << osc::BeginMessage( "/gate1" ) << 1 << osc::EndMessage << osc::BeginMessage( "/gate2" ) << 1 << osc::EndMessage << osc::EndBundle; sendOSCData(p); ch++; gateCount++; if (ch >= currentMaxPoly) { ch = 0; } } } else if (m.isNoteOff()) { if (monoMode) { switch (m.getChannel()) { case 1: p << osc::BeginMessage( "/gate1" ) << 0 << osc::EndMessage; break; case 2: p << osc::BeginMessage( "/gate2" ) << 0 << osc::EndMessage; break; case 3: p << osc::BeginMessage( "/gate3" ) << 0 << osc::EndMessage; break; case 4: p << osc::BeginMessage( "/gate4" ) << 0 << osc::EndMessage; break; default: break; } sendOSCData(p); } else if (shiftMode) { p << osc::BeginBundleImmediate << osc::BeginMessage( "/gate1" ) << 0 << osc::EndMessage << osc::BeginMessage( "/gate2" ) << 0 << osc::EndMessage << osc::EndBundle; sendOSCData(p); } else { gateCount --; if (gateCount <= 0) { p << osc::BeginBundleImmediate << osc::BeginMessage( "/gate1" ) << 0 << osc::EndMessage << osc::BeginMessage( "/gate2" ) << 0 << osc::EndMessage << osc::EndBundle; sendOSCData(p); gateCount = 0; } ch--; if (ch == -1) { ch = 0; } } } else if (m.isControllerOfType(1)) { // Modulation Wheel float modulation = m.getControllerValue(); if (!monoMode && !shiftMode) { p << osc::BeginMessage("/fader8") << (modulation / 127) << osc::EndMessage; sendOSCData(p); } } processedMidi.addEvent (m, time); } midiMessages.swapWith (processedMidi); buffer.clear(); for (int channel = 0; channel < getNumInputChannels(); ++channel) { float* channelData = 0; } }