Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MIDI input device support, MIDI settings and add global refs to binding generator #49

Merged
merged 9 commits into from
Jul 20, 2024
10 changes: 7 additions & 3 deletions ProjectObsidian.SourceGenerators/BindingGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,15 @@ public OrderedCount(string countVariableName, string methodName, string methodRe
private readonly OrderedCount _outputCount = new("NodeOutputCount", "GetOutputInternal", "INodeOutput");
private readonly OrderedCount _impulseCount = new("NodeImpulseCount", "GetImpulseInternal", "ISyncRef");
private readonly OrderedCount _operationCount = new("NodeOperationCount", "GetOperationInternal", "INodeOperation");

private readonly OrderedCount _globalRefCount = new("NodeGlobalRefCount", "GetGlobalRefInternal", "ISyncRef");

private readonly OrderedCount _inputListCount = new("NodeInputListCount", "GetInputListInternal", "ISyncList");
private readonly OrderedCount _outputListCount = new("NodeOutputListCount", "GetOutputListInternal", "ISyncList");
private readonly OrderedCount _impulseListCount = new("NodeImpulseListCount", "GetImpulseListInternal", "ISyncList");
private readonly OrderedCount _operationListCount = new("NodeOperationListCount", "GetOperationListInternal", "ISyncList");

private IEnumerable<OrderedCount> _counts => new[]
{ _inputCount, _outputCount, _impulseCount, _operationCount,
{ _inputCount, _outputCount, _impulseCount, _operationCount, _globalRefCount,
_inputListCount, _outputListCount, _impulseListCount, _operationListCount };

private string CountOverride => string.Concat(_counts.Select(i => i.CountOverride));
Expand Down Expand Up @@ -224,7 +225,10 @@ public override void VisitFieldDeclaration(FieldDeclarationSyntax node)
UntypedFieldDetection(type, name, "Call", "global::FrooxEngine.SyncRef<global::FrooxEngine.ProtoFlux.ISyncNodeOperation>", _impulseCount);
UntypedFieldDetection(type, name, "Continuation", "global::FrooxEngine.SyncRef<global::FrooxEngine.ProtoFlux.INodeOperation>", _impulseCount);
UntypedFieldDetection(type, name, "AsyncResumption", "global::FrooxEngine.SyncRef<global::FrooxEngine.ProtoFlux.INodeOperation>", _impulseCount);


//global refs
TypedFieldDetection(type, name, "GlobalRef", "global::FrooxEngine.SyncRef<global::FrooxEngine.ProtoFlux.IGlobalValueProxy<{1}>>", _globalRefCount);

//operations
UntypedFieldDetection(type, name, "Operation", "global::FrooxEngine.ProtoFlux.SyncNodeOperation", _operationCount);

Expand Down
114 changes: 114 additions & 0 deletions ProjectObsidian/Components/Devices/MIDI_CC_Value.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using Elements.Core;
using FrooxEngine;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Commons.Music.Midi.RtMidi;
using CoreMidi;
using Commons.Music.Midi;
using Obsidian.Elements;

namespace Obsidian;

[Category(new string[] { "Obsidian/Devices" })]
public class MIDI_CC_Value : Component
{
public readonly SyncRef<MIDI_InputDevice> InputDevice;

public readonly Sync<bool> AutoMap;

public readonly Sync<int> Channel;

public readonly Sync<int> ControllerNumber;

public readonly Sync<MIDI_CC_Definition?> OverrideDefinition;

public readonly Sync<int> Value;

public readonly Sync<float> NormalizedValue;

private MIDI_InputDevice _device;

protected override void OnStart()
{
base.OnStart();
InputDevice.OnTargetChange += OnTargetChange;
if (InputDevice.Target != null)
{
_device = InputDevice.Target;
InputDevice.Target.Control += OnControl;
}
}

protected override void OnDispose()
{
base.OnDispose();
if (_device != null)
{
_device.Control -= OnControl;
_device = null;
}
}

private void OnControl(MIDI_InputDevice device, MIDI_CC_EventData eventData)
{
RunSynchronously(() =>
{
if (AutoMap.Value)
{
AutoMap.Value = false;
ControllerNumber.Value = eventData.controller;
Channel.Value = eventData.channel;
if (OverrideDefinition.Value.HasValue)
{
if (Enum.IsDefined(typeof(MIDI_CC_Definition), eventData.controller))
{
OverrideDefinition.Value = (MIDI_CC_Definition)Enum.ToObject(typeof(MIDI_CC_Definition), eventData.controller);
}
else
{
OverrideDefinition.Value = MIDI_CC_Definition.UNDEFINED;
}
}
}
if (Channel.Value == eventData.channel)
{
if (OverrideDefinition.Value.HasValue && OverrideDefinition.Value.Value != MIDI_CC_Definition.UNDEFINED)
{
if (eventData.controller == (int)OverrideDefinition.Value.Value)
{
Value.Value = eventData.value;
NormalizedValue.Value = eventData.value / 127f;
}
}
else
{
if (eventData.controller == ControllerNumber.Value)
{
Value.Value = eventData.value;
NormalizedValue.Value = eventData.value / 127f;
}
}
}
});
}

private void OnTargetChange(SyncRef<MIDI_InputDevice> syncRef)
{
if (syncRef.Target == null && _device != null)
{
_device.Control -= OnControl;
_device = null;
}
else if (syncRef.Target != null)
{
if (_device != null)
{
_device.Control -= OnControl;
}
_device = syncRef.Target;
_device.Control += OnControl;
}
}
}
Loading