예제 #1
0
 /// <summary>
 /// Creates a new instance with the specified tempo
 /// </summary>
 /// <param name="tempo">The tempo</param>
 public MidiMessageMetaTempo(double tempo) : this(MidiUtility.TempoToMicroTempo(tempo))
 {
 }
예제 #2
0
 /// <summary>
 /// Adjusts the tempo of a MIDI file
 /// </summary>
 /// <param name="tempo">The new tempo</param>
 /// <returns>A new file with an adjusted tempo. All other tempo messages are adjusted relatively to the first one</returns>
 public MidiFile AdjustTempo(double tempo)
 => AdjustTempo(MidiUtility.TempoToMicroTempo(tempo));
예제 #3
0
        /// <summary>
        /// Plays the sequence to the specified MIDI device using the specified timebase
        /// </summary>
        /// <param name="timeBase">The timebase to use, in pulses/ticks per quarter note</param>
        /// <param name="deviceIndex">The MIDI device to output to</param>
        /// <param name="loop">Indicates whether to loop playback or not</param>
        public void Preview(short timeBase = 480, int deviceIndex = 0, bool loop = false)
        {
            var handle = MidiUtility.OpenOutputDevice(deviceIndex);
            var ppq    = timeBase;
            var mt     = MidiUtility.TempoToMicroTempo(120d);

            try
            {
                while (loop)
                {
                    var ticksusec    = mt / (double)timeBase;
                    var tickspertick = ticksusec / (TimeSpan.TicksPerMillisecond / 1000) * 100;
                    var tickStart    = MidiUtility.PreciseUtcNowTicks;
                    var tickCurrent  = tickStart;

                    var end = (long)(Length * tickspertick + tickStart);
                    var tpm = TimeSpan.TicksPerMillisecond;

                    using (var e = AbsoluteEvents.GetEnumerator())
                    {
                        if (!e.MoveNext())
                        {
                            return;
                        }
                        var done = false;
                        while (!done && tickCurrent <= end)
                        {
                            tickCurrent = MidiUtility.PreciseUtcNowTicks;
                            var ce = (long)((tickCurrent - tickStart) / tickspertick);
                            while (!done && e.Current.Position <= ce)
                            {
                                if (0xFF == e.Current.Message.Status)
                                {
                                    var mbs = e.Current.Message as MidiMessageMeta;
                                    if (0x51 == mbs.Data1)
                                    {
                                        if (BitConverter.IsLittleEndian)
                                        {
                                            mt = (mbs.Data[0] << 16) | (mbs.Data[1] << 8) | mbs.Data[2];
                                        }
                                        else
                                        {
                                            mt = (mbs.Data[2] << 16) | (mbs.Data[1] << 8) | mbs.Data[0];
                                        }
                                        ticksusec    = mt / (double)ppq;
                                        tickspertick = ticksusec / (tpm / 1000) * 100;
                                        end          = (long)(Length * tickspertick + tickStart);
                                    }
                                    else if (0x2F == mbs.Data1)
                                    {
                                        done = true;
                                    }
                                }
                                MidiUtility.Send(handle, e.Current.Message);
                                if (!e.MoveNext())
                                {
                                    done = true;
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                MidiUtility.CloseOutputDevice(handle);
            }
        }