예제 #1
0
        /// <summary>Reads a MIDI stream into a new MidiSequence.</summary>
        /// <param name="inputStream">The stream containing the MIDI data.</param>
        /// <returns>A MidiSequence containing the parsed MIDI data.</returns>
        public static MidiSequence Import(Stream inputStream)
        {
            // Validate input
            if (inputStream == null)
            {
                throw new ArgumentNullException("inputStream");
            }
            if (!inputStream.CanRead)
            {
                throw new ArgumentException("Stream must be readable.", "inputStream");
            }

            // Read in the main MIDI header
            MThdChunkHeader mainHeader = MThdChunkHeader.Read(inputStream);

            // Read in all of the tracks
            MTrkChunkHeader [] trackChunks = new MTrkChunkHeader[mainHeader.NumberOfTracks];
            for (int i = 0; i < mainHeader.NumberOfTracks; i++)
            {
                trackChunks[i] = MTrkChunkHeader.Read(inputStream);
            }

            // Create the MIDI sequence
            MidiSequence sequence = new MidiSequence(mainHeader.Format, mainHeader.Division);

            for (int i = 0; i < mainHeader.NumberOfTracks; i++)
            {
                sequence.AddTrack(MidiParser.ParseToTrack(trackChunks[i].Data));
            }
            return(sequence);
        }
예제 #2
0
        /// <summary>Trims a MIDI file to a specified length.</summary>
        /// <param name="sequence">The sequence to be copied and trimmed.</param>
        /// <param name="totalTime">The requested time length of the new MIDI sequence.</param>
        /// <returns>A MIDI sequence with only those events that fell before the requested time limit.</returns>
        public static MidiSequence Trim(MidiSequence sequence, long totalTime)
        {
            // Create a new sequence to mimic the old
            MidiSequence newSequence = new MidiSequence(sequence.Format, sequence.Division);

            // Copy each track up to the specified time limit
            foreach (MidiTrack track in sequence)
            {
                // Create a new track in the new sequence to match the old track in the old sequence
                MidiTrack newTrack = newSequence.AddTrack();

                // Convert all times in the old track to deltas
                track.Events.ConvertDeltasToTotals();

                // Copy over all events that fell before the specified time
                for (int i = 0; i < track.Events.Count && track.Events[i].DeltaTime < totalTime; i++)
                {
                    newTrack.Events.Add(track.Events[i].Clone());
                }

                // Convert all times back (on both new and old tracks; the new one inherited the totals)
                track.Events.ConvertTotalsToDeltas();
                newTrack.Events.ConvertTotalsToDeltas();

                // If the new track lacks an end of track, add one
                if (!newTrack.HasEndOfTrack)
                {
                    newTrack.Events.Add(new EndOfTrack(0));
                }
            }

            // Return the new sequence
            return(newSequence);
        }
예제 #3
0
        /// <summary>Plays an individual MIDI track.</summary>
        /// <param name="track">The track to be played.</param>
        /// <param name="division">The MIDI division to use for playing the track.</param>
        public static void Play(MidiTrack track, int division)
        {
            // Wrap the track in a sequence and play it
            MidiSequence tempSequence = new MidiSequence(0, division);

            tempSequence.AddTrack(track);
            Play(tempSequence);
        }
