示例#1
0
        private void DefineMetaEvent(MidiEvent mEvent)
        {
            string result;

            mEvent.EventFlag  = MUtil.MetaEvent;
            mEvent.MetaEvent  = file.ReadByte();
            mEvent.MetaLength = file.ReadVarlen();
            mEvent.Value      = file.ReadBytes(mEvent.MetaLength);
            mEvent.Text       = "ME ";//"" + EVENT_TYPE.MetaEvent; //+" " + mEvent.MetaEvent;
            mEvent.Meta       = ((META_EVENT)mEvent.MetaEvent);
            result            = string.Empty;

            switch ((META_EVENT)mEvent.MetaEvent)
            {
            case META_EVENT.Copyright:
                result = " Copyright " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.CuePoint:
                result = " CuePoint " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.DeviceName:
                result = " DeviceName " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.EndOfTrack:
                result = " End of track ";
                break;

            case META_EVENT.Instrument:
                result = " Instrument " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.KeySignature:
                result += " KeySignature : " + MUtil.TranslateKeySignature(mEvent.Value);
                break;

            case META_EVENT.Lyric:
                result = " Lyric " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.Marker:
                result = " Marker " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.MIDIChannelPrefix:
                byte channel = mEvent.Value[0];
                result = " MIDIChannelPrefix: " + channel;
                break;

            case META_EVENT.MIDIPort:
                byte port = mEvent.Value[0];
                result = " MIDIPort: " + port;
                break;

            case META_EVENT.ProgramName:
                result = "  ProgramName " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.Sequence:
                result = " Sequence " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.SequenceName:
                result = " SequenceName " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.SequencerSpecificEvent:
                result = " SequencerSpecific " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.SMPTEOffset:
                result = " SMPTEOffset " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.Tempo:
                result = SetMetaEventTempo(mEvent);
                break;

            case META_EVENT.Text:
                result = " Text " + System.Text.Encoding.UTF8.GetString(mEvent.Value);
                break;

            case META_EVENT.TimeSignature:
                result = " TimeSignature " + SetMetaEventTimeSignature(mEvent);
                break;
            }

            mEvent.Text += result;
        }
