示例#1
0
        /// <summary>
        /// Returns the exact tick at the time within a MIDI track.
        /// </summary>
        /// <param name="track">The MIDI track</param>
        /// <param name="time">The time in microseconds.</param>
        /// <param name="microsecondsPerTick">The microSeconds per tick of the MIDI file.</param>
        /// <returns></returns>
        private int microsecondsToTicks(MidiTrack track, double time, double microsecondsPerTick)
        {
            ushort division           = (ushort)this.music.DeltaTimeSpec;
            double currentTempo       = MidiUtil.MIDI_DEFAULT_TEMPO;
            int    passedTicks        = 0;
            double passedMicroSeconds = 0d;

            foreach (MidiMessage midiMessage in track.Messages)
            {
                passedMicroSeconds += midiMessage.DeltaTime * microsecondsPerTick;
                passedTicks        += midiMessage.DeltaTime;
                MidiEvent midiEvent = midiMessage.Event;

                if (passedMicroSeconds > time)
                {
                    // if we overstepped the set time get the time between this message and the previous one
                    double prevMsgTime = passedMicroSeconds - midiMessage.DeltaTime * microsecondsPerTick;
                    return((int)((time - prevMsgTime) / microsecondsPerTick));
                }

                if (midiEvent.EventType == MidiEvent.Meta && midiEvent.MetaType == MidiMetaType.Tempo)
                {
                    currentTempo        = MidiMetaType.GetTempo(midiEvent.Data);
                    microsecondsPerTick = currentTempo / division;
                }
            }
            return(passedTicks);
        }
示例#2
0
        /// <summary>
        /// Get the MIDI's duration in microseconds.
        /// </summary>
        public double GetDurationInMicroseconds()
        {
            double microsecondsPerTick = this.getMicrosecondsPerTick();
            ushort division            = (ushort)this.music.DeltaTimeSpec;
            double currentTempo        = MidiUtil.MIDI_DEFAULT_TEMPO;
            double midiMusicTimeLength = 0d;

            foreach (MidiTrack midiTrack in this.music.Tracks)
            {
                double trackTimeLength = 0d;
                foreach (MidiMessage midiMessage in midiTrack.Messages)
                {
                    trackTimeLength += midiMessage.DeltaTime * microsecondsPerTick;
                    MidiEvent midiEvent = midiMessage.Event;

                    if (midiEvent.EventType == MidiEvent.Meta && midiEvent.MetaType == MidiMetaType.Tempo)
                    {
                        currentTempo        = MidiMetaType.GetTempo(midiEvent.Data);
                        microsecondsPerTick = currentTempo / division;
                    }
                }

                if (trackTimeLength > midiMusicTimeLength)
                {
                    midiMusicTimeLength = trackTimeLength;
                }
            }
            return(midiMusicTimeLength);
        }
示例#3
0
 public void GetTempo()
 {
     Assert.AreEqual(500000, MidiMetaType.GetTempo(new byte[] { 7, 0xA1, 0x20 }, 0), "500000");
 }
示例#4
0
    private double GetTimeLengthInMicroseconds(MidiMusic midiMusic)
    {
        ushort       division            = (ushort)midiMusic.DeltaTimeSpec;
        const double defaultTempo        = 500000; // in microseconds per quarter-note, equals 120 beats per minute => 500000 / 1000000 * 4 * 60 = 120
        double       currentTempo        = defaultTempo;
        double       microsecondsPerTick = 0d;

        // division = 59512;

        Debug.Log("Divisions: " + System.Convert.ToString(division, 2).PadLeft(16, '0'));

        if (division >> 15 == 0)
        {
            Debug.Log("MSB is 0");

            microsecondsPerTick = currentTempo / division;
            // Debug.Log("MicrosecondsPerTick: " + microsecondsPerTick);
        }
        else
        {
            Debug.Log("MSB is 1");

            byte bitmask = 255; // 1111_1111
            byte bits    = (byte)((division >> 8) & bitmask);
            byte negatedFramesPerSecond = (byte)~bits;
            byte framesPerSecond        = (byte)(negatedFramesPerSecond + 1);
            Debug.Log("framesPerSecond: " + framesPerSecond);

            byte ticksPerFrame = (byte)(division & bitmask);
            Debug.Log("ticksPerFrame: " + System.Convert.ToString(ticksPerFrame, 2));
            Debug.Log("ticksPerFrame: " + ticksPerFrame);

            double ticksPerSecond = ticksPerFrame * framesPerSecond;
            microsecondsPerTick = 1000000 / ticksPerSecond;
        }

        double midiMusicTimeLength = 0d;

        foreach (MidiTrack midiTrack in midiMusic.Tracks)
        {
            double trackTimeLength = 0d;

            foreach (MidiMessage midiMessage in midiTrack.Messages)
            {
                trackTimeLength += midiMessage.DeltaTime * microsecondsPerTick;
                MidiEvent midiEvent = midiMessage.Event;

                if (midiEvent.EventType == MidiEvent.Meta && midiEvent.MetaType == MidiMetaType.Tempo)
                {
                    currentTempo        = MidiMetaType.GetTempo(midiEvent.Data);
                    microsecondsPerTick = currentTempo / division;
                }
            }

            if (trackTimeLength > midiMusicTimeLength)
            {
                midiMusicTimeLength = trackTimeLength;
            }
        }

        return(midiMusicTimeLength);
    }