Example #1
0
        /// <summary>
        /// Packs the data from a tempo meta message into an integer.
        /// </summary>
        /// <param name="message">
        /// The tempo meta message.
        /// </param>
        /// <returns>
        /// Returns the tempo packed into an integer.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// Thrown if the message is not a tempo meta message.
        /// </exception>
        public static int PackTempo(MetaMessage message)
        {
            // Enforce preconditions.
            if (message.Type != MetaType.Tempo)
            {
                throw new ArgumentException(
                          "Message is not a tempo meta message", "message");
            }

            int tempo = 0;

            if (BitConverter.IsLittleEndian)
            {
                int d = message.data.Length - 1;

                for (int i = 0; i < message.data.Length; i++)
                {
                    tempo |= message.data[d] << (Shift * i);
                    d--;
                }
            }
            else
            {
                for (int i = 0; i < message.data.Length; i++)
                {
                    tempo |= message.data[i] << (Shift * i);
                }
            }

            return(tempo);
        }
Example #2
0
 /// <summary>
 /// Visits meta messages.
 /// </summary>
 /// <param name="message">
 /// The MetaMessage to visit.
 /// </param>
 void Multimedia.Midi.IMidiMessageVisitor.Visit(MetaMessage message)
 {
     // If the meta message is a tempo change message type.
     if (message.Type == MetaType.Tempo)
     {
         // Change tempo.
         Tempo = MetaMessage.PackTempo(message);
     }
     // Else if the meta message is an end of track message type.
     else if (message.Type == MetaType.EndOfTrack)
     {
         // Stop playback.
         Stop();
     }
 }
Example #3
0
        /// <summary>
        /// Reads the data for the next track from the Midi file.
        /// </summary>
        /// <param name="trackNum">
        /// The track number.
        /// </param>
        private void ReadNextTrack(int trackNum)
        {
            MetaType metaType = MetaType.TrackName;
            int status = 0;
            int runningStatus = 0;

            // Read length of track.
            binReader.ReadBytes(LengthByteCount);

            // Continue reading Midi events until the end of the track.
            while(metaType != MetaType.EndOfTrack)
            {
                // Next Midi message in track.
                IMidiMessage msg = null;

                // Ticks for next Midi event.
                int ticks = ReadVariableLengthQuantity();

                // Read status byte for the next Midi message.
                status = binReader.ReadByte(); 

                // If this is a status byte.
                if((status & StatusFlag) == StatusFlag)
                { 
                    // If the next Midi message is a channel message.
                    if(ChannelMessage.IsChannelMessage(status))
                    {
                        // Read channel message from the Midi file.
                        msg = ReadChannelMessage(status);  
                      
                        // Update running status.
                        runningStatus = status;                         
                    }
                    // Else if the next Midi message is a meta message.
                    else if(MetaMessage.IsMetaMessage(status))
                    {
                        // Read the type of meta message.
                        metaType = (MetaType)binReader.ReadByte();

                        // Read the length of the meta message data.
                        int length = ReadVariableLengthQuantity();

                        // Read the meta message data.
                        byte[] data = binReader.ReadBytes(length);

                        // Create meta message.
                        msg = new MetaMessage(metaType, data);
                    }
                    // Else if the next Midi message is a system exclusive 
                    // message.
                    else if(SysExMessage.IsSysExMessage(status))
                    {
                        // The type of system exclusive message.
                        SysExType type = (SysExType)status;

                        // Read the length of the system exclusive data.
                        int length = ReadVariableLengthQuantity();

                        // Read the system exclusive data.
                        byte[] data = binReader.ReadBytes(length);

                        // Create system exclusive message.
                        msg = new SysExMessage(type, data);
                    }
                }
                // Assumes running status.
                else
                {
                    // Create channel message.
                    msg = ReadChannelMessage(runningStatus, status);
                }

                // Create the next Midi event and store it in the specified
                // track.
                MidiEvent e = new MidiEvent(msg, ticks);
                tracks[trackNum].Add(e);
            } 
        }