示例#2
0
        /// <summary>
        /// Parse a single Midi track into a list of MidiEvents.
        /// Entering this function, the file offset should be at the start of the MTrk header.
        /// Upon exiting, the file offset should be at the
        /// start of the next MTrk header.
        /// </summary>
        /// <returns></returns>
        private List <MidiEvent> ReadTrackEvents()
        {
            List <MidiEvent> result = new List <MidiEvent>();
            int    starttime        = 0;
            int    eventflag;
            int    tracklength;
            int    trackend;
            string id = file.ReadAscii(4);

            if (id != "MTrk")
            {
                throw new MidiException("Bad MTrk header", file.GetOffset() - 4);
            }
            tracklength = file.ReadInt();
            trackend    = tracklength + file.GetOffset();

            eventflag = 0;

            while (file.GetOffset() < trackend)
            {
                // If the midi file is truncated here, we can still recover.
                // Just return what we've parsed so far.
                int       startoffset, deltatime, channel;
                byte      peekevent;
                MidiEvent mEvent;
                try
                {
                    startoffset = file.GetOffset();
                    deltatime   = file.ReadVarlen();
                    starttime  += deltatime;
                    peekevent   = file.Peek();
                }
                catch (MidiException)
                {
                    return(result);
                }

                mEvent           = new MidiEvent();
                mEvent.DeltaTime = deltatime;
                mEvent.StartTime = starttime;
                result.Add(mEvent);

                if (peekevent >= MUtil.EventNoteOff)
                {
                    mEvent.HasEventflag = true;
                    eventflag           = file.ReadByte();
                }
                channel = 0;
                if (eventflag < byte.MaxValue)
                {
                    channel = eventflag % 16;
                }

                mEvent.EventFlag = (byte)(eventflag - channel);
                switch ((EVENT_TYPE)mEvent.EventFlag)
                {
                case EVENT_TYPE.NoteOn:
                    mEvent.Channel    = (byte)(channel);
                    mEvent.Notenumber = file.ReadByte();
                    mEvent.Volume     = file.ReadByte();
                    if (mEvent.Volume > 0)
                    {
                        mEvent.Text = "ON  Ch: " + channel + " key: " + mEvent.Notenumber + " vel: " + mEvent.Volume;
                        mEvent.Type = EVENT_TYPE.NoteOn;
                    }
                    else
                    {
                        mEvent.EventFlag = (byte)(128);
                        mEvent.Text      = "OFF Ch: " + channel + " key: " + mEvent.Notenumber + " vel: " + mEvent.Volume;
                        mEvent.Type      = EVENT_TYPE.NoteOff;
                    }
                    break;

                case EVENT_TYPE.NoteOff:
                    mEvent.Channel    = (byte)(channel);
                    mEvent.Notenumber = file.ReadByte();
                    mEvent.Volume     = file.ReadByte();
                    mEvent.Text       = "OFF Ch: " + channel + " key: " + mEvent.Notenumber + " vel: " + mEvent.Volume;
                    mEvent.Type       = ((EVENT_TYPE)mEvent.EventFlag);
                    break;

                case EVENT_TYPE.ChannelAfterTouch:
                    mEvent.Channel      = (byte)(channel);
                    mEvent.ChanPressure = file.ReadByte();
                    mEvent.Text         = EVENT_TYPE.ChannelAfterTouch + " Ch: " + channel + " pressure: " + mEvent.ChanPressure;
                    mEvent.Type         = ((EVENT_TYPE)mEvent.EventFlag);
                    break;

                case EVENT_TYPE.ControlChange:
                    mEvent.Channel      = (byte)(channel);
                    mEvent.ControlNum   = file.ReadByte();
                    mEvent.ControlValue = file.ReadByte();
                    mEvent.Text         = "CC  Ch: " + channel + " C: " + ((CC)(mEvent.ControlNum)).ToString() + " value: " + mEvent.ControlValue;
                    mEvent.Type         = ((EVENT_TYPE)mEvent.EventFlag);
                    break;

                case EVENT_TYPE.KeyPressure:
                    mEvent.Channel     = (byte)(channel);
                    mEvent.Notenumber  = file.ReadByte();
                    mEvent.KeyPressure = file.ReadByte();
                    mEvent.Text        = EVENT_TYPE.KeyPressure + " Ch: " + channel + " note: " + mEvent.Notenumber + " pressure: " + mEvent.KeyPressure;
                    mEvent.Type        = ((EVENT_TYPE)mEvent.EventFlag);
                    break;

                case EVENT_TYPE.PitchBend:
                    mEvent.Channel   = (byte)(channel);
                    mEvent.PitchBend = file.ReadShort();
                    mEvent.Text      = EVENT_TYPE.PitchBend + " Ch: " + channel + " PitchBend: " + mEvent.PitchBend;
                    mEvent.Type      = ((EVENT_TYPE)mEvent.EventFlag);
                    break;

                case EVENT_TYPE.ProgramChange:
                    mEvent.Channel    = (byte)(channel);
                    mEvent.Instrument = file.ReadByte();
                    mEvent.Text       = "PC  Ch: " + channel + " : " + (INSTRUMENT)mEvent.Instrument;
                    mEvent.Type       = ((EVENT_TYPE)mEvent.EventFlag);
                    break;

                case EVENT_TYPE.SysexEvent1:
                    mEvent.MetaLength = file.ReadVarlen();
                    mEvent.Value      = file.ReadBytes(mEvent.MetaLength);
                    string val = string.Empty;
                    for (int i = 0; i < mEvent.Value.Length; i++)
                    {
                        val += mEvent.Value[i] + " ";
                    }
                    mEvent.Text = EVENT_TYPE.SysexEvent1 + " length: " + mEvent.MetaLength + " value: " + val;
                    mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag);
                    break;

                case EVENT_TYPE.SysexEvent2:
                    mEvent.MetaLength = file.ReadVarlen();
                    mEvent.Value      = file.ReadBytes(mEvent.MetaLength);
                    mEvent.Text       = EVENT_TYPE.SysexEvent2 + " length: " + mEvent.MetaLength + " value: " + mEvent.Value;
                    mEvent.Type       = ((EVENT_TYPE)mEvent.EventFlag);
                    break;

                case EVENT_TYPE.MetaEvent:
                    DefineMetaEvent(mEvent);
                    mEvent.Type = ((EVENT_TYPE)mEvent.EventFlag);
                    break;

                default:
                    throw new MidiException("Unknown event " + mEvent.EventFlag, file.GetOffset() - 1);
                }
            }

            return(result);
        }