diff --git a/UnityProject/Assembly-CSharp-Editor.csproj b/UnityProject/Assembly-CSharp-Editor.csproj index 30b193e..4c5f88f 100644 --- a/UnityProject/Assembly-CSharp-Editor.csproj +++ b/UnityProject/Assembly-CSharp-Editor.csproj @@ -62,6 +62,7 @@ + diff --git a/UnityProject/Assembly-CSharp.csproj b/UnityProject/Assembly-CSharp.csproj index 7effe5d..f2e29c0 100644 --- a/UnityProject/Assembly-CSharp.csproj +++ b/UnityProject/Assembly-CSharp.csproj @@ -73,9 +73,9 @@ - + @@ -89,6 +89,7 @@ + diff --git a/UnityProject/Assets/Editor/PdBackendEditor.cs b/UnityProject/Assets/Editor/PdBackendEditor.cs index 2e6da97..63ee640 100644 --- a/UnityProject/Assets/Editor/PdBackendEditor.cs +++ b/UnityProject/Assets/Editor/PdBackendEditor.cs @@ -8,7 +8,7 @@ namespace cylvester { private PdBackend pdBackend_; private SerializedProperty midiMessageReceivedProperty_; - private SerializedProperty midiClockReceivedProperty_; + private SerializedProperty midiSyncReceivedProperty_; private readonly string[] samples_ = { @@ -38,8 +38,8 @@ namespace cylvester midiMessageReceivedProperty_ = serializedObject.FindProperty("midiMessageReceived"); EditorGUILayout.PropertyField(midiMessageReceivedProperty_); - midiClockReceivedProperty_ = serializedObject.FindProperty("midiClockReceived"); - EditorGUILayout.PropertyField(midiClockReceivedProperty_); + midiSyncReceivedProperty_ = serializedObject.FindProperty("midiSyncReceived"); + EditorGUILayout.PropertyField(midiSyncReceivedProperty_); if (Application.isPlaying) { diff --git a/UnityProject/Assets/Editor/SequencerEditor.cs b/UnityProject/Assets/Editor/SequencerEditor.cs new file mode 100644 index 0000000..1ee50f6 --- /dev/null +++ b/UnityProject/Assets/Editor/SequencerEditor.cs @@ -0,0 +1,34 @@ +using UnityEditor; +using UnityEngine; + +namespace cylvester +{ + [CustomEditor(typeof(Sequencer))] + public class SequencerEditor : Editor + { + private SerializedProperty sequenceProperty_; + private void OnEnable() + { + sequenceProperty_ = serializedObject.FindProperty("sequence"); + } + + public override void OnInspectorGUI() + { + serializedObject.Update (); + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Trigger on:", GUILayout.Width(200)); + EditorGUILayout.BeginHorizontal(GUILayout.Width(160)); + + for (var i = 0; i < 16; ++i) + { + sequenceProperty_.GetArrayElementAtIndex(i).boolValue + = EditorGUILayout.Toggle(sequenceProperty_.GetArrayElementAtIndex(i).boolValue); + } + + EditorGUILayout.EndHorizontal(); + EditorGUILayout.EndHorizontal(); + serializedObject.ApplyModifiedProperties (); + } + } + +} diff --git a/UnityProject/Assets/Editor/SequencerEditor.cs.meta b/UnityProject/Assets/Editor/SequencerEditor.cs.meta new file mode 100644 index 0000000..9c22a2d --- /dev/null +++ b/UnityProject/Assets/Editor/SequencerEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 271cb432726f4f145aef895a05d2a97a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Scenes/Examples/MIDI/MIDI.unity b/UnityProject/Assets/Scenes/Examples/MIDI/MIDI.unity index 9d55f96..014f6b3 100644 --- a/UnityProject/Assets/Scenes/Examples/MIDI/MIDI.unity +++ b/UnityProject/Assets/Scenes/Examples/MIDI/MIDI.unity @@ -480,6 +480,7 @@ GameObject: - component: {fileID: 1261823480} - component: {fileID: 1261823482} - component: {fileID: 1261823483} + - component: {fileID: 1261823484} m_Layer: 0 m_Name: PdBackend m_TagString: Untagged @@ -524,12 +525,12 @@ MonoBehaviour: m_StringArgument: m_BoolArgument: 0 m_CallState: 2 - midiClockReceived: + midiSyncReceived: m_PersistentCalls: m_Calls: - m_Target: {fileID: 1261823483} - m_MethodName: onClockReceived - m_Mode: 1 + m_MethodName: OnSyncReceived + m_Mode: 0 m_Arguments: m_ObjectArgument: {fileID: 0} m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine @@ -539,8 +540,8 @@ MonoBehaviour: m_BoolArgument: 0 m_CallState: 2 - m_Target: {fileID: 669316603} - m_MethodName: onClockReceived - m_Mode: 1 + m_MethodName: onSyncReceived + m_Mode: 0 m_Arguments: m_ObjectArgument: {fileID: 0} m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine @@ -592,6 +593,19 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: counter: {fileID: 1790437805} +--- !u!114 &1261823484 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1261823479} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6ebe1124d37e04742be155475d179a67, type: 3} + m_Name: + m_EditorClassIdentifier: + sequence: 00000000000000000000000000000000 --- !u!1 &1461024797 GameObject: m_ObjectHideFlags: 0 diff --git a/UnityProject/Assets/Scenes/Examples/MIDI/script/CubeSync.cs b/UnityProject/Assets/Scenes/Examples/MIDI/script/CubeSync.cs index 8b09076..ea9bfb9 100644 --- a/UnityProject/Assets/Scenes/Examples/MIDI/script/CubeSync.cs +++ b/UnityProject/Assets/Scenes/Examples/MIDI/script/CubeSync.cs @@ -1,4 +1,5 @@ -using UnityEngine; +using cylvester; +using UnityEngine; public class CubeSync : MonoBehaviour { @@ -8,15 +9,18 @@ public class CubeSync : MonoBehaviour private float lastCallBack_; private float callbackInterval_ = 0.05f; - public void onClockReceived() + public void onSyncReceived(MidiSync midiSync) { - var now = Time.realtimeSinceStartup; - callbackInterval_ = now - lastCallBack_; - lastCallBack_ = now; - currentX_ = (counter_ - 12) * 0.2f; - counter_++; - targetX_ = (counter_ - 12) * 0.2f; - counter_ %= 24; + if (midiSync == MidiSync.Clock) + { + var now = Time.realtimeSinceStartup; + callbackInterval_ = now - lastCallBack_; + lastCallBack_ = now; + currentX_ = (counter_ - 12) * 0.2f; + counter_++; + targetX_ = (counter_ - 12) * 0.2f; + counter_ %= 24; + } } public void Update() diff --git a/UnityProject/Assets/Scripts/PdConnection/MidiClockCounter.cs b/UnityProject/Assets/Scripts/PdConnection/MidiClockCounter.cs deleted file mode 100644 index 0a1f37d..0000000 --- a/UnityProject/Assets/Scripts/PdConnection/MidiClockCounter.cs +++ /dev/null @@ -1,21 +0,0 @@ - -using UnityEngine; -using UnityEngine.UI; - -public class MidiClockCounter : MonoBehaviour -{ - - [SerializeField] private Text counter; - - private int count_ = 0; - - public void onClockReceived() - { - count_++; - var tick = count_ % 24; - var beat = count_ / 24; - var measure = beat / 4; - - counter.text = (measure+1) + ":" + (beat%4+1) + ":" + tick; - } -} diff --git a/UnityProject/Assets/Scripts/PdConnection/MidiParser.cs b/UnityProject/Assets/Scripts/PdConnection/MidiParser.cs index 395c315..f229bd2 100644 --- a/UnityProject/Assets/Scripts/PdConnection/MidiParser.cs +++ b/UnityProject/Assets/Scripts/PdConnection/MidiParser.cs @@ -6,6 +6,17 @@ namespace cylvester [Serializable] public class UnityMidiEvent : UnityEvent {} + + [Serializable] + public class UnitySyncEvent : UnityEvent + {} + + public enum MidiSync + { + Start = 250, + Stop = 252, + Clock = 248, + } public struct MidiMessage { @@ -24,8 +35,7 @@ namespace cylvester public interface IMidiParser : IDisposable { event Action MidiMessageReceived; - event Action MidiClockReceived; - + event Action MidiSyncReceived; } public class MidiParser : IMidiParser @@ -41,7 +51,6 @@ namespace cylvester private Accept accept_ = Accept.StatusByte; private readonly IPdReceiver pdReceiver_; private readonly Action onDataReceived_; - private static byte MIDI_CLOCK = 248; public MidiParser(IPdReceiver pdReceiver) { @@ -51,9 +60,9 @@ namespace cylvester { foreach (var element in bytes) { - if (element == MIDI_CLOCK) - MidiClockReceived?.Invoke(); - + if (ProcessSyncByte(element)) + continue; + if (element >= 128) { message_ = new MidiMessage {Status = element}; @@ -82,8 +91,19 @@ namespace cylvester { pdReceiver_.DataReceived -= onDataReceived_; } + + private bool ProcessSyncByte(byte element) + { + if (element != (byte)MidiSync.Clock && + element != (byte)MidiSync.Start && + element != (byte)MidiSync.Stop) + return false; + + MidiSyncReceived?.Invoke((MidiSync)element); + return true; + } public event Action MidiMessageReceived; - public event Action MidiClockReceived; + public event Action MidiSyncReceived; } } \ No newline at end of file diff --git a/UnityProject/Assets/Scripts/PdConnection/MidiSyncCounter.cs b/UnityProject/Assets/Scripts/PdConnection/MidiSyncCounter.cs new file mode 100644 index 0000000..2a7b365 --- /dev/null +++ b/UnityProject/Assets/Scripts/PdConnection/MidiSyncCounter.cs @@ -0,0 +1,33 @@ +using cylvester; +using UnityEngine; +using UnityEngine.UI; + +public class MidiSyncCounter : MonoBehaviour +{ + + [SerializeField] private Text counter; + + private int count_ = 0; + + public void OnSyncReceived(MidiSync midiSync) + { + if (midiSync == MidiSync.Clock) + { + count_++; + var tick = count_ % 24; + var beat = count_ / 24; + var measure = beat / 4; + + counter.text = (measure + 1) + ":" + (beat % 4 + 1) + ":" + tick; + } + else if (midiSync == MidiSync.Start) + { + Debug.Log("playback started"); + count_ = 0; + } + else if (midiSync == MidiSync.Stop) + { + Debug.Log("playback ended"); + } + } +} diff --git a/UnityProject/Assets/Scripts/PdConnection/MidiClockCounter.cs.meta b/UnityProject/Assets/Scripts/PdConnection/MidiSyncCounter.cs.meta similarity index 100% rename from UnityProject/Assets/Scripts/PdConnection/MidiClockCounter.cs.meta rename to UnityProject/Assets/Scripts/PdConnection/MidiSyncCounter.cs.meta diff --git a/UnityProject/Assets/Scripts/PdConnection/PdBackend.cs b/UnityProject/Assets/Scripts/PdConnection/PdBackend.cs index 30a30b1..7572b22 100644 --- a/UnityProject/Assets/Scripts/PdConnection/PdBackend.cs +++ b/UnityProject/Assets/Scripts/PdConnection/PdBackend.cs @@ -18,7 +18,7 @@ namespace cylvester public class PdBackend : MonoBehaviour, IPdBackend { [SerializeField] UnityMidiEvent midiMessageReceived = null; - [SerializeField] UnityEvent midiClockReceived = null; + [SerializeField] UnitySyncEvent midiSyncReceived = null; public int samplePlayback; @@ -39,7 +39,7 @@ namespace cylvester private Action onSamplePlaybackChanged_; private Action onMidiMessageReceived_; - private Action onMidiClockReceived_; + private Action onMidiSyncReceived_; private void Awake() { @@ -72,11 +72,11 @@ namespace cylvester }; onMidiMessageReceived_ = (message) => { midiMessageReceived.Invoke(message); }; - onMidiClockReceived_ = () => { midiClockReceived.Invoke(); }; + onMidiSyncReceived_ = (sync) => { midiSyncReceived.Invoke(sync); }; samplePlaybackObserver_.ValueChanged += onSamplePlaybackChanged_; midiParser_.MidiMessageReceived += onMidiMessageReceived_; - midiParser_.MidiClockReceived += onMidiClockReceived_; + midiParser_.MidiSyncReceived += onMidiSyncReceived_; dspController_.State = true; } @@ -86,7 +86,7 @@ namespace cylvester pdSender_?.Dispose(); samplePlaybackObserver_.ValueChanged -= onSamplePlaybackChanged_; midiParser_.MidiMessageReceived -= onMidiMessageReceived_; - midiParser_.MidiClockReceived -= onMidiClockReceived_; + midiParser_.MidiSyncReceived -= onMidiSyncReceived_; } diff --git a/UnityProject/Assets/Scripts/PdConnection/Sequencer.cs b/UnityProject/Assets/Scripts/PdConnection/Sequencer.cs new file mode 100644 index 0000000..ae3c691 --- /dev/null +++ b/UnityProject/Assets/Scripts/PdConnection/Sequencer.cs @@ -0,0 +1,16 @@ +using System; +using UnityEngine; + +namespace cylvester +{ + public class Sequencer : MonoBehaviour + { + [SerializeField] private bool[] sequence = new bool[16]; + + private void OnValidate() + { + if(sequence.Length != 16) + Array.Resize(ref sequence, 16); + } + } +} diff --git a/UnityProject/Assets/Scripts/PdConnection/Sequencer.cs.meta b/UnityProject/Assets/Scripts/PdConnection/Sequencer.cs.meta new file mode 100644 index 0000000..81f68b6 --- /dev/null +++ b/UnityProject/Assets/Scripts/PdConnection/Sequencer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ebe1124d37e04742be155475d179a67 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: