Exemplo n.º 1
0
        /// <summary>Plays the specified MIDI sequence using Media Control Interface (MCI).</summary>
        /// <param name="sequence">The MIDI sequence to be played.</param>
        public static void Play(MidiSequence sequence)
        {
            // Validate the parameter
            if (sequence == null) throw new ArgumentNullException("sequence");

            // Save the MIDI sequence to a temporary file
            string fileName;
            try
            {
                fileName = Path.GetTempFileName();
                sequence.Save(fileName);
            }
            catch(Exception exc)
            {
                throw new ApplicationException(
                    "Unable to save the sequence to a temporary file.  " + exc.Message, exc);
            }

            // Play it from the temporary file
            //			Play(fileName);

            // Remove the temporary file
            try { File.Delete(fileName); }
            catch{}
        }
 public static void GenerateMIDICode(ICodeGenerator generator, MidiSequence sequence, string midiName, TextWriter writer)
 {
     CodeNamespace e = new CodeNamespace("AutoGenerated");
     CodeTypeDeclaration declaration = new CodeTypeDeclaration(midiName);
     declaration.Members.Add(CreateSequenceMethod(sequence));
     for (int i = 0; i < sequence.NumberOfTracks; i++)
     {
         int num2 = i + 1;
         declaration.Members.Add(CreateTrackMethod("CreateTrack" + num2.ToString(), sequence[i]));
     }
     e.Types.Add(declaration);
     generator.GenerateCodeFromNamespace(e, writer, new CodeGeneratorOptions());
 }
Exemplo n.º 3
0
        /// <summary>Creates code from a MIDI sequence.</summary>
        /// <param name="generator">Generator used to generate the actual code.</param>
        /// <param name="sequence">The sequence to translate.</param>
        /// <param name="midiName">The name of the MIDI sequence to be used as the class name.</param>
        /// <param name="writer">The writer to which the text is written.</param>
        public static void GenerateMIDICode(
            ICodeGenerator generator, MidiSequence sequence,
            string midiName, TextWriter writer)
        {
            // Create a new namespace
            CodeNamespace ns = new CodeNamespace("AutoGenerated");

            // Create the new class
            CodeTypeDeclaration midiType = new CodeTypeDeclaration(midiName);

            // Add a method to it to create the sequence
            midiType.Members.Add(CreateSequenceMethod(sequence));
            for (int i = 0; i < sequence.NumberOfTracks; i++)
            {
                midiType.Members.Add(CreateTrackMethod("CreateTrack" + (i + 1).ToString(), sequence[i]));
            }

            // Add the class to the namespace
            ns.Types.Add(midiType);

            // Generate the code
            generator.GenerateCodeFromNamespace(ns, writer, new CodeGeneratorOptions());
        }
Exemplo n.º 4
0
        /// <summary>Creates code from a MIDI sequence.</summary>
        /// <param name="generator">Generator used to generate the actual code.</param>
        /// <param name="sequence">The sequence to translate.</param>
        /// <param name="midiName">The name of the MIDI sequence to be used as the class name.</param>
        /// <param name="writer">The writer to which the text is written.</param>
        public static void GenerateMIDICode(
			ICodeGenerator generator, MidiSequence sequence, 
			string midiName, TextWriter writer)
        {
            // Create a new namespace
            CodeNamespace ns = new CodeNamespace("AutoGenerated");

            // Create the new class
            CodeTypeDeclaration midiType = new CodeTypeDeclaration(midiName);

            // Add a method to it to create the sequence
            midiType.Members.Add(CreateSequenceMethod(sequence));
            for(int i=0; i<sequence.NumberOfTracks; i++)
            {
                midiType.Members.Add(CreateTrackMethod("CreateTrack" + (i+1).ToString(), sequence[i]));
            }

            // Add the class to the namespace
            ns.Types.Add(midiType);

            // Generate the code
            generator.GenerateCodeFromNamespace(ns, writer, new CodeGeneratorOptions());
        }
Exemplo n.º 5
0
 /// <summary>Transposes a MIDI sequence up/down the specified number of half-steps.</summary>
 /// <param name="sequence">The sequence to be transposed.</param>
 /// <param name="steps">The number of steps up(+) or down(-) to transpose the sequence.</param>
 public static void Transpose(MidiSequence sequence, int steps)
 {
     // Transpose the sequence; do not transpose drum tracks
     Transpose(sequence, steps, false);
 }
