示例#1
0
        /// <summary>
        /// Write a sequence to an output stream in standard midi format.
        /// <see cref="gnu.sound.midi.spi.MidiFileWriter#write(Sequence, int, Stream)"/>
        /// </summary>
        public override int Write(Sequence stream, int fileType, Stream outputStream)
        {
            var dos = new MidiDataOutputStream(outputStream);

            Track[] tracks = stream.Tracks.ToArray();
            dos.Write((int)0x4D546864);             // MThd
            dos.Write((int)6);
            dos.Write((Int16)fileType);
            dos.Write((Int16)tracks.Length);

            float divisionType = stream.DivisionType;
            int   resolution   = stream.Resolution;

            // FIXME: division computation is incomplete.
            int division = 0;

            if (divisionType == Sequence.PPQ)
            {
                division = resolution & 0x7FFF;
            }
            dos.Write((Int16)division);

            int length = 14;

            for (int i = 0; i < tracks.Length; i++)
            {
                length += WriteTrack(tracks[i], dos);
            }
            return(length);
        }
示例#2
0
        /// <summary>
        /// Write a track to an output stream.
        /// <param name="track">the track to write</param>
        /// <param name="dos">a MidiDataOutputStream to write to</param>
        /// <returns>the number of bytes written</returns>
        /// </summary>
        private int WriteTrack(Track track, MidiDataOutputStream dos)
        {
            int i           = 0;
            int eventCount  = track.EventCount();
            int trackLength = 0;

            MidiEvent previousEvent = null;

            dos.Write((int)0x4D54726B);             // "MTrk"
            trackLength = ComputeTrackLength(track, dos);
            dos.Write((int)trackLength);

            while (i < eventCount)
            {
                MidiEvent midiEvent = track.Get(i);
                int       deltaTime = 0;
                if (previousEvent != null)
                {
                    deltaTime = (int)(midiEvent.Tick - previousEvent.Tick);
                }

                dos.WriteVariableLengthInt(deltaTime);

                // FIXME: use running status byte
                byte[] msg = midiEvent.Message.GetMessage();
                dos.Write(msg);
                previousEvent = midiEvent;

                i++;
            }

            // We're done if the last event was an End of Track meta message.
            if (previousEvent != null && (previousEvent.Message is MetaMessage))
            {
                var mm = (MetaMessage)previousEvent.Message;

                // End of Track message
                if (mm.GetMetaMessageType() == (int)MidiHelper.MetaEventType.EndOfTrack)
                {
                    return(trackLength + 8);
                }
            }

            // Write End of Track meta message
            dos.WriteVariableLengthInt(0);                        // Delta time of 0
            dos.Write((byte)MidiHelper.META);                     // Meta Message
            dos.Write((byte)MidiHelper.MetaEventType.EndOfTrack); // End of Track message
            dos.WriteVariableLengthInt(0);                        // Length of 0

            return(trackLength + 8 + 4);
        }
示例#3
0
        /// <summary>
        /// Compute the length of a track as it will be written to the
        /// output stream.
        /// <param name="track">the track to measure</param>
        /// <param name="dos">a MidiDataOutputStream used for helper method</param>
        /// <returns>the length of the track</returns>
        /// </summary>
        private int ComputeTrackLength(Track track, MidiDataOutputStream dos)
        {
            int  length       = 0;
            int  i            = 0;
            int  eventCount   = track.EventCount();
            long previousTick = 0;

            while (i < eventCount)
            {
                MidiEvent midiEvent = track.Get(i);
                long      tick      = midiEvent.Tick;
                length      += MidiDataOutputStream.VariableLengthIntLength((int)(tick - previousTick));
                previousTick = tick;
                length      += midiEvent.Message.Length;
                i++;
            }
            return(length);
        }