Skip to content

Commit

Permalink
Merge pull request #64 from Nytra/audioWork
Browse files Browse the repository at this point in the history
Add audio processing ProtoFlux Nodes, add ProxyVoidNode to binding generator, fill buffers with default samples if not active
  • Loading branch information
Xlinka authored Dec 27, 2024
2 parents f255108 + 2f59e43 commit dd4d164
Show file tree
Hide file tree
Showing 11 changed files with 809 additions and 1 deletion.
9 changes: 8 additions & 1 deletion ProjectObsidian.SourceGenerators/BindingGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ public OrderedCount(string countVariableName, string methodName, string methodRe
"AsyncActionNode",
"AsyncActionFlowNode",
"AsyncActionBreakableFlowNode",

"ProxyVoidNode"
};

private string UsingEnumerate =>
Expand Down Expand Up @@ -150,7 +152,7 @@ namespace {BindingPrefix}{_currentNameSpace};
{_genericTypesAttribute}
{_oldTypeNameAttribute}
[Category(new string[] {{""ProtoFlux/Runtimes/Execution/Nodes/{_category}""}})]
public partial class {_fullName} : global::FrooxEngine.ProtoFlux.Runtimes.Execution.{_baseType} {_constraints}
public partial class {_fullName} : global::{_baseTypeNamespace}{_baseType} {_constraints}
{{
{(string.IsNullOrEmpty(_debug) ? "" : "//")}{_debug}
{Declarations}
Expand Down Expand Up @@ -182,6 +184,7 @@ public override N Instantiate<N>()
private string _additionalName = "";
public string BaseName;
private string _baseType;
private string _baseTypeNamespace = "FrooxEngine.ProtoFlux.Runtimes.Execution.";
private string _fullBaseType;
private string _match;
private string _category;
Expand Down Expand Up @@ -307,6 +310,10 @@ public override void VisitClassDeclaration(ClassDeclarationSyntax node)
var baseTypeName = firstBaseType.Type.ToString();

_baseType = baseTypeName;
if (baseTypeName.Contains("ProxyVoidNode"))
{
_baseTypeNamespace = "FrooxEngine.FrooxEngine.ProtoFlux.";
}

if (!node.AttributeLists.Any())
{
Expand Down
1 change: 1 addition & 0 deletions ProjectObsidian/Components/Audio/BandPassFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public void Read<S>(Span<S> buffer) where S : unmanaged, IAudioSample<S>
{
if (!IsActive)
{
buffer.Fill(default(S));
return;
}

Expand Down
1 change: 1 addition & 0 deletions ProjectObsidian/Components/Audio/ButterworthFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public void Read<S>(Span<S> buffer) where S : unmanaged, IAudioSample<S>
{
if (!IsActive)
{
buffer.Fill(default(S));
return;
}

Expand Down
1 change: 1 addition & 0 deletions ProjectObsidian/Components/Audio/EMA_IIR_SmoothSignal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public void Read<S>(Span<S> buffer) where S : unmanaged, IAudioSample<S>
{
if (!IsActive)
{
buffer.Fill(default(S));
return;
}

Expand Down
2 changes: 2 additions & 0 deletions ProjectObsidian/Components/Audio/FrequencyModulator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ public void Read<S>(Span<S> buffer) where S : unmanaged, IAudioSample<S>
{
if (!IsActive)
{
buffer.Fill(default(S));
return;
}

int channelCount = ChannelCount;
if (channelCount == 0)
{
buffer.Fill(default(S));
return;
}

Expand Down
1 change: 1 addition & 0 deletions ProjectObsidian/ProjectObsidian.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
<PackageReference Include="managed-midi" Version="1.10.1" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3"> </PackageReference>
<PackageReference Include="System.Memory" Version="4.6.0" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.6.0" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(ResonitePath)Libraries" />
Expand Down
163 changes: 163 additions & 0 deletions ProjectObsidian/ProtoFlux/Audio/AudioAdder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
using System;
using ProtoFlux.Core;
using ProtoFlux.Runtimes.Execution;
using FrooxEngine.ProtoFlux;
using FrooxEngine;
using Elements.Assets;

namespace ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Audio
{
public class AudioAdderProxy : ProtoFluxEngineProxy, IAudioSource
{
public IAudioSource AudioInput;

public IAudioSource AudioInput2;

public bool Active;

public bool IsActive => Active;

public int ChannelCount => 1;

public void Read<S>(Span<S> buffer) where S : unmanaged, IAudioSample<S>
{
Span<S> newBuffer = stackalloc S[buffer.Length];
newBuffer = buffer;
Span<S> newBuffer2 = stackalloc S[buffer.Length];
if (AudioInput != null)
{
AudioInput.Read(newBuffer);
}
else
{
newBuffer.Fill(default);
}
if (AudioInput2 != null)
{
AudioInput2.Read(newBuffer2);
}
else
{
newBuffer2.Fill(default);
}
for (int i = 0; i < buffer.Length; i++)
{
newBuffer[i] = newBuffer[i].Add(newBuffer2[i]);
}
}
}
[NodeCategory("Obsidian/Audio")]
public class AudioAdder : ProxyVoidNode<FrooxEngineContext, AudioAdderProxy>, IExecutionChangeListener<FrooxEngineContext>
{
[ChangeListener]
public readonly ObjectInput<IAudioSource> AudioInput;

[ChangeListener]
public readonly ObjectInput<IAudioSource> AudioInput2;

public readonly ObjectOutput<IAudioSource> AudioOutput;

private ObjectStore<Action<IChangeable>> _enabledChangedHandler;

private ObjectStore<SlotEvent> _activeChangedHandler;

public bool ValueListensToChanges { get; private set; }

private bool ShouldListen(AudioAdderProxy proxy)
{
if (proxy.Enabled)
{
return proxy.Slot.IsActive;
}
return false;
}

protected override void ProxyAdded(AudioAdderProxy proxy, FrooxEngineContext context)
{
base.ProxyAdded(proxy, context);
NodeContextPath path = context.CaptureContextPath();
ProtoFluxNodeGroup group = context.Group;
context.GetEventDispatcher(out var dispatcher);
Action<IChangeable> enabledHandler = delegate
{
dispatcher.ScheduleEvent(path, delegate (FrooxEngineContext c)
{
UpdateListenerState(c);
});
};
SlotEvent activeHandler = delegate
{
dispatcher.ScheduleEvent(path, delegate (FrooxEngineContext c)
{
UpdateListenerState(c);
});
};
proxy.EnabledField.Changed += enabledHandler;
proxy.Slot.ActiveChanged += activeHandler;
_enabledChangedHandler.Write(enabledHandler, context);
_activeChangedHandler.Write(activeHandler, context);
ValueListensToChanges = ShouldListen(proxy);
proxy.Active = ValueListensToChanges;
}

protected override void ProxyRemoved(AudioAdderProxy proxy, FrooxEngineContext context, bool inUseByAnotherInstance)
{
if (!inUseByAnotherInstance)
{
proxy.EnabledField.Changed -= _enabledChangedHandler.Read(context);
proxy.Slot.ActiveChanged -= _activeChangedHandler.Read(context);
_enabledChangedHandler.Clear(context);
_activeChangedHandler.Clear(context);
}
}

protected void UpdateListenerState(FrooxEngineContext context)
{
AudioAdderProxy proxy = GetProxy(context);
if (proxy != null)
{
bool shouldListen = ShouldListen(proxy);
if (shouldListen != ValueListensToChanges)
{
ValueListensToChanges = shouldListen;
context.Group.MarkChangeTrackingDirty();
proxy.Active = shouldListen;
}
}
}

public void Changed(FrooxEngineContext context)
{
AudioAdderProxy proxy = GetProxy(context);
if (proxy == null)
{
return;
}
if (!proxy.IsValid)
{
return;
}
try
{
context.World.UpdateManager.NestCurrentlyUpdating(proxy);
proxy.AudioInput = AudioInput.Evaluate(context);
proxy.AudioInput2 = AudioInput2.Evaluate(context);
}
finally
{
context.World.UpdateManager.PopCurrentlyUpdating(proxy);
}
}

protected override void ComputeOutputs(FrooxEngineContext context)
{
AudioAdderProxy proxy = GetProxy(context);
AudioOutput.Write(proxy, context);
}

public AudioAdder()
{
AudioOutput = new ObjectOutput<IAudioSource>(this);
}
}
}
Loading

0 comments on commit dd4d164

Please sign in to comment.