New Control Numbers in MidiControlChange

Written by CyanPhase (Edward Blake) with information from Oskari

since the new Midi Control Change hack by Oskari inside Overloader there are now 4 more control numbers apart from the existing standard 128 midi cc messages. These control numbers allow machine developers to allow their machines to recognize some extra midi messages that weren't previously sent by MidiControlChange.

Control Code Description
252 Channel Aftertouch
253 Polyphonic Aftertouch
254 Program Change
255 Pitch Bend

you use this function to handle the MidiControlChange messages:

void miex::MidiControlChange(int const ctrl, int const channel, int const value)

example:

void miex::MidiControlChange(int const ctrl, int const channel, int const value)
{
    // TODO: check channel

    switch (ctrl)
    {
        case 252:          // 252 = channel aftertouch
                           // Note: depth amount is in the higher byte
        {
            int c = channel;
            int stateflags = pmi->pCB->GetStateFlags();
            if (stateflags & SF_PLAYING && stateflags & SF_RECORDING)
            {
                pseq = pmi->pCB->GetPlayingSequence(pmi->ThisMachine);
                byte *pdata = (byte *)pCB->GetPlayingRow(pseq, 2, c);
                pdata[1] = (int)(value >> 8);
            }
            else
            {
                pseq = NULL;
            }
            pmi->Tracks[c]->Depth = (value >> 8);  // shifting bits to get correct depth
            // TODO: Channel aftertouch code here
            return;
        }
        break;

        case 253:          // 253 = polyphonic aftertouch
                           // Note: depth amount is in the lower byte,
                           //       and Note is in the higher byte
        {
            byte depth = value & 0xFF;
            byte note = value >> 8;
            byte n = (((note / 12)-1) << 4) | ((note % 12) + 1);
            for (int c = 0; c < numTracks; c++)
            {
                if (Tracks[c].Note == n)
                {
                    int stateflags = pmi->pCB->GetStateFlags();
                    if (stateflags & SF_PLAYING && stateflags & SF_RECORDING)
                    {
                        pseq = pmi->pCB->GetPlayingSequence(pmi->ThisMachine);
                        byte *pdata = (byte *)pCB->GetPlayingRow(pseq, 2, c);
                        pdata[1] = (int)(depth);
                    }
                    else
                    {
                        pseq = NULL;
                    }
                    pmi->Tracks[c]->Depth = (depth);

                    break;
                }
            }
            // TODO: Polyphonic aftertouch code here
            return;
        }
        break;

        case 254:          // 254 = program change
        {
            int stateflags = pmi->pCB->GetStateFlags();
            if (stateflags & SF_PLAYING && stateflags & SF_RECORDING)
            {
                pseq = pmi->pCB->GetPlayingSequence(pmi->ThisMachine);
                byte *pdata = (byte *)pCB->GetPlayingRow(pseq, 1, 0);
                pdata[2] = (int)value;
            }
            else
            {
                pseq = NULL;
            }
            pmi->CurrentProgram = value;
            // TODO: Program change code here
            return;
        }
        break;

        case 255:          // 255 = pitch bend
        {                  // Note: value is 14-bit, with a range from 0 to 16383
                           //       with 8192 in the middle.
            int stateflags = pmi->pCB->GetStateFlags();
            if (stateflags & SF_PLAYING && stateflags & SF_RECORDING)
            {
                pseq = pmi->pCB->GetPlayingSequence(pmi->ThisMachine);
                byte *pdata = (byte *)pCB->GetPlayingRow(pseq, 1, 0);
                pdata[1] = (int)(value / 16383.0 * 254.0);
            }
            else
            {
                pseq = NULL;
            }
            pmi->NoteSpeed = pow(2.0,((float)(value - 8192) * pmi->BendRange / 8192.0));
            // TODO: Pitch bend code here
            return;
        }
        break;

        case 64:           // 64 = sustain pedal
        {                  // This part was borrowed from MidiRecExample.txt
            if (value < 64)
            {
                CSequence *pseq;
                int stateflags = pmi->pCB->GetStateFlags();
                if (stateflags & SF_PLAYING && stateflags & SF_RECORDING)
                    pseq = pmi->pCB->GetPlayingSequence(pmi->ThisMachine);
                else
                    pseq = NULL;
                int notedelay = pmi->pMasterInfo->PosInTick * 24 / pmi->pMasterInfo->SamplesPerTick;
                pmi->SustainPedal = false;
                for (int c = 0; c < pmi->numTracks; c++)
                {
                    if (pmi->Tracks[c].Note != NOTE_NO && pmi->Tracks[c].Sustained)
                    {
                        pmi->Tracks[c].Sustained = false;
                        pmi->MidiNoteOff(c, pseq, notedelay);
                    }
                }
            }
            else
            {
                pmi->SustainPedal = true;
            }
            // TODO: sustain pedal code here
            return;
        }
        break;

        default:           // unknown control code
        {
            return;
        }
        break;
    }
}