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

Improvements, fix phase, fix default values, add reset impulse, add AudioMultiply, remove TestAudio #65

Merged
merged 3 commits into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 3 additions & 14 deletions ProjectObsidian/ProtoFlux/Audio/AudioAdder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ protected override void ProxyRemoved(AudioAdderProxy proxy, FrooxEngineContext c
proxy.Slot.ActiveChanged -= _activeChangedHandler.Read(context);
_enabledChangedHandler.Clear(context);
_activeChangedHandler.Clear(context);
proxy.Active = false;
}
}

Expand All @@ -133,20 +134,8 @@ public void Changed(FrooxEngineContext context)
{
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);
}
proxy.AudioInput = AudioInput.Evaluate(context);
proxy.AudioInput2 = AudioInput2.Evaluate(context);
}

protected override void ComputeOutputs(FrooxEngineContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,65 +3,59 @@
using ProtoFlux.Runtimes.Execution;
using FrooxEngine.ProtoFlux;
using FrooxEngine;
using Elements.Assets;
using Elements.Core;

namespace ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Audio
{
public class TestAudioProxy : ProtoFluxEngineProxy
public class AudioMultiplyProxy : ProtoFluxEngineProxy, IAudioSource
{
private AudioOutput _output;
private SineWaveClip _clip;
private AudioClipPlayer _player;
public readonly FieldDrive<float> FreqDrive;
public readonly FieldDrive<float> AmpDrive;
public bool Active
{
get { return _output.Enabled; }
set { _output.Enabled = value; }
}
public bool IsValid => _clip.FilterWorldElement() != null && FreqDrive.Target != null && FreqDrive.IsLinkValid && AmpDrive.Target != null && AmpDrive.IsLinkValid;
public float Frequency
{
get { return FreqDrive.Target.Value; }
set { FreqDrive.Target.Value = value; }
}
public float Amplitude
{
get { return AmpDrive.Target.Value; }
set { AmpDrive.Target.Value = value; }
}
protected override void OnAttach()
public IAudioSource AudioInput;

public float Value;

public bool Active;

public bool IsActive => Active;

public int ChannelCount => 1;

public void Read<S>(Span<S> buffer) where S : unmanaged, IAudioSample<S>
{
_output = Slot.AttachComponent<AudioOutput>();
_clip = Slot.AttachComponent<SineWaveClip>();
_player = Slot.AttachComponent<AudioClipPlayer>();
_player.Play();
_player.Loop = true;
_player.Clip.Target = _clip;
_output.Source.Target = _player;
FreqDrive.Target = _clip.Frequency;
FreqDrive.Target.Value = 440f;
AmpDrive.Target = _clip.Amplitude;
AmpDrive.Target.Value = 1f;
Span<S> newBuffer = stackalloc S[buffer.Length];
newBuffer = buffer;
if (AudioInput != null)
{
AudioInput.Read(newBuffer);
}
else
{
newBuffer.Fill(default);
}
for (int i = 0; i < buffer.Length; i++)
{
newBuffer[i] = newBuffer[i].Multiply(Value);
}
}
}
[NodeCategory("Obsidian/Audio")]
public class TestAudio : ProxyVoidNode<FrooxEngineContext, TestAudioProxy>, IExecutionChangeListener<FrooxEngineContext>
public class AudioMultiply : ProxyVoidNode<FrooxEngineContext, AudioMultiplyProxy>, IExecutionChangeListener<FrooxEngineContext>
{
[ChangeListener]
[@DefaultValue(440f)]
public readonly ValueInput<float> Frequency;
public readonly ObjectInput<IAudioSource> AudioInput;

[ChangeListener]
[@DefaultValue(1f)]
public readonly ValueInput<float> Amplitude;
public readonly ValueInput<float> Value;

public readonly ObjectOutput<IAudioSource> AudioOutput;

private ObjectStore<Action<IChangeable>> _enabledChangedHandler;

private ObjectStore<SlotEvent> _activeChangedHandler;

public bool ValueListensToChanges { get; private set; }

private bool ShouldListen(TestAudioProxy proxy)
private bool ShouldListen(AudioMultiplyProxy proxy)
{
if (proxy.Enabled)
{
Expand All @@ -70,7 +64,7 @@ private bool ShouldListen(TestAudioProxy proxy)
return false;
}

protected override void ProxyAdded(TestAudioProxy proxy, FrooxEngineContext context)
protected override void ProxyAdded(AudioMultiplyProxy proxy, FrooxEngineContext context)
{
base.ProxyAdded(proxy, context);
NodeContextPath path = context.CaptureContextPath();
Expand All @@ -95,22 +89,24 @@ protected override void ProxyAdded(TestAudioProxy proxy, FrooxEngineContext cont
_enabledChangedHandler.Write(enabledHandler, context);
_activeChangedHandler.Write(activeHandler, context);
ValueListensToChanges = ShouldListen(proxy);
proxy.Active = ValueListensToChanges;
}

protected override void ProxyRemoved(TestAudioProxy proxy, FrooxEngineContext context, bool inUseByAnotherInstance)
protected override void ProxyRemoved(AudioMultiplyProxy 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);
proxy.Active = false;
}
}

protected void UpdateListenerState(FrooxEngineContext context)
{
TestAudioProxy proxy = GetProxy(context);
AudioMultiplyProxy proxy = GetProxy(context);
if (proxy != null)
{
bool shouldListen = ShouldListen(proxy);
Expand All @@ -125,25 +121,24 @@ protected void UpdateListenerState(FrooxEngineContext context)

public void Changed(FrooxEngineContext context)
{
TestAudioProxy proxy = GetProxy(context);
AudioMultiplyProxy proxy = GetProxy(context);
if (proxy == null)
{
return;
}
if (!proxy.IsValid)
{
return;
}
try
{
context.World.UpdateManager.NestCurrentlyUpdating(proxy);
proxy.Frequency = Frequency.Evaluate(context);
proxy.Amplitude = Amplitude.Evaluate(context);
}
finally
{
context.World.UpdateManager.PopCurrentlyUpdating(proxy);
}
proxy.AudioInput = AudioInput.Evaluate(context);
proxy.Value = Value.Evaluate(context);
}

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

public AudioMultiply()
{
AudioOutput = new ObjectOutput<IAudioSource>(this);
}
}
}
17 changes: 3 additions & 14 deletions ProjectObsidian/ProtoFlux/Audio/AudioSubtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ protected override void ProxyRemoved(AudioSubtractorProxy proxy, FrooxEngineCont
proxy.Slot.ActiveChanged -= _activeChangedHandler.Read(context);
_enabledChangedHandler.Clear(context);
_activeChangedHandler.Clear(context);
proxy.Active = false;
}
}

Expand All @@ -133,20 +134,8 @@ public void Changed(FrooxEngineContext context)
{
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);
}
proxy.AudioInput = AudioInput.Evaluate(context);
proxy.AudioInput2 = AudioInput2.Evaluate(context);
}

