Ticket #8905: xmidi.diff

File xmidi.diff, 3.7 KB (added by eriktorbjorn, 12 years ago)

Patch against current SVN

  • sound/midiparser.h

     
    352352        };
    353353
    354354public:
     355        typedef void (*XMidiCallbackProc)(byte eventData, void *refCon);
     356
    355357        MidiParser();
    356358        virtual ~MidiParser() { allNotesOff(); }
    357359
     
    371373        virtual uint32 getTick() { return _position._play_tick; }
    372374
    373375        static MidiParser *createParser_SMF();
    374         static MidiParser *createParser_XMIDI();
     376        static MidiParser *createParser_XMIDI(XMidiCallbackProc proc = 0, void *refCon = 0);
    375377        static void timerCallback(void *data) { ((MidiParser *) data)->onTimer(); }
    376378};
    377379
  • sound/midiparser_xmidi.cpp

     
    4646        Loop _loop[4];
    4747        int _loopCount;
    4848
     49        XMidiCallbackProc _callbackProc;
     50        void *_callbackData;
     51
    4952protected:
    5053        uint32 readVLQ2(byte * &data);
    5154        void resetTracking();
    5255        void parseNextEvent(EventInfo &info);
    5356
    5457public:
    55         MidiParser_XMIDI() : _inserted_delta(0) {}
     58        MidiParser_XMIDI(XMidiCallbackProc proc, void *data) : _inserted_delta(0), _callbackProc(proc), _callbackData(data) {}
    5659        ~MidiParser_XMIDI() { }
    5760
    5861        bool loadMusic(byte *data, uint32 size);
     
    103106                info.basic.param1 = *(_position._play_pos++);
    104107                info.basic.param2 = *(_position._play_pos++);
    105108
     109                // This isn't a full XMIDI implementation, but it should
     110                // hopefully be "good enough" for most things.
     111
     112                switch (info.basic.param1) {
    106113                // Simplified XMIDI looping.
    107                 //
    108                 // I would really like to turn the loop events into some sort
    109                 // of NOP event (perhaps a dummy META event?), but for now we
    110                 // just pass them on to the MIDI driver. That has worked in the
    111                 // past, so it shouldn't cause any actual damage...
     114                case 0x74: {    // XMIDI_CONTROLLER_FOR_LOOP
     115                                byte *pos = _position._play_pos;
     116                                if (_loopCount < ARRAYSIZE(_loop) - 1)
     117                                        _loopCount++;
    112118
    113                 if (info.basic.param1 == 0x74) {
    114                         // XMIDI_CONTROLLER_FOR_LOOP
    115                         byte *pos = _position._play_pos;
    116                         if (_loopCount < ARRAYSIZE(_loop) - 1)
    117                                 _loopCount++;
     119                                _loop[_loopCount].pos = pos;
     120                                _loop[_loopCount].repeat = info.basic.param2;
     121                                break;
     122                        }
    118123
    119                         _loop[_loopCount].pos = pos;
    120                         _loop[_loopCount].repeat = info.basic.param2;
    121                 } else if (info.basic.param1 == 0x75) {
    122                         // XMIDI_CONTROLLER_NEXT_BREAK
     124                case 0x75:      // XMIDI_CONTORLLER_NEXT_BREAK
    123125                        if (_loopCount >= 0) {
    124126                                if (info.basic.param2 < 64) {
    125127                                        // End the current loop.
     
    133135                                        }
    134136                                }
    135137                        }
    136                 } else if (info.basic.param1 >= 0x6e && info.basic.param1 <= 0x78) {
    137                         warning("Unsupported XMIDI controller %d (0x%2x)",
    138                                 info.basic.param1, info.basic.param1);
     138                        break;
     139
     140                case 0x77:      // XMIDI_CONTROLLER_CALLBACK_TRIG
     141                        if (_callbackProc)
     142                                _callbackProc(info.basic.param2, _callbackData);
     143                        break;
     144
     145                default:
     146                        if (info.basic.param1 >= 0x6e && info.basic.param1 <= 0x78) {
     147                                warning("Unsupported XMIDI controller %d (0x%2x)",
     148                                        info.basic.param1, info.basic.param1);
     149                        }
     150                        break;
    139151                }
     152
     153                // Should we really keep passing the XMIDI controller events to
     154                // the MIDI driver, or should we turn them into some kind of
     155                // NOP events? (Dummy meta events, perhaps?) Ah well, it has
     156                // worked so far, so it shouldn't cause any damage...
     157
    140158                break;
    141159
    142160        case 0xF: // Meta or SysEx event
     
    336354        _inserted_delta = 0;
    337355}
    338356
    339 MidiParser *MidiParser::createParser_XMIDI() { return new MidiParser_XMIDI; }
     357MidiParser *MidiParser::createParser_XMIDI(XMidiCallbackProc proc, void *data) {
     358        return new MidiParser_XMIDI(proc, data);
     359}