Example #1
0
        private void ParseEvents(int offset, int length, int trackNumber)
        {
            string        s;
            int           n = offset + length, i, j = 0;
            MidiEvent     mtrkEvent = null;
            MidiMetaEvent metaEvent;

            /* A track chunk is a stream of MIDI (MTrk) events.  Process each such
             * event in this part of the byte array comprising the track chunk.
             */
            for (i = offset; i < n; i += mtrkEvent.Size)
            {
                /* In order to know what kind of event to instantiate, we must read the event's status
                 * byte, which requires skipping past the delta-time (stored as a variable-length quantity).
                 */
                for (j = i; j < this.Bytes.Length && (this.Bytes[j] & 0x80) > 0; ++j)
                {
                    if (j - i > 3)
                    {
                        s = string.Format("{0} (@ {1} {2})", Properties.Resources.InvalidVLQ, Properties.Resources.Byte, i);
                        this.AddErrorText(s, trackNumber);
                        return;
                    }
                }
                if (++j >= this.Bytes.Length)
                {
                    break;
                }

                /* Instantiate an event object of the appropriate type (based on the status byte). */
                switch (this.Bytes[j])
                {
                case 0xFF: mtrkEvent = new MidiMetaEvent(this, i); break;

                case 0xF7: mtrkEvent = new MidiSysExEvent(this, i); break;

                case 0xF0: mtrkEvent = new MidiSysExEvent(this, i); break;

                default: mtrkEvent = new MidiChannelEvent(this, i); break;
                }
                this.Items.Add(mtrkEvent);
                this.SetTotalTime(this.ItemCount - 1);

                /* If the event is a MIDI channel message/event that does not use
                 * running status, use it to set the running status at this byte offset.
                 */
                if (++j >= this.Bytes.Length)
                {
                    break;
                }
                MidiChannelEvent channelEvent = mtrkEvent as MidiChannelEvent;
                if (channelEvent != null && !channelEvent.RunningStatus)
                {
                    this.SetRunningStatus(i, channelEvent.Status);
                }

                /* If the event is a meta-event representing a key signature,
                 * use it to set the key signature at the appropriate time.
                 */
                if (++j >= this.Bytes.Length)
                {
                    break;
                }
                metaEvent = MidiFile.ItemToKeySignatureEvent(mtrkEvent);
                if (metaEvent != null)
                {
                    this.SetKeySignature(metaEvent);
                }
            }

            /* If we ran out of data, add an error message. */
            if (j >= this.Bytes.Length)
            {
                s = string.Format(Properties.Resources.MismatchFormat, Properties.Resources.Byte, length, i - offset);
                this.AddErrorText(s, trackNumber);
            }

            /* The last event in a track chunk should be an End of Track meta-event. */
            metaEvent = mtrkEvent as MidiMetaEvent;
            if (metaEvent == null || (metaEvent != null && metaEvent.Type != MidiMetaEvent.EndOfTrackType))
            {
                this.AddErrorText(Properties.Resources.NoEndOfTrack, trackNumber);
            }
        }
Example #2
0
 /// <summary>Initializes a new instance of the MidiMetaEvent class.</summary>
 /// <param name="file">MidiFile object representing the MIDI file to which this item belongs.</param>
 /// <param name="offset">Offset into the file's byte array at which this item begins.</param>
 public MidiMetaEvent(MidiFile file, int offset) : base(file, offset)
 {
 }
 /// <summary>Initializes a new instance of the MidiChannelEvent class.</summary>
 /// <param name="file">MidiFile object representing the MIDI file to which this item belongs.</param>
 /// <param name="offset">Offset into the file's byte array at which this item begins.</param>
 public MidiChannelEvent(MidiFile file, int offset) : base(file, offset)
 {
 }
Example #4
0
        /****************
        * Constructors *
        ****************/

        #region Public Constructors

        /// <summary>Initializes a new instance of the MidiItem class.</summary>
        /// <param name="file">MidiFile object representing the MIDI file to which this item belongs.</param>
        /// <param name="offset">Offset into the file's byte array at which this item begins.</param>
        public MidiItem(MidiFile file, int offset)
        {
            this._File = file; this.Offset = offset;
        }