protected override void ComputeOutputs(FrooxEngineContext context)
Expand Down
58 changes: 29 additions & 29 deletions ProjectObsidian/ProtoFlux/Audio/SineGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class SineGeneratorProxy : ProtoFluxEngineProxy, IAudioSource

public float Phase;

private float time;
public float time;

private float[] tempBuffer;

Expand All @@ -29,22 +29,16 @@ public class SineGeneratorProxy : ProtoFluxEngineProxy, IAudioSource

public int ChannelCount => 1;

protected override void OnAwake()
{
base.OnAwake();
Frequency = 440f;
Amplitude = 1f;
Phase = 0f;
}

// TODO: Make this not advance time on each read
Xlinka marked this conversation as resolved.
Show resolved Hide resolved
// If two things are reading this generator, it advances twice as fast
public void Read<S>(Span<S> buffer) where S : unmanaged, IAudioSample<S>
{
tempBuffer = tempBuffer.EnsureSize(buffer.Length);
time %= MathX.PI * 2f + Phase;
time %= MathX.PI * 2f;
float advance = 1f / (float)base.Engine.AudioSystem.SampleRate * (MathX.PI * 2f) * (float)Frequency;
for (int i = 0; i < buffer.Length; i++)
{
tempBuffer[i] = MathX.Sin(time) * MathX.Clamp01(Amplitude);
tempBuffer[i] = MathX.Sin(time + Phase) * MathX.Clamp01(Amplitude);
time += advance;
}
double position = 0.0;
Expand All @@ -56,17 +50,22 @@ public void Read<S>(Span<S> buffer) where S : unmanaged, IAudioSample<S>
public class SineGenerator : ProxyVoidNode<FrooxEngineContext, SineGeneratorProxy>, IExecutionChangeListener<FrooxEngineContext>
{
[ChangeListener]
[@DefaultValue(440f)]
[DefaultValueAttribute(440f)]
public readonly ValueInput<float> Frequency;

[ChangeListener]
[@DefaultValue(1f)]
[DefaultValueAttribute(1f)]
public readonly ValueInput<float> Amplitude;

[ChangeListener]
[@DefaultValue(0f)]
[DefaultValueAttribute(0f)]
public readonly ValueInput<float> Phase;

[PossibleContinuations(new string[] { "OnReset" })]
public readonly Operation Reset;

public Continuation OnReset;

public readonly ObjectOutput<IAudioSource> AudioOutput;

private ObjectStore<Action<IChangeable>> _enabledChangedHandler;
Expand Down Expand Up @@ -120,6 +119,7 @@ protected override void ProxyRemoved(SineGeneratorProxy proxy, FrooxEngineContex
proxy.Slot.ActiveChanged -= _activeChangedHandler.Read(context);
_enabledChangedHandler.Clear(context);
_activeChangedHandler.Clear(context);
proxy.Active = false;
}
}

Expand All @@ -145,21 +145,9 @@ public void Changed(FrooxEngineContext context)
{
return;
}
if (!proxy.IsValid)
{
return;
}
try
{
context.World.UpdateManager.NestCurrentlyUpdating(proxy);
proxy.Frequency = Frequency.Evaluate(context);
proxy.Amplitude = Amplitude.Evaluate(context);
proxy.Phase = Phase.Evaluate(context);
}
finally
{
context.World.UpdateManager.PopCurrentlyUpdating(proxy);
}
proxy.Frequency = Frequency.Evaluate(context, 440f);
proxy.Amplitude = Amplitude.Evaluate(context, 1f);
proxy.Phase = Phase.Evaluate(context, 0f);
}

protected override void ComputeOutputs(FrooxEngineContext context)
Expand All @@ -168,9 +156,21 @@ protected override void ComputeOutputs(FrooxEngineContext context)
AudioOutput.Write(proxy, context);
}

private IOperation DoReset(FrooxEngineContext context)
{
SineGeneratorProxy proxy = GetProxy(context);
if (proxy == null)
{
return null;
}
proxy.time = 0f;
return OnReset.Target;
}

public SineGenerator()
{
AudioOutput = new ObjectOutput<IAudioSource>(this);
Reset = new Operation(this, 0);
}
}
}
Loading
Loading