示例#1
0
        //read data for a single event in a track's data, convert the event's delta time to an absolute track time
        private static Event loadEventData(MidiInStream stream)
        {
            Event evt = null;

            int status = stream.getOne();

            if (status < 0x80)                              //running status
            {
                stream.pushBack(1);
                status = runningStatus;
            }
            if (status >= 0x80 && status < 0xff)             //message event
            {
                Message msg = loadMessageData(stream, status);
                runningStatus = status;
                evt           = new MessageEvent(msg);
            }
            else if (status == 0xff)                        //meta event
            {
                evt = loadMetaEventData(stream);            //this may return null for unrecognized events
            }
            else
            {
                throw new MidiFileException(stream.filename + " has an invalid event at", stream.getDataPos() - 8);
            }
            return(evt);
        }
示例#2
0
        //read data for known meta events & skip any we don't recognize
        private static MetaEvent loadMetaEventData(MidiInStream stream)
        {
            MetaEvent meta     = null;
            int       metatype = stream.getOne();
            int       metalen  = (int)stream.getVariableLengthVal();

            switch (metatype)
            {
            case 0x00:
                if (metalen == 0)
                {
                    meta = new SequenceNumberEvent(curTrackNum);
                }
                if (metalen >= 2)
                {
                    int val = stream.getTwo();
                    metalen -= 2;
                    meta     = new SequenceNumberEvent(val);
                }
                break;

            //text events
            case 0x01:
                String txt = stream.getString(metalen);
                metalen = 0;
                meta    = new TextEvent(txt);
                break;

            case 0x02:
                String copyright = stream.getString(metalen);
                metalen = 0;
                meta    = new CopyrightEvent(copyright);
                break;

            case 0x03:
                String trackname = stream.getString(metalen);
                metalen = 0;
                meta    = new TrackNameEvent(trackname);
                break;

            case 0x04:
                String instrument = stream.getString(metalen);
                metalen = 0;
                meta    = new InstrumentEvent(instrument);
                break;

            case 0x05:
                String lyric = stream.getString(metalen);
                metalen = 0;
                meta    = new LyricEvent(lyric);
                break;

            case 0x06:
                String marker = stream.getString(metalen);
                metalen = 0;
                meta    = new MarkerEvent(marker);
                break;

            case 0x07:
                String cue = stream.getString(metalen);
                metalen = 0;
                meta    = new CuePointEvent(cue);
                break;

            case 0x08:
                String patchname = stream.getString(metalen);
                metalen = 0;
                meta    = new PatchNameEvent(patchname);
                break;

            case 0x09:
                String devname = stream.getString(metalen);
                metalen = 0;
                meta    = new DeviceNameEvent(devname);
                break;

            //obsolete events
            case 0x20:
                int chanNum = stream.getOne();
                metalen -= 1;
                meta     = new MidiChannelEvent(chanNum);
                break;

            case 0x21:
                int portNum = stream.getOne();
                metalen -= 1;
                meta     = new MidiPortEvent(portNum);
                break;

            //end of track event
            case 0x2f:
                meta = new EndofTrackEvent();
                break;

            //timing events
            case 0x51:
                int t1    = stream.getTwo();
                int t2    = stream.getOne();
                int tempo = (t1 * 256) + t2;
                metalen -= 3;
                meta     = new TempoEvent(tempo);
                break;

            case 0x54:
                int hr = stream.getOne();
                int rr = (hr / 32) % 4;
                int hh = hr % 32;
                int mn = stream.getOne();
                int se = stream.getOne();
                int fr = stream.getOne();
                int ff = stream.getOne();
                metalen -= 5;
                meta     = new SMPTEOffsetEvent(rr, hh, mn, se, fr, ff);
                break;

            case 0x58:
                int nn = stream.getOne();
                int b1 = stream.getOne();
                int dd = (int)Math.Pow(2.0, b1);
                int cc = stream.getOne();
                int bb = stream.getOne();
                metalen -= 4;
                meta     = new TimeSignatureEvent(nn, dd, cc, bb);
                break;

            case 0x59:
                int sf = stream.getOne();
                int mi = stream.getOne();
                metalen -= 2;
                meta     = new KeySignatureEvent(sf, mi);
                break;

            //other people's events
            case 0x7f:
                List <byte> propdata = stream.getRange(metalen);
                metalen = 0;
                meta    = new ProprietaryEvent(propdata);
                break;

            //skip any other events
            default:
                break;
            }
            stream.skipBytes(metalen);      //skip unknown events & any extra bytes at the end of known events
            runningStatus = 0;              //meta events cancel running status

            return(meta);
        }
示例#3
0
        //read data for a midi message (80 - ff), handle sysex continuation and escape sequences
        private static Message loadMessageData(MidiInStream stream, int status)
        {
            Message msg = null;

            if (status < 0xF0)          //midi channel message
            {
                int msgtype = status / 16;
                int channel = status % 16;

                int b1 = stream.getOne();
                int b2 = 0;
                if ((msgtype != 0xC) && (msgtype != 0xD))
                {
                    b2 = stream.getOne();
                }

                msg = Message.getChannelMessage(msgtype, channel, b1, b2);
            }
            else if (status == 0xF0)            //sysex message
            {
                int         len       = stream.getOne();
                List <byte> sysExData = stream.getRange(len);
                sysexCont     = (sysExData[sysExData.Count - 1] != 0xf7);   //is the last byte of sysex data a F7?
                msg           = new SysExMessage(sysExData);
                prevSysEx     = (SysExMessage)msg;
                runningStatus = 0;                      //sysex msg cancel running status
            }
            else if (status == 0xF7)
            {
                if (sysexCont)                  //sysex continuation - append this data to prev sysex message
                {
                    int         len      = stream.getOne();
                    List <byte> contData = stream.getRange(len);
                    sysexCont = (contData[contData.Count - 1] != 0xf7);       //is the last byte of sysex data a F7?
                    prevSysEx.sysExData.AddRange(contData);
                }
                else
                {                                   //escape sequence
                    int         len     = stream.getOne();
                    List <byte> escData = stream.getRange(len);
                    msg = new EscapeMessage(escData);
                }
                runningStatus = 0;
            }
            else
            {                                   //system common msgs shouldn't occur here, but if they do, we need to skip them
                int b1      = 0;
                int b2      = 0;
                int datalen = SystemMessage.SysMsgLen[status - 0xF0] - 1;
                if (datalen > 0)
                {
                    b1 = stream.getOne();
                }
                if (datalen > 1)
                {
                    b2 = stream.getOne();
                    b1 = ((b1 % 128) * 128) + (b2 % 128);
                }
                msg           = new SystemMessage(status, b1);
                runningStatus = 0;
            }

            return(msg);
        }