Skip to content

Commit

Permalink
Fixes a feedback loop of the plugin state after changing parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
azeno committed Nov 27, 2024
1 parent 2eff660 commit 8eb30f8
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 19 deletions.
2 changes: 1 addition & 1 deletion deployment/VL.Audio.VST.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/10/nuspec.xsd">
<metadata>
<id>VL.Audio.VST</id>
<version>0.0.8-alpha</version>
<version>0.0.9-alpha</version>
<title>VL.Audio.VST</title>
<authors>vvvv</authors>
<projectUrl>https://github.com/vvvv/VL.Audio.VST</projectUrl>
Expand Down
2 changes: 1 addition & 1 deletion src/EffectHost.UI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private void ShowEditor()

void SaveCurrentWindowBounds()
{
if (window is null || window.IsDisposed)
if (window is null || window.IsDisposed || boundsPin.Value is null)
return;

var position = window.DesktopLocation;
Expand Down
49 changes: 33 additions & 16 deletions src/EffectHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ internal partial class EffectHost : FactoryBasedVLNode, IVLNode, IComponentHandl
private readonly Pin<bool> applyPin;

private PluginState? state;
private bool stateIsBeingSet;
private RectangleF bounds;
private AudioPin audioInputPin, audioOutputPin;
private IObservable<IMidiMessage>? midiInput;
Expand All @@ -81,6 +82,7 @@ internal partial class EffectHost : FactoryBasedVLNode, IVLNode, IComponentHandl

private readonly ProcessSetup processSetup;
private readonly AudioOutput audioOutput;
private readonly StatePin statePin;

public EffectHost(NodeContext nodeContext, IVLNodeDescription nodeDescription, string modulePath, ClassInfo info) : base(nodeContext)
{
Expand Down Expand Up @@ -132,7 +134,7 @@ public EffectHost(NodeContext nodeContext, IVLNodeDescription nodeDescription, s

var i = 0; var o = 0;

Inputs[i] = new StatePin();
Inputs[i] = statePin = new StatePin();
i++;
Inputs[i++] = boundsPin = new Pin<IChannel<RectangleF>>();
Inputs[i++] = audioInputPin = new AudioPin();
Expand Down Expand Up @@ -195,10 +197,17 @@ public void Dispose()

private void SavePluginState()
{
var state = PluginState.From(plugProvider.ClassInfo.ID, component, controller);
var statePin = (StatePin)Inputs[0];
if (stateIsBeingSet)
return;

var channel = statePin.Value;
SaveToChannelOrPin(channel, StateInputPinName, state);
if (channel is null)
return;

// Acknowledge the new state, we don't want to trigger a SetState on the controller in the next update
var state = PluginState.From(plugProvider.ClassInfo.ID, component, controller);
if (Acknowledge(ref this.state, state))
SaveToChannelOrPin(channel, StateInputPinName, state);
}

private static bool Acknowledge<T>(ref T current, T value)
Expand All @@ -219,17 +228,25 @@ public void Update()
for (int i = 0; i < inputAudioSignals.Length; i++)
inputAudioSignals[i] = aduioInputSignals[i];

if (Acknowledge(ref state, ((StatePin)Inputs[0]).Value?.Value))
if (Acknowledge(ref state, statePin.Value?.Value))
{
if (state != null && state.Id == plugProvider.ClassInfo.ID)
stateIsBeingSet = true;
try
{
if (state.HasComponentData)
if (state != null && state.Id == plugProvider.ClassInfo.ID)
{
component.IgnoreNotImplementedException(c => c.setState(state.GetComponentStream()));
controller?.IgnoreNotImplementedException(c => c.setComponentState(state.GetComponentStream()));
if (state.HasComponentData)
{
component.IgnoreNotImplementedException(c => c.setState(state.GetComponentStream()));
controller?.IgnoreNotImplementedException(c => c.setComponentState(state.GetComponentStream()));
}
if (state.HasControllerData)
controller?.IgnoreNotImplementedException(c => c.setState(state.GetControllerStream()));
}
if (state.HasControllerData)
controller?.IgnoreNotImplementedException(c => c.setState(state.GetControllerStream()));
}
finally
{
stateIsBeingSet = false;
}
}

Expand Down Expand Up @@ -592,16 +609,16 @@ void IComponentHandler2.finishGroupEdit()
logger.LogTrace("Finishing group edit");
}

private void SaveToChannelOrPin<T>(IChannel<T>? channel, string pinName, T value)
private void SaveToChannelOrPin<T>(IChannel<T> channel, string pinName, T value)
{
// Only write changes to the channel. Avoids document marked as dirty on open.
if (channel != null && Equals(channel.Value, value))
if (Equals(channel.Value, value))
return;

if (channel is null || channel.IsSystemGenerated())
channel.Value = value;

if (channel.IsSystemGenerated())
SaveToPin(pinName, value);
else
channel.Value = value;
}

private void SaveToPin<T>(string pinName, T value)
Expand Down
14 changes: 13 additions & 1 deletion src/PluginState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,22 @@

namespace VL.Audio.VST;

public record PluginState(Guid Id, ImmutableArray<byte> Component, ImmutableArray<byte> Controller)
public sealed record PluginState(Guid Id, ImmutableArray<byte> Component, ImmutableArray<byte> Controller)
{
public static readonly PluginState Default = new PluginState(default, ImmutableArray<byte>.Empty, ImmutableArray<byte>.Empty);

public bool Equals(PluginState? other)
{
if (other is null)
return false;

return Id == other.Id
&& Component.SequenceEqual(other.Component)
&& Controller.SequenceEqual(other.Controller);
}

public override int GetHashCode() => Id.GetHashCode();

internal bool HasComponentData => Component.Length > 0;
internal bool HasControllerData => Controller.Length > 0;

Expand Down

0 comments on commit 8eb30f8

Please sign in to comment.