144 lines
3.8 KiB
C#
144 lines
3.8 KiB
C#
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using JD.Audio.SoundPlayer;
|
|
using JD.Interfaces.Player;
|
|
using JD.Interfaces.Remoting;
|
|
using JD.Remoting;
|
|
|
|
namespace JD.Application.Plugin
|
|
{
|
|
/// <summary>
|
|
/// Controls the playback into the engine (play, pause, seek, ...)
|
|
/// </summary>
|
|
public class Conductor : IPlayer
|
|
{
|
|
#region Variables
|
|
|
|
private readonly List<IPlugin> _plugins;
|
|
private float _currentLocalBeat;
|
|
private float _currentAbsoluteBeat;
|
|
private bool _playing;
|
|
private readonly SeekingGuard _seekingGuard = new SeekingGuard();
|
|
private readonly PlayerTimer _timer;
|
|
public PlayerComponents Components { get; private set; }
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
public Conductor(IEnumerable<IPlugin> plugins)
|
|
{
|
|
Components = new PlayerComponents(this);
|
|
_timer = new PlayerTimer(this);
|
|
_plugins = new List<IPlugin>(plugins);
|
|
UseAbsoluteTime = false; // Use Local beat as default
|
|
|
|
// Do not handle on main thread,
|
|
foreach (var plugin in _plugins)
|
|
plugin.RegisterHandler(CommandNames.GetPlayingState, OnReceivedEnginePlayingState, dispatchOnMainThread: false);
|
|
}
|
|
|
|
public Conductor(IPlugin plugin)
|
|
: this(new IPlugin[] { plugin })
|
|
{
|
|
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
_timer.Initialize();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_timer.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
public float CurrentTime
|
|
{
|
|
get
|
|
{
|
|
if (UseAbsoluteTime)
|
|
{
|
|
return _currentAbsoluteBeat;
|
|
}
|
|
return _currentLocalBeat;
|
|
}
|
|
set
|
|
{
|
|
//Seek no available in AbsoluteTime
|
|
if (UseAbsoluteTime == false)
|
|
{
|
|
_seekingGuard.UserSeeksTo(value);
|
|
foreach (var plugin in _plugins)
|
|
plugin.Send(CommandNames.SetBeat, blob => blob.Push(value));
|
|
_currentLocalBeat = value;
|
|
_timer.Tick();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool UseAbsoluteTime { get; set; }
|
|
|
|
public bool Playing
|
|
{
|
|
get { return _playing; }
|
|
set
|
|
{
|
|
_playing = value;
|
|
foreach (var plugin in _plugins)
|
|
plugin.Send(CommandNames.SetIsPlaying, blob => blob.Push(_playing));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
private bool _receivedPlaying = false;
|
|
|
|
private void OnReceivedEnginePlayingState(IBlob blob)
|
|
{
|
|
|
|
if (!_receivedPlaying)
|
|
{
|
|
_receivedPlaying = true;
|
|
float current;
|
|
float absoluteStartBeat;
|
|
float playSpeed;
|
|
blob.Extract(out _playing);
|
|
blob.Extract(out current);
|
|
blob.Extract(out absoluteStartBeat);
|
|
blob.Extract(out playSpeed);
|
|
|
|
if (_seekingGuard.IsValidEngineTime(current))
|
|
{
|
|
_currentLocalBeat = current;
|
|
_currentAbsoluteBeat = absoluteStartBeat + current;
|
|
}
|
|
_receivedPlaying = false;
|
|
}
|
|
|
|
// Do not raise the current time changed, will be called from
|
|
// the timer which is invoked from the main thread.
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Events
|
|
|
|
public event EventHandler<EventArgs> TimeChanged
|
|
{
|
|
add { _timer.TimeChanged += value; }
|
|
remove { _timer.TimeChanged -= value; }
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|