예제 #4
0
        /// <summary>Plays a collection of MIDI events.</summary>
        /// <param name="events">The events to be played.</param>
        /// <param name="division">The division to use for playing the events.</param>
        public static void Play(MidiEventCollection events, int division)
        {
            // Add all of the events to a temporary track and sequence, then play it
            MidiSequence tempSequence = new MidiSequence(0, division);
            MidiTrack    tempTrack    = tempSequence.AddTrack();

            tempTrack.Events.Add(events);
            if (!tempTrack.HasEndOfTrack)
            {
                tempTrack.Events.Add(new EndOfTrack(0));
            }
            Play(tempSequence);
        }
 public static MidiSequence Convert(MidiSequence sequence, int format, FormatConversionOptions options)
 {
     if (sequence == null)
     {
         throw new ArgumentNullException("sequence");
     }
     if ((format < 0) || (format > 2))
     {
         throw new ArgumentOutOfRangeException("format", format, "The format must be 0, 1, or 2.");
     }
     if (sequence.Format == format)
     {
         return sequence;
     }
     if ((format != 0) || (sequence.NumberOfTracks == 1))
     {
         sequence.SetFormat(format);
         return sequence;
     }
     MidiSequence sequence2 = new MidiSequence(format, sequence.Division);
     MidiTrack track = sequence2.AddTrack();
     foreach (MidiTrack track2 in sequence)
     {
         track2.Events.ConvertDeltasToTotals();
     }
     int num = 0;
     foreach (MidiTrack track3 in sequence)
     {
         foreach (MidiEvent event2 in track3.Events)
         {
             if ((((options & FormatConversionOptions.CopyTrackToChannel) > FormatConversionOptions.None) && (event2 is VoiceMidiEvent)) && ((num >= 0) && (num <= 15)))
             {
                 ((VoiceMidiEvent) event2).Channel = (byte) num;
             }
             if (!(event2 is EndOfTrack))
             {
                 track.Events.Add(event2);
             }
         }
         num++;
     }
     track.Events.SortByTime();
     track.Events.ConvertTotalsToDeltas();
     track.Events.Add(new EndOfTrack(0L));
     return sequence2;
 }
 public static MidiSequence Trim(MidiSequence sequence, long totalTime)
 {
     MidiSequence sequence2 = new MidiSequence(sequence.Format, sequence.Division);
     foreach (MidiTrack track in sequence)
     {
         MidiTrack track2 = sequence2.AddTrack();
         track.Events.ConvertDeltasToTotals();
         for (int i = 0; (i < track.Events.Count) && (track.Events[i].DeltaTime < totalTime); i++)
         {
             track2.Events.Add(track.Events[i].Clone());
         }
         track.Events.ConvertTotalsToDeltas();
         track2.Events.ConvertTotalsToDeltas();
         if (!track2.HasEndOfTrack)
         {
             track2.Events.Add(new EndOfTrack(0L));
         }
     }
     return sequence2;
 }
 public static MidiSequence Import(Stream inputStream)
 {
     if (inputStream == null)
     {
         throw new ArgumentNullException("inputStream");
     }
     if (!inputStream.CanRead)
     {
         throw new ArgumentException("Stream must be readable.", "inputStream");
     }
     MThdChunkHeader header = MThdChunkHeader.Read(inputStream);
     MTrkChunkHeader[] headerArray = new MTrkChunkHeader[header.NumberOfTracks];
     for (int i = 0; i < header.NumberOfTracks; i++)
     {
         headerArray[i] = MTrkChunkHeader.Read(inputStream);
     }
     MidiSequence sequence = new MidiSequence(header.Format, header.Division);
     for (int j = 0; j < header.NumberOfTracks; j++)
     {
         sequence.AddTrack(MidiParser.ParseToTrack(headerArray[j].Data));
     }
     return sequence;
 }
