Пример #1
0
bool QLCMIDIProtocol::midiToInput(uchar cmd, uchar data1, uchar data2,
                                  uchar midiChannel, quint32* channel,
                                  uchar* value)
{
    /* Check if cmd is a MIDI COMMAND byte */
    if (!MIDI_IS_CMD(cmd))
        return false;

    /** Use a special handler function for system common messages */
    if (MIDI_IS_SYSCOMMON(cmd))
        return midiSysCommonToInput(cmd, data1, data2, channel, value);

    /* Check that the command came on the correct MIDI channel */
    if (midiChannel <= 0xF && MIDI_CH(cmd) != midiChannel)
        return false;

    switch(MIDI_CMD(cmd))
    {
        case MIDI_NOTE_OFF:
            *channel = CHANNEL_OFFSET_NOTE + quint32(data1);
            *value = 0;
            return true;

        case MIDI_NOTE_ON:
            *channel = CHANNEL_OFFSET_NOTE + quint32(data1);
            *value = MIDI2DMX(data2);
            return true;

        case MIDI_NOTE_AFTERTOUCH:
            *channel = CHANNEL_OFFSET_NOTE_AFTERTOUCH + quint32(data1);
            *value = MIDI2DMX(data2);
            return true;

        case MIDI_CONTROL_CHANGE:
            *channel = CHANNEL_OFFSET_CONTROL_CHANGE + quint32(data1);
            *value = MIDI2DMX(data2);
            return true;

        case MIDI_PROGRAM_CHANGE:
            *channel = CHANNEL_OFFSET_PROGRAM_CHANGE;
            *value = MIDI2DMX(data1);
            return true;

        case MIDI_CHANNEL_AFTERTOUCH:
            *channel = CHANNEL_OFFSET_CHANNEL_AFTERTOUCH;
            *value = MIDI2DMX(data1);
            return true;

        case MIDI_PITCH_WHEEL:
            *channel = CHANNEL_OFFSET_PITCH_WHEEL;
            *value = MIDI2DMX(data2);
            return true;

        default:
            return false;
    }
}
Пример #2
0
static void MidiInProc(const MIDIPacketList* pktList, void* readProcRefCon,
                       void* srcConnRefCon)
{
    Q_UNUSED(readProcRefCon);

    CoreMidiInputDevice* self = static_cast<CoreMidiInputDevice*>(srcConnRefCon);
    Q_ASSERT(self != 0);

    // Go thru all packets in the midi packet list
    const MIDIPacket* packet = &pktList->packet[0];
    for (quint32 p = 0; p < pktList->numPackets && packet != NULL; ++p)
    {
        // Go thru all simultaneously-occurring messages in the packet
        for (quint32 i = 0; i < packet->length && i < 256; ++i)
        {
            uchar cmd = 0;
            uchar data1 = 0;
            uchar data2 = 0;
            quint32 channel = 0;
            uchar value = 0;

            // MIDI Command
            cmd = packet->data[0];
            if (!MIDI_IS_CMD(cmd))
                continue; // Not a MIDI command. Skip to the next byte.
            if (cmd == MIDI_SYSEX)
                break; // Sysex reserves the whole packet. Not interested.

            // 1 or 2 MIDI Data bytes
            if (packet->length > (i + 1) && !MIDI_IS_CMD(packet->data[i + 1]))
            {
                data1 = packet->data[++i];
                if (packet->length > (i + 1) && !MIDI_IS_CMD(packet->data[i + 1]))
                    data2 = packet->data[++i];
                else
                    // no data2 ? Could be a Program Change, so act like Linux
                    // and give it a value
                    data2 = 127;
            }

            if (cmd >= MIDI_BEAT_CLOCK && cmd <= MIDI_BEAT_STOP)
            {
                if (self->processMBC(cmd) == false)
                    continue;
            }

            // Convert the data to QLC input channel & value
            if (QLCMIDIProtocol::midiToInput(cmd, data1, data2, self->midiChannel(),
                                             &channel, &value) == true)
            {
                self->emitValueChanged(channel, value);
                // for MIDI beat clock signals,
                // generate a synthetic release event
                if (cmd >= MIDI_BEAT_CLOCK && cmd <= MIDI_BEAT_STOP)
                    self->emitValueChanged(channel, 0);
            }
        }

        // Get the next packet in the packet list
        packet = MIDIPacketNext(packet);
    }
}