示例#1
0
        /// <summary>
        /// Ends the current recording session, returning a MIDI file
        /// </summary>
        /// <param name="trimRemainder">Indicates whether or not the silent remainder of the recording (if any) is trimmed</param>
        /// <returns>The MIDI file containing the recorded performance, or null if recording was never started.</returns>
        /// <remarks>The returned file is always a type 1 MIDI file at the stream's timebase, and following the stream's tempo. The file consists of two tracks. Track 0 is a meta track containing the tempo map, and the other track contains the performance data</remarks>
        public MidiFile EndRecording(bool trimRemainder = false)
        {
            if (IntPtr.Zero == _handle)
            {
                throw new InvalidOperationException("The device is closed.");
            }
            if (0 == _recordingLastTimestamp)
            {
                return(null);
            }
            var result = new MidiFile(1, unchecked ((short)_timeBase));
            var tb     = _timeBase;
            var mt     = _microTempo;
            var pos    = _recordingPos;
            var ts     = _recordingLastTimestamp;

            Interlocked.Exchange(ref _recordingLastTimestamp, 0);
            Interlocked.Exchange(ref _recordingPos, 0);
            lock (_recordingTrack0Lock)
            {
                result.Tracks.Add(_recordingTrack0);
                Interlocked.Exchange(ref _recordingTrack0, null);
            }
            result.Tracks.Add(_recordingSequence);
            Interlocked.Exchange(ref _recordingSequence, null);
            var endTrack = new MidiSequence();
            int len;

            if (!trimRemainder)
            {
                // we need to compute the number of MIDI ticks since
                // _recordingLastTimestamp (last message received)
                // first recompute our timing
                var ticksusec    = mt / (double)tb;
                var tickspertick = ticksusec / (TimeSpan.TicksPerMillisecond / 1000) * 100;
                // now convert the time difference to MIDI ticks
                var remst = unchecked ((int)Math.Round((_PreciseUtcNowTicks - ts) / tickspertick, MidpointRounding.AwayFromZero));
                // tack it on to the length
                len = pos + remst;
            }
            else
            {
                len = result.Tracks[1].Length;
            }
            endTrack.Events.Add(new MidiEvent(len, new MidiMessageMetaEndOfTrack()));
            result.Tracks[0] = MidiSequence.Merge(result.Tracks[0], endTrack);
            result.Tracks[1] = MidiSequence.Merge(result.Tracks[1], endTrack);
            return(result);
        }
示例#2
0
 /// <summary>
 /// Plays the file over the specified device
 /// </summary>
 /// <param name="deviceIndex">The index of the device to use</param>
 /// <param name="loop">Indicates whether to loop playback or not</param>
 public void Preview(int deviceIndex = 0, bool loop = false)
 {
     MidiSequence.Merge(Tracks).Preview(TimeBase, deviceIndex, loop);
 }
示例#3
0
 /// <summary>
 /// Plays the file over the specified device
 /// </summary>
 /// <param name="device">The MIDI output device to use</param>
 /// <param name="loop">Indicates whether to loop playback or not</param>
 public void Preview(MidiOutputDevice device = null, bool loop = false)
 {
     MidiSequence.Merge(Tracks).Preview(TimeBase, device, loop);
 }