예제 #8
0
        /// <summary>Converts a MIDI sequence from its current format to the specified format.</summary>
        /// <param name="sequence">The sequence to be converted.</param>
        /// <param name="format">The format to which we want to convert the sequence.</param>
        /// <param name="options">Options used when doing the conversion.</param>
        /// <returns>The converted sequence.</returns>
        /// <remarks>
        /// This may or may not return the same sequence as passed in.
        /// Regardless, the reference passed in should not be used after this call as the old
        /// sequence could be unusable if a different reference was returned.
        /// </remarks>
        public static MidiSequence Convert(MidiSequence sequence, int format, FormatConversionOptions options)
        {
            // Validate the parameters
            if (sequence == null)
            {
                throw new ArgumentNullException("sequence");
            }
            if (format < 0 || format > 2)
            {
                throw new ArgumentOutOfRangeException("format", format, "The format must be 0, 1, or 2.");
            }

            // Handle the simple cases
            if (sequence.Format == format)
            {
                return(sequence);                                       // already in requested format
            }
            if (format != 0 || sequence.NumberOfTracks == 1)            // only requires change in format #
            {
                // Change the format and return the same sequence
                sequence.SetFormat(format);
                return(sequence);
            }

            // Now the hard one, converting to format 0.
            // We need to combine all tracks into 1.
            MidiSequence newSequence = new MidiSequence(format, sequence.Division);
            MidiTrack    newTrack    = newSequence.AddTrack();

            // Iterate through all events in all tracks and change deltaTimes to actual times.
            // We'll then be able to sort based on time and change them back to deltas later
            foreach (MidiTrack track in sequence)
            {
                track.Events.ConvertDeltasToTotals();
            }

            // Add all events to new track (except for end of track markers!)
            int trackNumber = 0;

            foreach (MidiTrack track in sequence)
            {
                foreach (MidiEvent midiEvent in track.Events)
                {
                    // If this event has a channel, and if we're storing tracks as channels, copy to it
                    if ((options & FormatConversionOptions.CopyTrackToChannel) > 0 &&
                        (midiEvent is VoiceMidiEvent) &&
                        trackNumber >= 0 && trackNumber <= 0xF)
                    {
                        ((VoiceMidiEvent)midiEvent).Channel = (byte)trackNumber;
                    }

                    // Add all events, except for end of track markers (we'll add our own)
                    if (!(midiEvent is EndOfTrack))
                    {
                        newTrack.Events.Add(midiEvent);
                    }
                }
                trackNumber++;
            }

            // Sort the events
            newTrack.Events.SortByTime();

            // Now go back through all of the events and update the times to be deltas
            newTrack.Events.ConvertTotalsToDeltas();

            // Put an end of track on for good measure as we've already taken out
            // all of the ones that were in the original tracks.
            newTrack.Events.Add(new EndOfTrack(0));

            // Return the new sequence
            return(newSequence);
        }
 public static void Play(MidiEventCollection events, int division)
 {
     MidiSequence sequence = new MidiSequence(0, division);
     MidiTrack track = sequence.AddTrack();
     track.Events.Add(events);
     if (!track.HasEndOfTrack)
     {
         track.Events.Add(new EndOfTrack(0L));
     }
     Play(sequence);
 }
 public static void Play(MidiTrack track, int division)
 {
     MidiSequence sequence = new MidiSequence(0, division);
     sequence.AddTrack(track);
     Play(sequence);
 }
예제 #11
0
        /// <summary>Trims a MIDI file to a specified length.</summary>
        /// <param name="sequence">The sequence to be copied and trimmed.</param>
        /// <param name="totalTime">The requested time length of the new MIDI sequence.</param>
        /// <returns>A MIDI sequence with only those events that fell before the requested time limit.</returns>
        public static MidiSequence Trim(MidiSequence sequence, long totalTime)
        {
            // Create a new sequence to mimic the old
            MidiSequence newSequence = new MidiSequence(sequence.Format, sequence.Division);

            // Copy each track up to the specified time limit
            foreach(MidiTrack track in sequence)
            {
                // Create a new track in the new sequence to match the old track in the old sequence
                MidiTrack newTrack = newSequence.AddTrack();

                // Convert all times in the old track to deltas
                track.Events.ConvertDeltasToTotals();

                // Copy over all events that fell before the specified time
                for(int i=0; i<track.Events.Count && track.Events[i].DeltaTime < totalTime; i++)
                {
                    newTrack.Events.Add(track.Events[i].Clone());
                }

                // Convert all times back (on both new and old tracks; the new one inherited the totals)
                track.Events.ConvertTotalsToDeltas();
                newTrack.Events.ConvertTotalsToDeltas();

                // If the new track lacks an end of track, add one
                if (!newTrack.HasEndOfTrack) newTrack.Events.Add(new EndOfTrack(0));
            }

            // Return the new sequence
            return newSequence;
        }
예제 #12
0
        /// <summary>Reads a MIDI stream into a new MidiSequence.</summary>
        /// <param name="inputStream">The stream containing the MIDI data.</param>
        /// <returns>A MidiSequence containing the parsed MIDI data.</returns>
        public static MidiSequence Import(Stream inputStream)
        {
            // Validate input
            if (inputStream == null) throw new ArgumentNullException("inputStream");
            if (!inputStream.CanRead) throw new ArgumentException("Stream must be readable.", "inputStream");

            // Read in the main MIDI header
            MThdChunkHeader mainHeader = MThdChunkHeader.Read(inputStream);

            // Read in all of the tracks
            MTrkChunkHeader [] trackChunks = new MTrkChunkHeader[mainHeader.NumberOfTracks];
            for(int i=0; i<mainHeader.NumberOfTracks; i++)
            {
                trackChunks[i] = MTrkChunkHeader.Read(inputStream);
            }

            // Create the MIDI sequence
            MidiSequence sequence = new MidiSequence(mainHeader.Format, mainHeader.Division);
            for(int i=0; i<mainHeader.NumberOfTracks; i++)
            {
                sequence.AddTrack(MidiParser.ParseToTrack(trackChunks[i].Data));
            }
            return sequence;
        }
