Beispiel #1
0
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());
}
Beispiel #2
0
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;
}
Beispiel #3
0
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());
		}
	}
}
Beispiel #4
0
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;
}
Beispiel #5
0
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 ) ) );
}
Beispiel #6
0
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);
        }
    }
}
Beispiel #8
0
void NotePlayHandle::setPanning( panning_t panning )
{
	note::setPanning( panning );

	MidiEvent event( MidiMetaEvent, midiChannel(), midiKey(), panningToMidi( panning ) );
	event.setMetaEvent( MidiNotePanning );

	m_instrumentTrack->processOutEvent( event );
}
Beispiel #9
0
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);
		}
	}
}
Beispiel #10
0
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();
}
Beispiel #11
0
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);
}
Beispiel #13
0
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();
}