/Source/Glissando/Modified MIDI Toolkit/LocalSequencer.cs
http://glissando.codeplex.com · C# · 391 lines · 306 code · 85 blank · 0 comment · 27 complexity · 46a238d9336033788c7b68de9d4be026 MD5 · raw file
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using Sanford.Multimedia.Midi;
-
- namespace Glissando
- {
- public class SequencerModified : IComponent
- {
- private Sequence sequence = null;
-
- private List<IEnumerator<int>> enumerators = new List<IEnumerator<int>>();
-
- private MessageDispatcher dispatcher = new MessageDispatcher();
-
- private ChannelChaser chaser = new ChannelChaser();
-
- private ChannelStopper stopper = new ChannelStopper();
-
- private MidiInternalClockModified clock = new MidiInternalClockModified();
-
- private int tracksPlayingCount;
-
- private readonly object lockObject = new object();
-
- private bool playing = false;
-
- private bool disposed = false;
-
- private ISite site = null;
-
- public MidiInternalClockModified Clock { get { return clock; } }
-
- #region Events
-
- public event EventHandler PlayingCompleted;
-
- public event EventHandler<ChannelMessageEventArgs> ChannelMessagePlayed
- {
- add
- {
- dispatcher.ChannelMessageDispatched += value;
- }
- remove
- {
- dispatcher.ChannelMessageDispatched -= value;
- }
- }
-
- public event EventHandler<SysExMessageEventArgs> SysExMessagePlayed
- {
- add
- {
- dispatcher.SysExMessageDispatched += value;
- }
- remove
- {
- dispatcher.SysExMessageDispatched -= value;
- }
- }
-
- public event EventHandler<MetaMessageEventArgs> MetaMessagePlayed
- {
- add
- {
- dispatcher.MetaMessageDispatched += value;
- }
- remove
- {
- dispatcher.MetaMessageDispatched -= value;
- }
- }
-
- public event EventHandler<ChasedEventArgs> Chased
- {
- add
- {
- chaser.Chased += value;
- }
- remove
- {
- chaser.Chased -= value;
- }
- }
-
- public event EventHandler<StoppedEventArgs> Stopped
- {
- add
- {
- stopper.Stopped += value;
- }
- remove
- {
- stopper.Stopped -= value;
- }
- }
-
- #endregion
-
- public SequencerModified()
- {
- clock.Tempo = 5000000; // microseconds per beat
-
- dispatcher.MetaMessageDispatched += delegate(object sender, MetaMessageEventArgs e)
- {
- if(e.Message.MetaType == MetaType.EndOfTrack)
- {
- tracksPlayingCount--;
-
- if(tracksPlayingCount == 0)
- {
- Stop();
-
- OnPlayingCompleted(EventArgs.Empty);
- }
- }
- else
- {
- clock.Process(e.Message);
- }
- };
-
- dispatcher.ChannelMessageDispatched += delegate(object sender, ChannelMessageEventArgs e)
- {
- stopper.Process(e.Message);
- };
-
- clock.Tick += delegate(object sender, EventArgs e)
- {
- lock(lockObject)
- {
- if(!playing)
- {
- return;
- }
-
- foreach(IEnumerator<int> enumerator in enumerators)
- {
- enumerator.MoveNext();
- }
- }
- };
- }
-
- ~SequencerModified()
- {
- Dispose(false);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if(disposing)
- {
- lock(lockObject)
- {
- Stop();
-
- clock.Dispose();
-
- disposed = true;
-
- GC.SuppressFinalize(this);
- }
- }
- }
-
- public void Start()
- {
- #region Require
-
- if(disposed)
- {
- throw new ObjectDisposedException(this.GetType().Name);
- }
-
- #endregion
-
- lock(lockObject)
- {
- Stop();
-
- Position = 0;
-
- Continue();
- }
- }
-
- public void Continue()
- {
- #region Require
-
- if(disposed)
- {
- throw new ObjectDisposedException(this.GetType().Name);
- }
-
- #endregion
-
- #region Guard
-
- if(Sequence == null)
- {
- return;
- }
-
- #endregion
-
- lock(lockObject)
- {
- Stop();
-
- enumerators.Clear();
-
- foreach(Track t in Sequence)
- {
- enumerators.Add(t.TickIterator(Position, chaser, dispatcher).GetEnumerator());
- }
-
- tracksPlayingCount = Sequence.Count;
-
- playing = true;
- clock.Ppqn = sequence.Division;
- clock.Continue();
- }
- }
-
- public void Stop()
- {
- #region Require
-
- if(disposed)
- {
- throw new ObjectDisposedException(this.GetType().Name);
- }
-
- #endregion
-
- lock(lockObject)
- {
- #region Guard
-
- if(!playing)
- {
- return;
- }
-
- #endregion
-
- playing = false;
- clock.Stop();
- stopper.AllSoundOff();
- }
- }
-
- protected virtual void OnPlayingCompleted(EventArgs e)
- {
- EventHandler handler = PlayingCompleted;
-
- if(handler != null)
- {
- handler(this, e);
- }
- }
-
- protected virtual void OnDisposed(EventArgs e)
- {
- EventHandler handler = Disposed;
-
- if(handler != null)
- {
- handler(this, e);
- }
- }
-
- public int Position
- {
- get
- {
- #region Require
-
- if(disposed)
- {
- throw new ObjectDisposedException(this.GetType().Name);
- }
-
- #endregion
-
- return clock.Ticks;
- }
- set
- {
- #region Require
-
- if(disposed)
- {
- throw new ObjectDisposedException(this.GetType().Name);
- }
- else if(value < 0)
- {
- throw new ArgumentOutOfRangeException();
- }
-
- #endregion
-
- bool wasPlaying;
-
- lock(lockObject)
- {
- wasPlaying = playing;
-
- Stop();
-
- clock.SetTicks(value);
- }
-
- lock(lockObject)
- {
- if(wasPlaying)
- {
- Continue();
- }
- }
- }
- }
-
- public Sequence Sequence
- {
- get
- {
- return sequence;
- }
- set
- {
- #region Require
-
- if(value == null)
- {
- throw new ArgumentNullException();
- }
- else if(value.SequenceType == SequenceType.Smpte)
- {
- throw new NotSupportedException();
- }
-
- #endregion
-
- lock(lockObject)
- {
- Stop();
- sequence = value;
- }
- }
- }
-
- #region IComponent Members
-
- public event EventHandler Disposed;
-
- public ISite Site
- {
- get
- {
- return site;
- }
- set
- {
- site = value;
- }
- }
-
- #endregion
-
- #region IDisposable Members
-
- public void Dispose()
- {
- #region Guard
-
- if(disposed)
- {
- return;
- }
-
- #endregion
-
- Dispose(true);
- }
-
- #endregion
- }
- }