예제 #13
0
        /// <summary>Converts a MIDI sequence from its current format to the specified format.</summary>
        /// <param name="sequence">The sequence to be converted.</param>
        /// <param name="format">The format to which we want to convert the sequence.</param>
        /// <param name="options">Options used when doing the conversion.</param>
        /// <returns>The converted sequence.</returns>
        /// <remarks>
        /// This may or may not return the same sequence as passed in.
        /// Regardless, the reference passed in should not be used after this call as the old
        /// sequence could be unusable if a different reference was returned.
        /// </remarks>
        public static MidiSequence Convert(MidiSequence sequence, int format, FormatConversionOptions options)
        {
            // Validate the parameters
            if (sequence == null) throw new ArgumentNullException("sequence");
            if (format < 0 || format > 2) throw new ArgumentOutOfRangeException("format", format, "The format must be 0, 1, or 2.");

            // Handle the simple cases
            if (sequence.Format == format) return sequence; // already in requested format
            if (format != 0 || sequence.NumberOfTracks == 1) // only requires change in format #
            {
                // Change the format and return the same sequence
                sequence.SetFormat(format);
                return sequence;
            }

            // Now the hard one, converting to format 0.
            // We need to combine all tracks into 1.
            MidiSequence newSequence = new MidiSequence(format, sequence.Division);
            MidiTrack newTrack = newSequence.AddTrack();

            // Iterate through all events in all tracks and change deltaTimes to actual times.
            // We'll then be able to sort based on time and change them back to deltas later
            foreach(MidiTrack track in sequence) track.Events.ConvertDeltasToTotals();

            // Add all events to new track (except for end of track markers!)
            int trackNumber = 0;
            foreach(MidiTrack track in sequence)
            {
                foreach(MidiEvent midiEvent in track.Events)
                {
                    // If this event has a channel, and if we're storing tracks as channels, copy to it
                    if ((options & FormatConversionOptions.CopyTrackToChannel) > 0 &&
                        (midiEvent is VoiceMidiEvent) &&
                        trackNumber >= 0 && trackNumber <= 0xF)
                    {
                        ((VoiceMidiEvent)midiEvent).Channel = (byte)trackNumber;
                    }

                    // Add all events, except for end of track markers (we'll add our own)
                    if (!(midiEvent is EndOfTrack)) newTrack.Events.Add(midiEvent);
                }
                trackNumber++;
            }

            // Sort the events
            newTrack.Events.SortByTime();

            // Now go back through all of the events and update the times to be deltas
            newTrack.Events.ConvertTotalsToDeltas();

            // Put an end of track on for good measure as we've already taken out
            // all of the ones that were in the original tracks.
            newTrack.Events.Add(new EndOfTrack(0));

            // Return the new sequence
            return newSequence;
        }
예제 #14
0
파일: MidiPlayer.cs 프로젝트: rsenn/s2midi
 /// <summary>Plays an individual MIDI track.</summary>
 /// <param name="track">The track to be played.</param>
 /// <param name="division">The MIDI division to use for playing the track.</param>
 public static void Play(MidiTrack track, int division)
 {
     // Wrap the track in a sequence and play it
     MidiSequence tempSequence = new MidiSequence(0, division);
     tempSequence.AddTrack(track);
     Play(tempSequence);
 }
예제 #15
0
파일: MidiPlayer.cs 프로젝트: rsenn/s2midi
 /// <summary>Plays a collection of MIDI events.</summary>
 /// <param name="events">The events to be played.</param>
 /// <param name="division">The division to use for playing the events.</param>
 public static void Play(MidiEventCollection events, int division)
 {
     // Add all of the events to a temporary track and sequence, then play it
     MidiSequence tempSequence = new MidiSequence(0, division);
     MidiTrack tempTrack = tempSequence.AddTrack();
     tempTrack.Events.Add(events);
     if (!tempTrack.HasEndOfTrack) tempTrack.Events.Add(new EndOfTrack(0));
     Play(tempSequence);
 }