void MIDIDevice::outputDMX(const QByteArray& universe) { MIDIOut* plugin = static_cast<MIDIOut*> (parent()); Q_ASSERT(plugin != NULL); Q_ASSERT(plugin->alsa() != NULL); Q_ASSERT(m_address != NULL); /* Setup a common event structure for all values */ snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_dest(&ev, m_address->client, m_address->port); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); /* Since MIDI devices can have only 128 real channels, we don't attempt to write more than that */ for (unsigned char channel = 0; channel < MAX_MIDI_DMX_CHANNELS; channel++) { /* Scale 0-255 to 0-127 */ char scaled = DMX2MIDI(universe[channel]); /* Since MIDI is so slow, we only send values that are actually changed. */ if (m_values[channel] == scaled) continue; /* Store the changed MIDI value */ m_values[channel] = scaled; if (mode() == Note) { if (scaled == 0) { /* 0 is sent as a note off command */ snd_seq_ev_set_noteoff(&ev, midiChannel(), channel, scaled); } else { /* 1-127 is sent as note on command */ snd_seq_ev_set_noteon(&ev, midiChannel(), channel, scaled); } snd_seq_event_output(plugin->alsa(), &ev); } else { /* Control change */ snd_seq_ev_set_controller(&ev, midiChannel(), channel, scaled); snd_seq_event_output_buffer(plugin->alsa(), &ev); } } /* Make sure that all values go to the MIDI endpoint */ snd_seq_drain_output(plugin->alsa()); }
QString MIDIDevice::infoText() { MIDIInput* plugin = static_cast<MIDIInput*> (parent()); Q_ASSERT(plugin != NULL); QString info; if (plugin->alsa() != NULL) { info += QString("<B>%1</B>").arg(name()); info += QString("<P>"); info += tr("Device is working correctly."); info += QString("</P>"); info += QString("<P>"); info += QString("<B>%1:</B> ").arg(tr("MIDI Channel")); if (midiChannel() < 16) info += QString("%1<BR/>").arg(midiChannel() + 1); else info += QString("%1<BR/>").arg(tr("Any")); info += QString("</P>"); } else { info += QString("<B>%1</B>").arg(tr("Unknown device")); info += QString("<P>"); info += tr("ALSA sequencer interface is not available."); info += QString("</P>"); } return info; }
void MIDIDevice::feedBack(t_input_channel channel, t_input_value value) { /* MIDI devices can have only 128 notes or controllers */ if (channel < 128) { snd_seq_event_t ev; MIDIInput* plugin; plugin = static_cast<MIDIInput*> (parent()); Q_ASSERT(plugin != NULL); Q_ASSERT(plugin->alsa() != NULL); Q_ASSERT(m_address != NULL); /* Setup an event structure */ snd_seq_ev_clear(&ev); snd_seq_ev_set_dest(&ev, m_address->client, m_address->port); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); char scaled = static_cast <char> (SCALE(double(value), double(0), double(KInputValueMax), double(0), double(127))); if (m_mode == ControlChange) { /* Send control change */ snd_seq_ev_set_controller(&ev, midiChannel(), channel, scaled); snd_seq_event_output(plugin->alsa(), &ev); snd_seq_drain_output(plugin->alsa()); } else { /* Send note on/off */ if (value == 0) { snd_seq_ev_set_noteoff(&ev, midiChannel(), channel, scaled); } else { snd_seq_ev_set_noteon(&ev, midiChannel(), channel, scaled); } snd_seq_event_output(plugin->alsa(), &ev); snd_seq_drain_output(plugin->alsa()); } } }
void NotePlayHandle::noteOff( const f_cnt_t _s ) { if( m_released ) { return; } // first note-off all sub-notes for( NotePlayHandleList::Iterator it = m_subNotes.begin(); it != m_subNotes.end(); ++it ) { ( *it )->noteOff( _s ); } // then set some variables indicating release-state m_framesBeforeRelease = _s; m_releaseFramesToDo = qMax<f_cnt_t>( 0, actualReleaseFramesToDo() ); if( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() ) { // send MidiNoteOff event m_instrumentTrack->processOutEvent( MidiEvent( MidiNoteOff, midiChannel(), midiKey(), 0 ), MidiTime::fromFrames( _s, engine::framesPerTick() ), _s ); } // inform attached components about MIDI finished (used for recording in Piano Roll) if( m_origin == OriginMidiInput ) { setLength( MidiTime( static_cast<f_cnt_t>( totalFramesPlayed() / engine::framesPerTick() ) ) ); m_instrumentTrack->midiNoteOff( *this ); } m_released = true; }
void NotePlayHandle::setVolume( volume_t _volume ) { note::setVolume( _volume ); const int baseVelocity = m_instrumentTrack->midiPort()->baseVelocity(); m_instrumentTrack->processOutEvent( MidiEvent( MidiKeyPressure, midiChannel(), midiKey(), midiVelocity( baseVelocity ) ) ); }
void MIDIDevice::feedBack(quint32 channel, uchar value) { MIDIInput* plugin = static_cast<MIDIInput*> (parent()); Q_ASSERT(plugin != NULL); Q_ASSERT(plugin->alsa() != NULL); Q_ASSERT(m_address != NULL); uchar cmd = 0; uchar data1 = 0; uchar data2 = 0; bool d2v = false; if (QLCMIDIProtocol::feedbackToMidi(channel, value, midiChannel(), &cmd, &data1, &data2, &d2v) == true) { /* Setup an event structure */ snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_dest(&ev, m_address->client, m_address->port); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); if (MIDI_CMD(cmd) == MIDI_NOTE_OFF) { /* Send data as note off command */ snd_seq_ev_set_noteoff(&ev, midiChannel(), data1, data2); snd_seq_event_output(plugin->alsa(), &ev); snd_seq_drain_output(plugin->alsa()); } else if (MIDI_CMD(cmd) == MIDI_NOTE_ON) { /* Send data as note on command */ snd_seq_ev_set_noteon(&ev, midiChannel(), data1, data2); snd_seq_event_output(plugin->alsa(), &ev); snd_seq_drain_output(plugin->alsa()); } else if (MIDI_CMD(cmd) == MIDI_CONTROL_CHANGE) { /* Send data as control change command */ snd_seq_ev_set_controller(&ev, midiChannel(), data1, data2); snd_seq_event_output(plugin->alsa(), &ev); snd_seq_drain_output(plugin->alsa()); } } }
void Win32MidiOutputDevice::writeUniverse(const QByteArray& universe) { if (isOpen() == false) return; for (BYTE channel = 0; channel < MAX_MIDI_DMX_CHANNELS && channel < universe.size(); channel++) { /* Scale 0-255 to 0-127 */ char scaled = DMX2MIDI(uchar(universe[channel])); /* Since MIDI is so slow, we only send values that are actually changed. */ if (m_universe[channel] == scaled) continue; /* Store the changed MIDI value */ m_universe[channel] = scaled; if (mode() == Note) { if (scaled == 0) { /* Zero is sent as a note off command */ sendData(MIDI_NOTE_OFF | (BYTE) midiChannel(), channel, scaled); } else { /* 1-127 are sent as note on commands */ sendData(MIDI_NOTE_ON | (BYTE) midiChannel(), channel, scaled); } } else if (mode() == ProgramChange) { /* Program change */ sendData(MIDI_PROGRAM_CHANGE | (BYTE) midiChannel(), channel, (BYTE)scaled); } else { //qDebug() << "[writeUniverse] MIDI: " << midiChannel() << ", channel: " << channel << ", value: " << scaled; /* Control change */ sendData(MIDI_CONTROL_CHANGE | (BYTE) midiChannel(), channel, (BYTE)scaled); } } }
void NotePlayHandle::setPanning( panning_t panning ) { note::setPanning( panning ); MidiEvent event( MidiMetaEvent, midiChannel(), midiKey(), panningToMidi( panning ) ); event.setMetaEvent( MidiNotePanning ); m_instrumentTrack->processOutEvent( event ); }
void MIDIDevice::writeRange(t_value* values, t_channel num) { for (BYTE channel = 0; channel < MAX_MIDI_DMX_CHANNELS; channel++) { /* Scale 0-255 to 0-127 */ BYTE scaled = static_cast<BYTE> (SCALE(double(values[channel]), double(0), double(KInputValueMax), double(0), double(127))); /* Since MIDI is so slow, we only send values that are actually changed. */ if (m_values[channel] == scaled) continue; /* Store the changed MIDI value */ m_values[channel] = scaled; if (m_mode == Note) { if (scaled == 0) { /* Zero is sent as a note off command */ sendData(MIDI_NOTE_OFF | (BYTE) midiChannel(), channel, scaled); } else { /* 1-127 are sent as note on commands */ sendData(MIDI_NOTE_ON | (BYTE) midiChannel(), channel, scaled); } } else { /* Control change */ sendData(MIDI_CONTROL_CHANGE | (BYTE) midiChannel(), channel, scaled); } } }
void MidiDevice::saveSettings() const { QSettings settings; QString key = QString(SETTINGS_MIDICHANNEL).arg(type(), name()); settings.setValue(key, midiChannel()); key = QString(SETTINGS_MODE).arg(type(), name()); settings.setValue(key, MidiDevice::modeToString(mode())); key = QString(SETTINGS_INITMESSAGE).arg(type(), name()); settings.setValue(key, midiTemplateName()); qDebug() << "Saving mididevice with template name: " << midiTemplateName(); }
void MIDIDevice::outputDMX(const QByteArray& universe) { /* If there's no output port or a destination, the endpoint probably doesn't have a MIDI OUT port. */ if (m_outPort == 0 || m_destination == 0) return; Byte buffer[512]; // Should be enough for 128 channels MIDIPacketList* list = (MIDIPacketList*) buffer; MIDIPacket* packet = MIDIPacketListInit(list); /* Since MIDI devices can have only 128 real channels, we don't attempt to write more than that */ for (Byte channel = 0; channel < MAX_MIDI_DMX_CHANNELS; channel++) { Byte cmd[3]; cmd[1] = channel; cmd[2] = DMX2MIDI(universe[channel]); /* Since MIDI is so slow, we only send values that are actually changed. */ if (m_values[channel] == cmd[2]) continue; /* Store the changed MIDI value. */ m_values[channel] = cmd[2]; if (m_mode == Note) { if (cmd[2] == 0) { /* Zero is sent as a note off command */ cmd[0] = MIDI_NOTE_OFF; } else { /* 1-127 is sent as note on command */ cmd[0] = MIDI_NOTE_ON; } } else { /* Control change */ cmd[0] = MIDI_CONTROL_CHANGE; } /* Encode MIDI channel to the command */ cmd[0] |= (Byte) midiChannel(); /* Add the MIDI command to the packet list */ packet = MIDIPacketListAdd(list, sizeof(buffer), packet, 0, sizeof(cmd), cmd); if (packet == 0) { qWarning() << "MIDIOut buffer overflow"; break; } } /* Send the MIDI packet list */ OSStatus s = MIDISend(m_outPort, m_destination, list); if (s != 0) qWarning() << "Unable to send MIDI data to" << name(); }
void AlsaMidiOutputDevice::writeUniverse(const QByteArray& universe) { if (isOpen() == false) return; // Setup a common event structure for all values snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_dest(&ev, m_receiver_address->client, m_receiver_address->port); //snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); // Since MIDI devices can have only 128 real channels, we don't // attempt to write more than that. for (uchar channel = 0; channel < MAX_MIDI_DMX_CHANNELS && channel < universe.size(); channel++) { // Scale 0-255 to 0-127 char scaled = DMX2MIDI(universe[channel]); bool invalidData = false; // Since MIDI is so slow, we only send values that are actually changed if (m_universe[channel] == scaled) continue; // Store the changed MIDI value m_universe[channel] = scaled; if (mode() == Note) { qDebug() << "Send out NOTE"; // 0 is sent as a note off // 1-127 is sent as note on if (scaled == 0) snd_seq_ev_set_noteoff(&ev, midiChannel(), channel, scaled); else snd_seq_ev_set_noteon(&ev, midiChannel(), channel, scaled); snd_seq_event_output(m_alsa, &ev); } else if (mode() == ProgramChange) { qDebug() << "Send out Program Change"; snd_seq_ev_set_pgmchange(&ev, midiChannel(), channel); } else if (mode() == ControlChange) { qDebug() << "Send out CC. Channel: " << midiChannel() << ", CC: " << channel << ", val: " << scaled; // Control change snd_seq_ev_set_controller(&ev, midiChannel(), channel, scaled); } else invalidData = true; if (!invalidData) if (snd_seq_event_output(m_alsa, &ev) < 0) qDebug() << "snd_seq_event_output ERROR"; } // Make sure that all values go to the MIDI endpoint snd_seq_drain_output(m_alsa); }
NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack, const f_cnt_t _offset, const f_cnt_t _frames, const note& n, NotePlayHandle *parent, int midiEventChannel, Origin origin ) : PlayHandle( TypeNotePlayHandle, _offset ), note( n.length(), n.pos(), n.key(), n.getVolume(), n.getPanning(), n.detuning() ), m_pluginData( NULL ), m_filter( NULL ), m_instrumentTrack( instrumentTrack ), m_frames( 0 ), m_totalFramesPlayed( 0 ), m_framesBeforeRelease( 0 ), m_releaseFramesToDo( 0 ), m_releaseFramesDone( 0 ), m_released( false ), m_hasParent( parent != NULL ), m_hadChildren( false ), m_muted( false ), m_bbTrack( NULL ), m_origTempo( engine::getSong()->getTempo() ), m_origBaseNote( instrumentTrack->baseNote() ), m_frequency( 0 ), m_unpitchedFrequency( 0 ), m_baseDetuning( NULL ), m_songGlobalParentOffset( 0 ), m_midiChannel( midiEventChannel >= 0 ? midiEventChannel : instrumentTrack->midiPort()->realOutputChannel() ), m_origin( origin ) { if( hasParent() == false ) { m_baseDetuning = new BaseDetuning( detuning() ); m_instrumentTrack->m_processHandles.push_back( this ); } else { m_baseDetuning = parent->m_baseDetuning; parent->m_subNotes.push_back( this ); parent->m_hadChildren = true; m_bbTrack = parent->m_bbTrack; } updateFrequency(); setFrames( _frames ); // inform attached components about new MIDI note (used for recording in Piano Roll) if( m_origin == OriginMidiInput ) { m_instrumentTrack->midiNoteOn( *this ); } if( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() ) { const int baseVelocity = m_instrumentTrack->midiPort()->baseVelocity(); // send MidiNoteOn event m_instrumentTrack->processOutEvent( MidiEvent( MidiNoteOn, midiChannel(), midiKey(), midiVelocity( baseVelocity ) ), MidiTime::fromFrames( offset(), engine::framesPerTick() ), offset() ); } }
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(); }