soundvision/UnityProject/Assets/Scripts/PdConnection/MidiParser.cs
Chikashi Miyama d00d95859f refer #60
2019-10-05 14:18:52 +02:00

98 lines
No EOL
2.6 KiB
C#

using System;
using UnityEngine.Events;
namespace cylvester
{
[Serializable]
public class UnityControlEvent : UnityEvent<ControlMessage>
{}
public struct ControlMessage
{
public byte Channel;
public byte ControlNumber;
public byte ControlValue;
}
public interface IMidiParser : IDisposable
{
event Action<ControlMessage> ControlMessageReceived;
}
public class MidiParser : IMidiParser
{
private enum Accept
{
StatusByte,
DataByte1,
DataByte2
}
private struct MidiMessage
{
public byte Status;
public byte Data1;
public byte Data2;
}
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()
{
if (176 <= message_.Status || message_.Status <= 191)
{
var controlMessage = new ControlMessage
{
Channel = (byte) (message_.Status - 176),
ControlNumber = message_.Data1,
ControlValue = message_.Data2
};
ControlMessageReceived?.Invoke(controlMessage);
}
}
public void Dispose()
{
pdReceiver_.DataReceived -= onDataReceived_;
}
public event Action<ControlMessage> ControlMessageReceived;
}
}