soundvision/UnityProject/Assets/Scripts/PdConnection/CylMidiTransitionController.cs

112 lines
3.9 KiB
C#
Raw Normal View History

2019-12-06 20:49:52 +00:00
using System;
using UnityEngine;
2019-12-05 12:37:20 +00:00
using UnityEngine.Playables;
namespace cylvester
2019-12-06 14:19:36 +00:00
{
public class CylMidiTransitionController : MonoBehaviour
{
2019-12-06 21:21:24 +00:00
private enum CylCommand
{
OneBarLoopButton = 94,
FourBarLoopButton = 86,
NextSelectedScene = 18,
CurrentSelectedScene = 17,
InstantTrigger = 2,
}
2019-12-05 12:37:20 +00:00
[SerializeField] private PlayableDirector playableDirector;
[SerializeField] private TimelineController timelineController;
2019-12-06 14:19:36 +00:00
[SerializeField, Range(1, 16)] private int channel = 1;
2019-12-06 20:49:52 +00:00
[SerializeField] private StateManager stateManager;
[SerializeField] private float instaTransitionSpeed = 10;
private const int OneBarTrigger = 96;
private const int FourBarTrigger = OneBarTrigger * 4;
private const float TransitionLength = 16;
2019-12-06 21:21:24 +00:00
private ScheduledAction scheduledAction_;
2019-12-06 20:49:52 +00:00
private int currentTick_;
private int currentSelectedScene_ ;
private int nextSelectedScene_;
2019-12-06 21:21:24 +00:00
private void Start()
{
scheduledAction_ = new ScheduledAction(() =>
{
stateManager.SelectedState = currentSelectedScene_;
playableDirector.playableGraph.GetRootPlayable(0).SetSpeed(instaTransitionSpeed);
});
}
public void OnSyncReceived(MidiSync midiSync, int counter)
{
2019-12-06 20:49:52 +00:00
currentTick_ = counter;
}
public void OnMidiMessageReceived(MidiMessage mes)
{
2019-12-06 20:49:52 +00:00
if (mes.Status - 176 != channel - 1) return;
2019-12-06 21:21:24 +00:00
var command = (CylCommand)mes.Data1;
2019-12-06 20:49:52 +00:00
switch (command)
{
2019-12-06 21:21:24 +00:00
case CylCommand.NextSelectedScene:
{
2019-12-06 20:49:52 +00:00
nextSelectedScene_ = mes.Data2;
2019-12-06 14:19:36 +00:00
break;
2019-12-06 20:49:52 +00:00
}
2019-12-06 21:21:24 +00:00
case CylCommand.InstantTrigger:
2019-12-06 20:49:52 +00:00
{
2019-12-06 21:21:24 +00:00
scheduledAction_.Ready();
2019-12-06 14:19:36 +00:00
break;
2019-12-06 20:49:52 +00:00
}
2019-12-06 21:21:24 +00:00
case CylCommand.CurrentSelectedScene:
2019-12-06 20:49:52 +00:00
{
currentSelectedScene_ = mes.Data2;
2019-12-06 21:21:24 +00:00
scheduledAction_.Go();
2019-12-06 14:19:36 +00:00
break;
2019-12-06 20:49:52 +00:00
}
2019-12-06 21:21:24 +00:00
case CylCommand.FourBarLoopButton:
2019-12-06 20:49:52 +00:00
{
var restTime = CalculateRestTime(FourBarTrigger - currentTick_ % FourBarTrigger);
2019-12-06 20:49:52 +00:00
if (nextSelectedScene_ > currentSelectedScene_)
{
timelineController.UpdateTransitionTargetRealTime(restTime, false);
2019-12-06 20:49:52 +00:00
stateManager.SelectedState = nextSelectedScene_;
}
else
{
timelineController.UpdateTransitionTargetRealTime(restTime, true);
stateManager.SelectedState = nextSelectedScene_ + 1;
2019-12-06 20:49:52 +00:00
}
2019-12-06 14:19:36 +00:00
break;
2019-12-06 20:49:52 +00:00
}
2019-12-06 21:21:24 +00:00
case CylCommand.OneBarLoopButton:
2019-12-06 20:49:52 +00:00
{
var restTime = CalculateRestTime(OneBarTrigger - currentTick_ % OneBarTrigger);
if (nextSelectedScene_ > currentSelectedScene_)
{
timelineController.UpdateTransitionTargetRealTime(restTime, false);
stateManager.SelectedState = nextSelectedScene_;
}
else
{
timelineController.UpdateTransitionTargetRealTime(restTime, true);
stateManager.SelectedState = nextSelectedScene_ + 1;
}
2019-12-06 20:49:52 +00:00
break;
}
default:
throw new Exception("Unexpected CYL command");
}
}
private float CalculateRestTime(int restTicks)
{
2019-12-06 21:29:46 +00:00
return restTicks / 24f / stateManager.CurrentState.Bpm * 60f;
}
}
}