Example #1
0
        /// <summary>
        /// Constructor (standard).
        /// </summary>
        /// <param name="TrackNumber">The defined track number for the new track. This number will be used to refer to the track when adding events.</param>
        /// <param name="TrackName">The human-readable track name for the new track.</param>
        public MIDITrack(int TrackNumber, String TrackName)
        {
            // create a list of bytes that represents the track's human-readable name.
            List <byte> trackHeader = new List <byte>();

            // populate the local holder variables for the track's number and human-readable name.
            this.TrackNumber = TrackNumber;
            this.TrackName   = TrackName;

            // instantiate the list of Events.
            Events = new List <List <byte> >();

            // populate the header event with the standard MIDI track header.
            trackHeader.Add(0x00);
            trackHeader.Add(0xFF);
            trackHeader.Add(0x03);

            // Write out the length of the track's human-readable name (as a string of characters). This is
            // defined to be a variable length quantity.
            VariableLength.WriteVariableLength(trackHeader, (ulong)TrackName.Length);

            // Go through each character in the track's human-readable name. Write it out as an ASCII byte.
            for (int x = 0; x < TrackName.Length; x++)
            {
                trackHeader.Add((byte)TrackName[x]);
            }

            // add the track's name as an event.
            Events.Add(trackHeader);
        }
Example #2
0
        /// <summary>
        /// AddNoteEvent() provides a workhorse method for the AddNote() and AddNotes() methods.
        /// Specifically, the AddNoteEvent method translates the specific notes into MIDI-format event commands.
        /// </summary>
        /// <param name="onOff">A boolean representing whether the note is beginning (analagous to a musician pressing a key) or if it is ending (analagous to a musician releasing a key). True is ON (pressing a key), and false is OFF (releasing a key).</param>
        /// <param name="nChannel">The track's channel through which the note event will be played.</param>
        /// <param name="nMidiNoteNumber">The note number (see MIDI specification for standard note numbers) that will be played or released.</param>
        /// <param name="offset">The time-tick offset after which this event will take place. A note is defined by the following sequence:
        /// 1. Call the AddNoteEvent() function with onOff defined as true for a given note, offset = 0.
        /// 2. Call the AddNoteEvent() function with onOff defined as false for a given note, offset = duration of note.
        /// The duration of the note can be found by viewing the documentation for the AddNote() and AddNotes() functions. A quarter-note is defined as 12 time-ticks.
        /// </param>
        private void AddNoteEvent(bool onOff, int nChannel, int nMidiNoteNumber, byte offset)
        {
            List <byte> newByteArray = new List <byte>();

            // write out the duration of the note as a variable length quantity.
            VariableLength.WriteVariableLength(newByteArray, offset);

            // newByteArray.Add(0xFF);

            // if the user selected true for onOff (note pressed), the 0x9X MIDI command must be used.
            // otherwise, the 0x8X MIDI command must be used.
            if (onOff == true)
            {
                newByteArray.Add((byte)((0x9 << 4) | (byte)nChannel));
            }
            else
            {
                newByteArray.Add((byte)((0x8 << 4) | (byte)nChannel));
            }

            // write out the standard MIDI note number that will be played, followed by its velocity.
            // the velocity is analogous to the pressure a musician would apply on a key. It is defined as 0x7F (full).
            newByteArray.Add((byte)nMidiNoteNumber);
            newByteArray.Add(0x7F);


            // write out the new event.
            Events.Add(newByteArray);
        }
Example #3
0
        /// <summary>
        /// Save() outputs a complete MIDI file. It accepts a FileStream that must be defined and instantiated by the calling code blocks.
        /// </summary>
        /// <param name="objWriter">A FileStream pointing to an open .mid or .midi file for output.</param>
        public void Save(MemoryStream objWriter)
        {
            // go back to the beginning of the file.
            objWriter.Seek(0, SeekOrigin.Begin);

            // write the MIDI header:
            objWriter.WriteByte(0x4D);
            objWriter.WriteByte(0x54);
            objWriter.WriteByte(0x68);
            objWriter.WriteByte(0x64);

            // write three bytes of 0x00.
            for (int x = 0; x < 3; x++)
            {
                objWriter.WriteByte(0x00);
            }

            // define the length of the MIDI header (always 0x6).
            objWriter.WriteByte(0x06);
            objWriter.WriteByte(0x00);

            // define the format of the file. If only one track, the file will be MIDI format 0.
            // if multiple tracks, the file will be MIDI format 1.
            if (Tracks.Count > 1)
            {
                if (asynchronous)
                {
                    objWriter.WriteByte(0x02);
                }
                else
                {
                    objWriter.WriteByte(0x01);
                }
            }
            else
            {
                objWriter.WriteByte(0x00);
            }

            if (Tracks.Count < 0x80)
            {
                objWriter.WriteByte(0x00);
            }

            // write out the number of tracks as a variable length quantity.
            VariableLength.WriteVariableLength(objWriter, (ulong)Tracks.Count);

            // write out the number of time-ticks (see AddNote() and AddNotes() methods) that define a quarter-note.
            // by design, this is defined to be 12 time-ticks.
            objWriter.WriteByte(0x00);
            VariableLength.WriteVariableLength(objWriter, 12);

            // go through each track in the list, and output its contents to the file.
            for (int x = 0; x < Tracks.Count; x++)
            {
                Tracks[x].Save(objWriter);
            }
        }