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

88 lines
2.3 KiB
C#
Raw Normal View History

2019-10-05 12:18:52 +00:00
using System;
using UnityEngine.Events;
namespace cylvester
{
[Serializable]
2019-10-26 20:15:30 +00:00
public class UnityControlEvent : UnityEvent<MidiMessage>
2019-10-05 12:18:52 +00:00
{}
2019-10-26 20:15:30 +00:00
public struct MidiMessage
2019-10-05 12:18:52 +00:00
{
2019-10-26 20:15:30 +00:00
public byte Status;
public byte Data1;
public byte Data2;
2019-10-26 20:45:33 +00:00
public override string ToString()
{
var statusStr = Status.ToString();
var data1Str = Data1.ToString();
var data2Str = Data2.ToString();
return statusStr + " " +data1Str + " " +data2Str;
}
2019-10-05 12:18:52 +00:00
}
public interface IMidiParser : IDisposable
{
2019-10-26 20:15:30 +00:00
event Action<MidiMessage> MidiMessageReceived;
2019-10-05 12:18:52 +00:00
}
public class MidiParser : IMidiParser
{
private enum Accept
{
StatusByte,
DataByte1,
DataByte2
}
private MidiMessage message_;
private Accept accept_ = Accept.StatusByte;
private readonly IPdReceiver pdReceiver_;
private readonly Action<byte[]> onDataReceived_;
public MidiParser(IPdReceiver pdReceiver)
{
pdReceiver_ = pdReceiver;
onDataReceived_ = (bytes) =>
{
foreach (var element in bytes)
{
if (element >= 128)
{
message_ = new MidiMessage {Status = element};
accept_ = Accept.DataByte1;
continue;
}
if (accept_ == Accept.DataByte1 && element <= 128)
{
message_.Data1 = element;
accept_ = Accept.DataByte2;
}
else if (accept_ == Accept.DataByte2 && element <= 128)
{
message_.Data2 = element;
Invoke();
accept_ = Accept.StatusByte;
}
}
};
pdReceiver_.DataReceived += onDataReceived_;
}
private void Invoke()
{
2019-10-26 20:15:30 +00:00
MidiMessageReceived?.Invoke(message_);
2019-10-05 12:18:52 +00:00
}
public void Dispose()
{
pdReceiver_.DataReceived -= onDataReceived_;
}
2019-10-26 20:15:30 +00:00
public event Action<MidiMessage> MidiMessageReceived;
2019-10-05 12:18:52 +00:00
}
}