Example #4
0
 /// <summary>
 /// Initializes a new instance of the MetaMessage class with
 /// another instance of the MetaMessage class.
 /// </summary>
 /// <param name="message">
 /// The MetaMessage instance to use for initialization.
 /// </param>
 public MetaMessage(MetaMessage message)
 {
     type = message.type;
     data = new byte[message.data.Length];
     message.data.CopyTo(data, 0);
 }
        /// <summary>
        /// Reads the data for the next track from the Midi file.
        /// </summary>
        /// <param name="trackNum">
        /// The track number.
        /// </param>
        private void ReadNextTrack(int trackNum)
        {
            MetaType metaType      = MetaType.TrackName;
            int      status        = 0;
            int      runningStatus = 0;

            // Read length of track.
            binReader.ReadBytes(LengthByteCount);

            // Continue reading Midi events until the end of the track.
            while (metaType != MetaType.EndOfTrack)
            {
                // Next Midi message in track.
                IMidiMessage msg = null;

                // Ticks for next Midi event.
                int ticks = ReadVariableLengthQuantity();

                // Read status byte for the next Midi message.
                status = binReader.ReadByte();

                // If this is a status byte.
                if ((status & StatusFlag) == StatusFlag)
                {
                    // If the next Midi message is a channel message.
                    if (ChannelMessage.IsChannelMessage(status))
                    {
                        // Read channel message from the Midi file.
                        msg = ReadChannelMessage(status);

                        // Update running status.
                        runningStatus = status;
                    }
                    // Else if the next Midi message is a meta message.
                    else if (MetaMessage.IsMetaMessage(status))
                    {
                        // Read the type of meta message.
                        metaType = (MetaType)binReader.ReadByte();

                        // Read the length of the meta message data.
                        int length = ReadVariableLengthQuantity();

                        // Read the meta message data.
                        byte[] data = binReader.ReadBytes(length);

                        // Create meta message.
                        msg = new MetaMessage(metaType, data);
                    }
                    // Else if the next Midi message is a system exclusive
                    // message.
                    else if (SysExMessage.IsSysExMessage(status))
                    {
                        // The type of system exclusive message.
                        SysExType type = (SysExType)status;

                        // Read the length of the system exclusive data.
                        int length = ReadVariableLengthQuantity();

                        // Read the system exclusive data.
                        byte[] data = binReader.ReadBytes(length);

                        // Create system exclusive message.
                        msg = new SysExMessage(type, data);
                    }
                }
                // Assumes running status.
                else
                {
                    // Create channel message.
                    msg = ReadChannelMessage(runningStatus, status);
                }

                // Create the next Midi event and store it in the specified
                // track.
                MidiEvent e = new MidiEvent(msg, ticks);
                tracks[trackNum].Add(e);
            }
        }
Example #6
0
        /// <summary>
        /// Packs the data from a tempo meta message into an integer.
        /// </summary>
        /// <param name="message">
        /// The tempo meta message.
        /// </param>
        /// <returns>
        /// Returns the tempo packed into an integer.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// Thrown if the message is not a tempo meta message.
        /// </exception>
        public static int PackTempo(MetaMessage message)
        {
            // Enforce preconditions.
            if(message.Type != MetaType.Tempo)
                throw new ArgumentException(
                    "Message is not a tempo meta message", "message");

            int tempo = 0;

            if(BitConverter.IsLittleEndian)
            {
                int d = message.data.Length - 1;

                for(int i = 0; i < message.data.Length; i++)
                {
                    tempo |= message.data[d] << (Shift * i);
                    d--;
                }
            }
            else
            {                    
                for(int i = 0; i < message.data.Length; i++)
                {
                    tempo |= message.data[i] << (Shift * i);
                }                    
            }

            return tempo;
        }
Example #7
0
 /// <summary>
 /// Initializes a new instance of the MetaMessage class with 
 /// another instance of the MetaMessage class.
 /// </summary>
 /// <param name="message">
 /// The MetaMessage instance to use for initialization.
 /// </param>
 public MetaMessage(MetaMessage message)
 {
     type = message.type;
     data = new byte[message.data.Length];
     message.data.CopyTo(data, 0);
 }
Example #8
0
 /// <summary>
 /// Visits meta messages.
 /// </summary>
 /// <param name="message">
 /// The MetaMessage to visit.
 /// </param>
 void Multimedia.Midi.IMidiMessageVisitor.Visit(MetaMessage message)
 {
     // If the meta message is a tempo change message type.
     if(message.Type == MetaType.Tempo)
     {
         // Change tempo.
         Tempo = MetaMessage.PackTempo(message);
     }
     // Else if the meta message is an end of track message type.
     else if(message.Type == MetaType.EndOfTrack)
     {
         // Stop playback.
         Stop();
     }
 }