Exemplo n.º 6
0
        /// <summary>Creates the code for the sequence.</summary>
        /// <param name="sequence">The sequence for which we want code.</param>
        /// <returns>The method that creates the sequence.</returns>
        private static CodeMemberMethod CreateSequenceMethod(MidiSequence sequence)
        {
            // Create the method
            CodeMemberMethod method = new CodeMemberMethod();
            method.Attributes = MemberAttributes.Public;
            method.Name = "CreateSequence";
            method.ReturnType = new CodeTypeReference(typeof(MidiSequence));

            // MidiSequence sequence = new MidiSequence(format, division);
            method.Statements.Add(
                new CodeVariableDeclarationStatement(typeof(MidiSequence), "sequence",
                new CodeObjectCreateExpression(typeof(MidiSequence),
                new CodeExpression[]{
                                        new CodePrimitiveExpression(sequence.Format),
                                        new CodePrimitiveExpression(sequence.Division)})));

            // sequence.AddTrack(CreateTrack1());
            // sequence.AddTrack(CreateTrack2());
            // ...
            // sequence.AddTrack(CreateTrackN());
            for(int i=0; i<sequence.NumberOfTracks; i++)
            {
                method.Statements.Add(new CodeMethodInvokeExpression(
                    new CodeVariableReferenceExpression("sequence"),
                    "AddTrack",
                    new CodeExpression[]{
                                            new CodeMethodInvokeExpression(
                                            new CodeThisReferenceExpression(),
                                            "CreateTrack" + (i+1).ToString())}));
            }

            // return sequence;
            method.Statements.Add(new CodeMethodReturnStatement(
                new CodeVariableReferenceExpression("sequence")));

            // Return the newly created method
            return method;
        }
 public static MidiSequence Convert(MidiSequence sequence, int format)
 {
     return Convert(sequence, format, FormatConversionOptions.None);
 }
 public static void Transpose(MidiSequence sequence, int steps, bool includeDrums)
 {
     if (sequence == null)
     {
         throw new ArgumentNullException("sequence");
     }
     foreach (MidiTrack track in sequence)
     {
         foreach (MidiEvent event2 in track.Events)
         {
             NoteVoiceMidiEvent event3 = event2 as NoteVoiceMidiEvent;
             if ((event3 != null) && (includeDrums || (event3.Channel != 9)))
             {
                 event3.Note = (byte) ((event3.Note + steps) % 0x80);
             }
         }
     }
 }
 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;
 }
Exemplo n.º 10
0
 /// <summary>Transposes a MIDI sequence up/down the specified number of half-steps.</summary>
 /// <param name="sequence">The sequence to be transposed.</param>
 /// <param name="steps">The number of steps up(+) or down(-) to transpose the sequence.</param>
 public static void Transpose(MidiSequence sequence, int steps)
 {
     // Transpose the sequence; do not transpose drum tracks
     Transpose(sequence, steps, false);
 }
Exemplo n.º 11
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;
        }
Exemplo n.º 12
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;
        }
Exemplo n.º 13
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);
 }
Exemplo n.º 14
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);
 }
Exemplo n.º 15
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>
 /// <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)
 {
     return(Convert(sequence, format, FormatConversionOptions.None));
 }
Exemplo n.º 16
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);
        }
Exemplo n.º 17
0
        /// <summary>Transposes a MIDI sequence up/down the specified number of half-steps.</summary>
        /// <param name="sequence">The sequence to be transposed.</param>
        /// <param name="steps">The number of steps up(+) or down(-) to transpose the sequence.</param>
        /// <param name="includeDrums">Whether drum tracks should also be transposed.</param>
        /// <remarks>If the step value is too large or too small, notes may wrap.</remarks>
        public static void Transpose(MidiSequence sequence, int steps, bool includeDrums)
        {
            // If the sequence is null, throw an exception.
            if (sequence == null) throw new ArgumentNullException("sequence");

            // Modify each track
            foreach(MidiTrack track in sequence)
            {
                // Modify each event
                foreach(MidiEvent ev in track.Events)
                {
                    // If the event is not a voice MIDI event but the channel is the
                    // drum channel and the user has chosen not to include drums in the
                    // transposition (which makes sense), skip this event.
                    NoteVoiceMidiEvent nvme = ev as NoteVoiceMidiEvent;
                    if (nvme == null ||
                        (!includeDrums && nvme.Channel == (byte)SpecialChannels.Percussion))
                        continue;

                    // If the event is a NoteOn, NoteOff, or Aftertouch, shift the note
                    // according to the supplied number of steps.
                    nvme.Note = (byte)((nvme.Note + steps) % 128);
                }
            }
        }
 public static void Transpose(MidiSequence sequence, int steps)
 {
     Transpose(sequence, steps, false);
 }
Exemplo n.º 19
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;
        }
 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 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 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 void Play(MidiTrack track, int division)
 {
     MidiSequence sequence = new MidiSequence(0, division);
     sequence.AddTrack(track);
     Play(sequence);
 }
 public static void Play(MidiSequence sequence)
 {
     string tempFileName;
     if (sequence == null)
     {
         throw new ArgumentNullException("sequence");
     }
     try
     {
         tempFileName = Path.GetTempFileName();
         sequence.Save(tempFileName);
     }
     catch (Exception exception)
     {
         throw new ApplicationException("Unable to save the sequence to a temporary file.  " + exception.Message, exception);
     }
     Play(tempFileName);
     try
     {
         File.Delete(tempFileName);
     }
     catch
     {
     }
 }
 private static CodeMemberMethod CreateSequenceMethod(MidiSequence sequence)
 {
     CodeMemberMethod method = new CodeMemberMethod {
         Attributes = MemberAttributes.Public,
         Name = "CreateSequence",
         ReturnType = new CodeTypeReference(typeof(MidiSequence))
     };
     method.Statements.Add(new CodeVariableDeclarationStatement(typeof(MidiSequence), "sequence", new CodeObjectCreateExpression(typeof(MidiSequence), new CodeExpression[] { new CodePrimitiveExpression(sequence.Format), new CodePrimitiveExpression(sequence.Division) })));
     for (int i = 0; i < sequence.NumberOfTracks; i++)
     {
         CodeExpression[] parameters = new CodeExpression[1];
         int num2 = i + 1;
         parameters[0] = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "CreateTrack" + num2.ToString(), new CodeExpression[0]);
         method.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("sequence"), "AddTrack", parameters));
     }
     method.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("sequence")));
     return method;
 }