void Zerberus::process(const MidiEvent& event) { if (busy) return; Channel* cp = _channel[int(event.channel())]; if (cp->instrument() == 0) { // printf("Zerberus::process(): no instrument for channel %d\n", event.channel()); return; } switch(event.type()) { case MidiEventType::NOTEOFF: processNoteOff(cp, event.dataA()); break; case MidiEventType::NOTEON: { int key = event.dataA(); int vel = event.dataB(); if (vel) processNoteOn(cp, key, vel); else processNoteOff(cp, key); } break; case MidiEventType::CONTROLLER: cp->controller(event.dataA(), event.dataB()); break; default: printf("event type 0x%02x\n", event.type()); break; } }
void MidiPort::processInEvent( const MidiEvent& event, const MidiTime& time ) { // mask event if( isInputEnabled() && ( inputChannel() == 0 || inputChannel()-1 == event.channel() ) ) { MidiEvent inEvent = event; if( event.type() == MidiNoteOn || event.type() == MidiNoteOff || event.type() == MidiKeyPressure ) { if( inEvent.key() < 0 || inEvent.key() >= NumKeys ) { return; } } if( fixedInputVelocity() >= 0 && inEvent.velocity() > 0 ) { inEvent.setVelocity( fixedInputVelocity() ); } m_midiEventProcessor->processInEvent( inEvent, time ); } }
void MidiPort::processOutEvent( const MidiEvent& event, const MidiTime& time ) { // mask event if( isOutputEnabled() && realOutputChannel() == event.channel() ) { MidiEvent outEvent = event; if( fixedOutputVelocity() >= 0 && event.velocity() > 0 && ( event.type() == MidiNoteOn || event.type() == MidiKeyPressure ) ) { outEvent.setVelocity( fixedOutputVelocity() ); } m_midiClient->processOutEvent( outEvent, time, this ); } }
bool ZynAddSubFxInstrument::handleMidiEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { // do not forward external MIDI Control Change events if the according // LED is not checked if( event.type() == MidiControlChange && event.sourcePort() != this && m_forwardMidiCcModel.value() == false ) { return true; } MidiEvent localEvent = event; localEvent.setChannel( 0 ); m_pluginMutex.lock(); if( m_remotePlugin ) { m_remotePlugin->processMidiEvent( localEvent, 0 ); } else { m_plugin->processMidiEvent( localEvent ); } m_pluginMutex.unlock(); return true; }
void MidiWinMM::processOutEvent( const MidiEvent& event, const MidiTime& time, const MidiPort* port ) { const DWORD shortMsg = ( event.type() + event.channel() ) + ( ( event.param( 0 ) & 0xff ) << 8 ) + ( ( event.param( 1 ) & 0xff ) << 16 ); QStringList outDevs; for( SubMap::ConstIterator it = m_outputSubs.begin(); it != m_outputSubs.end(); ++it ) { for( MidiPortList::ConstIterator jt = it.value().begin(); jt != it.value().end(); ++jt ) { if( *jt == port ) { outDevs += it.key(); break; } } } for( QMap<HMIDIOUT, QString>::Iterator it = m_outputDevices.begin(); it != m_outputDevices.end(); ++it ) { if( outDevs.contains( *it ) ) { midiOutShortMsg( it.key(), shortMsg ); } } }
void MidiFile::writeEvent(const MidiEvent& event) { switch(event.type()) { case ME_NOTEON: writeStatus(ME_NOTEON, event.channel()); put(event.pitch()); put(event.velo()); break; case ME_NOTEOFF: writeStatus(ME_NOTEOFF, event.channel()); put(event.pitch()); put(event.velo()); break; case ME_CONTROLLER: switch(event.controller()) { case CTRL_PROGRAM: writeStatus(ME_PROGRAM, event.channel()); put(event.value() & 0x7f); break; case CTRL_PITCH: { writeStatus(ME_PITCHBEND, event.channel()); int v = event.value() + 8192; put(v & 0x7f); put((v >> 7) & 0x7f); } break; case CTRL_PRESS: writeStatus(ME_AFTERTOUCH, event.channel()); put(event.value() & 0x7f); break; default: writeStatus(ME_CONTROLLER, event.channel()); put(event.controller()); put(event.value() & 0x7f); break; } break; case ME_META: put(ME_META); put(event.metaType()); putvl(event.len()); write(event.edata(), event.len()); resetRunningStatus(); // really ?! break; case ME_SYSEX: put(ME_SYSEX); putvl(event.len() + 1); // including 0xf7 write(event.edata(), event.len()); put(ME_ENDSYSEX); resetRunningStatus(); break; } }
MIDIPacketList MidiApple::createMidiPacketList( const MidiEvent& event ) { MIDIPacketList packetList; packetList.numPackets = 1; MIDIPacket* firstPacket = &packetList.packet[0]; firstPacket->timeStamp = 0; // send immediately firstPacket->length = 3; firstPacket->data[0] = ( event.type() + event.channel() ); firstPacket->data[1] = ( event.param( 0 ) & 0xff ); firstPacket->data[2] = ( event.param( 1 ) & 0xff ); return packetList; }
void RemotePlugin::processMidiEvent( const MidiEvent & _e, const f_cnt_t _offset ) { message m( IdMidiEvent ); m.addInt( _e.type() ); m.addInt( _e.channel() ); m.addInt( _e.param( 0 ) ); m.addInt( _e.param( 1 ) ); m.addInt( _offset ); lock(); sendMessage( m ); unlock(); }
void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { // do nothing if we do not have an instrument instance (e.g. when loading settings) if( m_instrument == NULL ) { return; } const MidiEvent transposedEvent = applyMasterKey( event ); const int key = transposedEvent.key(); switch( event.type() ) { case MidiNoteOn: m_midiNotesMutex.lock(); m_piano.setKeyState( event.key(), true ); // event.key() = original key if( key >= 0 && key < NumKeys ) { if( m_runningMidiNotes[key] > 0 ) { m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time, offset ); } ++m_runningMidiNotes[key]; m_instrument->handleMidiEvent( MidiEvent( MidiNoteOn, midiPort()->realOutputChannel(), key, event.velocity() ), time, offset ); } m_midiNotesMutex.unlock(); emit newNote(); break; case MidiNoteOff: m_midiNotesMutex.lock(); m_piano.setKeyState( event.key(), false ); // event.key() = original key if( key >= 0 && key < NumKeys && --m_runningMidiNotes[key] <= 0 ) { m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time, offset ); } m_midiNotesMutex.unlock(); break; default: m_instrument->handleMidiEvent( transposedEvent, time, offset ); break; } // if appropriate, midi-port does futher routing m_midiPort.processOutEvent( event, time ); }
MidiEvent InstrumentTrack::applyMasterKey( const MidiEvent& event ) { MidiEvent copy( event ); switch( event.type() ) { case MidiNoteOn: case MidiNoteOff: case MidiKeyPressure: copy.setKey( masterKey( event.key() ) ); break; default: break; } return copy; }
void LocalZynAddSubFx::processMidiEvent( const MidiEvent& event ) { // all functions are called while m_master->mutex is held static NULLMidiIn midiIn; switch( event.type() ) { case MidiNoteOn: if( event.velocity() > 0 ) { if( event.key() <= 0 || event.key() >= 128 ) { break; } if( m_runningNotes[event.key()] > 0 ) { m_master->NoteOff( event.channel(), event.key() ); } ++m_runningNotes[event.key()]; m_master->NoteOn( event.channel(), event.key(), event.velocity() ); break; } case MidiNoteOff: if( event.key() <= 0 || event.key() >= 128 ) { break; } if( --m_runningNotes[event.key()] <= 0 ) { m_master->NoteOff( event.channel(), event.key() ); } break; case MidiPitchBend: m_master->SetController( event.channel(), C_pitchwheel, event.pitchBend()-8192 ); break; case MidiControlChange: m_master->SetController( event.channel(), midiIn.getcontroller( event.controllerNumber() ), event.controllerValue() ); break; default: break; } }
void LocalZynAddSubFx::processMidiEvent( const MidiEvent& event ) { switch( event.type() ) { case MidiNoteOn: if( event.velocity() > 0 ) { if( event.key() < 0 || event.key() > MidiMaxKey ) { break; } if( m_runningNotes[event.key()] > 0 ) { m_master->noteOff( event.channel(), event.key() ); } ++m_runningNotes[event.key()]; m_master->noteOn( event.channel(), event.key(), event.velocity() ); break; } case MidiNoteOff: if( event.key() < 0 || event.key() > MidiMaxKey ) { break; } if( --m_runningNotes[event.key()] <= 0 ) { m_master->noteOff( event.channel(), event.key() ); } break; case MidiPitchBend: m_master->setController( event.channel(), C_pitchwheel, event.pitchBend()-8192 ); break; case MidiControlChange: m_master->setController( event.channel(), event.controllerNumber(), event.controllerValue() ); break; default: break; } }
bool MidiFile::readTrack() { char tmp[4]; read(tmp, 4); if (memcmp(tmp, "MTrk", 4)) throw(QString("bad midifile: MTrk expected")); int len = readLong(); // len qint64 endPos = curPos + len; status = -1; sstatus = -1; // running status, will not be reset on meta or sysex click = 0; _tracks.push_back(MidiTrack()); int port = 0; _tracks.back().setOutPort(port); _tracks.back().setOutChannel(-1); for (;;) { MidiEvent event; if (!readEvent(&event)) return true; // check for end of track: if ((event.type() == ME_META) && (event.metaType() == META_EOT)) break; _tracks.back().insert(click, event); } if (curPos != endPos) { qWarning("bad track len: %lld != %lld, %lld bytes too much\n", endPos, curPos, endPos - curPos); if (curPos < endPos) { qWarning(" skip %lld\n", endPos-curPos); skip(endPos - curPos); } } return false; }
void MidiController::processInEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { unsigned char controllerNum; switch( event.type() ) { case MidiControlChange: controllerNum = event.controllerNumber(); if( m_midiPort.inputController() == controllerNum + 1 && ( m_midiPort.inputChannel() == event.channel() + 1 || m_midiPort.inputChannel() == 0 ) ) { unsigned char val = event.controllerValue(); m_previousValue = m_lastValue; m_lastValue = (float)( val ) / 127.0f; emit valueChanged(); } break; default: // Don't care - maybe add special cases for pitch and mod later break; } }
bool isLyricEvent(const MidiEvent &e) { return e.type() == ME_META && (e.metaType() == META_TEXT || e.metaType() == META_LYRIC); }
void InstrumentTrack::processInEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset ) { bool eventHandled = false; switch( event.type() ) { // we don't send MidiNoteOn, MidiNoteOff and MidiKeyPressure // events to instrument as NotePlayHandle will send them on its // own case MidiNoteOn: if( event.velocity() > 0 ) { NotePlayHandle* nph; m_notesMutex.lock(); if( m_notes[event.key()] == NULL ) { nph = NotePlayHandleManager::acquire( this, offset, typeInfo<f_cnt_t>::max() / 2, Note( MidiTime(), MidiTime(), event.key(), event.volume( midiPort()->baseVelocity() ) ), NULL, event.channel(), NotePlayHandle::OriginMidiInput ); m_notes[event.key()] = nph; if( ! Engine::mixer()->addPlayHandle( nph ) ) { m_notes[event.key()] = NULL; } } m_notesMutex.unlock(); eventHandled = true; break; } case MidiNoteOff: m_notesMutex.lock(); if( m_notes[event.key()] != NULL ) { // do actual note off and remove internal reference to NotePlayHandle (which itself will // be deleted later automatically) m_notes[event.key()]->noteOff( offset ); m_notes[event.key()] = NULL; } m_notesMutex.unlock(); eventHandled = true; break; case MidiKeyPressure: if( m_notes[event.key()] != NULL ) { // setVolume() calls processOutEvent() with MidiKeyPressure so the // attached instrument will receive the event as well m_notes[event.key()]->setVolume( event.volume( midiPort()->baseVelocity() ) ); } eventHandled = true; break; case MidiPitchBend: // updatePitch() is connected to m_pitchModel::dataChanged() which will send out // MidiPitchBend events m_pitchModel.setValue( m_pitchModel.minValue() + event.pitchBend() * m_pitchModel.range() / MidiMaxPitchBend ); break; case MidiControlChange: if( event.controllerNumber() == MidiControllerSustain ) { if( event.controllerValue() > MidiMaxControllerValue/2 ) { m_sustainPedalPressed = true; } else { m_sustainPedalPressed = false; } } if( event.controllerNumber() == MidiControllerAllSoundOff || event.controllerNumber() == MidiControllerAllNotesOff || event.controllerNumber() == MidiControllerOmniOn || event.controllerNumber() == MidiControllerOmniOff || event.controllerNumber() == MidiControllerMonoOn || event.controllerNumber() == MidiControllerPolyOn ) { silenceAllNotes(); } break; case MidiMetaEvent: // handle special cases such as note panning switch( event.metaEvent() ) { case MidiNotePanning: if( m_notes[event.key()] != NULL ) { eventHandled = true; m_notes[event.key()]->setPanning( event.panning() ); } break; default: qWarning( "InstrumentTrack: unhandled MIDI meta event: %i", event.metaEvent() ); break; } break; default: break; } if( eventHandled == false && instrument()->handleMidiEvent( event, time, offset ) == false ) { qWarning( "InstrumentTrack: unhandled MIDI event %d", event.type() ); } }
bool CarlaInstrument::handleMidiEvent(const MidiEvent& event, const MidiTime&, f_cnt_t offset) { const QMutexLocker ml(&fMutex); if (fMidiEventCount >= kMaxMidiEvents) return false; NativeMidiEvent& nEvent(fMidiEvents[fMidiEventCount++]); std::memset(&nEvent, 0, sizeof(NativeMidiEvent)); nEvent.port = 0; nEvent.time = offset; nEvent.data[0] = event.type() | (event.channel() & 0x0F); switch (event.type()) { case MidiNoteOn: if (event.velocity() > 0) { if (event.key() < 0 || event.key() > MidiMaxKey) break; nEvent.data[1] = event.key(); nEvent.data[2] = event.velocity(); nEvent.size = 3; break; } else { nEvent.data[0] = MidiNoteOff | (event.channel() & 0x0F); // nobreak } case MidiNoteOff: if (event.key() < 0 || event.key() > MidiMaxKey) break; nEvent.data[1] = event.key(); nEvent.data[2] = event.velocity(); nEvent.size = 3; break; case MidiKeyPressure: nEvent.data[1] = event.key(); nEvent.data[2] = event.velocity(); nEvent.size = 3; break; case MidiControlChange: nEvent.data[1] = event.controllerNumber(); nEvent.data[2] = event.controllerValue(); nEvent.size = 3; break; case MidiProgramChange: nEvent.data[1] = event.program(); nEvent.size = 2; break; case MidiChannelPressure: nEvent.data[1] = event.channelPressure(); nEvent.size = 2; break; case MidiPitchBend: nEvent.data[1] = event.pitchBend() & 0x7f; nEvent.data[2] = event.pitchBend() >> 7; nEvent.size = 3; break; default: // unhandled --fMidiEventCount; break; } return true; }
void MidiAlsaSeq::processOutEvent( const MidiEvent& event, const MidiTime& time, const MidiPort* port ) { // HACK!!! - need a better solution which isn't that easy since we // cannot store const-ptrs in our map because we need to call non-const // methods of MIDI-port - it's a mess... MidiPort* p = const_cast<MidiPort *>( port ); snd_seq_event_t ev; snd_seq_ev_clear( &ev ); snd_seq_ev_set_source( &ev, ( m_portIDs[p][1] != -1 ) ? m_portIDs[p][1] : m_portIDs[p][0] ); snd_seq_ev_set_subs( &ev ); snd_seq_ev_schedule_tick( &ev, m_queueID, 1, static_cast<int>( time ) ); ev.queue = m_queueID; switch( event.type() ) { case MidiNoteOn: snd_seq_ev_set_noteon( &ev, event.channel(), event.key() + KeysPerOctave, event.velocity() ); break; case MidiNoteOff: snd_seq_ev_set_noteoff( &ev, event.channel(), event.key() + KeysPerOctave, event.velocity() ); break; case MidiKeyPressure: snd_seq_ev_set_keypress( &ev, event.channel(), event.key() + KeysPerOctave, event.velocity() ); break; case MidiControlChange: snd_seq_ev_set_controller( &ev, event.channel(), event.controllerNumber(), event.controllerValue() ); break; case MidiProgramChange: snd_seq_ev_set_pgmchange( &ev, event.channel(), event.program() ); break; case MidiChannelPressure: snd_seq_ev_set_chanpress( &ev, event.channel(), event.channelPressure() ); break; case MidiPitchBend: snd_seq_ev_set_pitchbend( &ev, event.channel(), event.param( 0 ) - 8192 ); break; default: qWarning( "MidiAlsaSeq: unhandled output event %d\n", (int) event.type() ); return; } m_seqMutex.lock(); snd_seq_event_output( m_seqHandle, &ev ); snd_seq_drain_output( m_seqHandle ); m_seqMutex.unlock(); }