Expose public gesture timeline API
This commit is contained in:
parent
5e1463fcb9
commit
1bf220027d
9 changed files with 198 additions and 9 deletions
|
|
@ -133,4 +133,45 @@ public sealed class NativeFaustRuntimeTests
|
|||
Assert.Contains(stream.SnapshotProbes(), pair => pair.Key == "debug/level" && pair.Value >= 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NativeFaustCompiledPatchExposesPrimitiveControlSurfaceCatalogWhenToolchainIsAvailable()
|
||||
{
|
||||
const string script = """
|
||||
morphology name=oral length_cm=17 diameters=.6,.8,1.2,1.5,.9
|
||||
waveguide_path name=oral_path morphology=oral loss=.998
|
||||
source_port name=folds path=oral_path pressure=.7 tension=.55 opening=.45 noise=.05 impedance=.3
|
||||
radiation_load name=mouth path=oral_path aperture=.8 reflection=-.82 impedance=.28
|
||||
vocal_network name=voice paths=oral_path sources=folds radiation=mouth
|
||||
vocal network=voice freq=150 gain=.2 sustain=.05 decay=.04
|
||||
""";
|
||||
|
||||
using var compiler = new AquaSynthPatchCompiler();
|
||||
if (!compiler.TryCompileScript(new AquaSynthCompileIdentity("native_surface_smoke", "native_surface_smoke", script), out var patch, out var error))
|
||||
{
|
||||
if (error?.Contains("Faust toolchain not found", StringComparison.OrdinalIgnoreCase) == true ||
|
||||
error?.Contains("Faust DLL not found", StringComparison.OrdinalIgnoreCase) == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.Fail($"AquaSynth native Faust surface compile failed: {error}");
|
||||
}
|
||||
|
||||
using (patch)
|
||||
{
|
||||
Assert.Contains("/vocal/sources/0/pressure", patch!.ControlSurfaces.SurfacePaths);
|
||||
Assert.Contains("vocal/sources/0/pressure", patch.ControlPaths);
|
||||
|
||||
var timeline = patch.ControlSurfaces.CreateTimeline(includePatchSplines: false);
|
||||
timeline.SetFuturePoint("/vocal/sources/0/pressure", timeSeconds: .01f, normalizedValue: .9f, nowSeconds: 0);
|
||||
var controls = patch.ControlValuesAt(timeline, .01f);
|
||||
var samples = patch.Render(controls);
|
||||
|
||||
Assert.Contains("/vocal/sources/0/pressure", controls.Keys);
|
||||
Assert.DoesNotContain("/vocal/radiation/0/reflection", controls.Keys);
|
||||
Assert.True(samples.Length > 1024);
|
||||
Assert.Contains(samples, sample => MathF.Abs(sample) > 0.0001f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -374,6 +374,39 @@ public sealed class PatchScriptTests
|
|||
Assert.InRange(last.Value, .34f, .36f);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ControlSurfaceCatalogIsThePublicGestureAuthoringApi()
|
||||
{
|
||||
var patch = PatchScript.Parse("""
|
||||
morphology name=oral length_cm=17 diameters=.6,.8,1.2,1.6,.9
|
||||
waveguide_path name=oral_path morphology=oral loss=.998
|
||||
source_port name=folds path=oral_path pressure=.7 tension=.55 opening=.45 noise=.05 impedance=.3
|
||||
radiation_load name=mouth path=oral_path aperture=.8 reflection=-.82 impedance=.28
|
||||
vocal_network name=voice paths=oral_path sources=folds radiation=mouth
|
||||
vocal network=voice freq=150 gain=.2 sustain=.2
|
||||
""");
|
||||
|
||||
var catalog = ControlSurfaceCatalog.FromPatch(patch);
|
||||
Assert.Contains("/vocal/sources/0/pressure", catalog.SurfacePaths);
|
||||
Assert.Contains("/vocal/radiation/0/aperture", catalog.SurfacePaths);
|
||||
|
||||
var pressure = catalog.Surface("/vocal/sources/0/pressure");
|
||||
Assert.Equal("folds", pressure.Owner);
|
||||
Assert.Equal("pressure", pressure.Field);
|
||||
Assert.InRange(pressure.DefaultNormalized, .69f, .71f);
|
||||
|
||||
var timeline = catalog.CreateTimeline(includePatchSplines: false);
|
||||
timeline.SetFuturePoint("/vocal/sources/0/pressure", timeSeconds: .016f, normalizedValue: .9f, nowSeconds: .0f);
|
||||
timeline.SetFuturePoint("/vocal/radiation/0/aperture", timeSeconds: .016f, normalizedValue: .4f, nowSeconds: .0f);
|
||||
var controls = timeline.ControlValuesAt(.016f);
|
||||
|
||||
Assert.InRange(controls["/vocal/sources/0/pressure"], .89f, .91f);
|
||||
Assert.InRange(controls["/vocal/radiation/0/aperture"], .39f, .41f);
|
||||
Assert.Contains(controls, pair => pair.Key == "/vocal/sources/0/tension");
|
||||
Assert.Throws<KeyNotFoundException>(() =>
|
||||
timeline.SetFuturePoint("/vocal/nope", timeSeconds: .02f, normalizedValue: .5f, nowSeconds: .0f));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PrimitiveProbeTimelineReportsFlowBeforeAudioParity()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue