Faust SetControls: write control zones without allocating
Marshal.Copy([value], ...) allocated a float[1] per control and the IReadOnlyDictionary foreach boxed an enumerator per call. Write the float bits straight to the zone and use Dictionary's struct enumerator when the caller passes one. 10000-block smoke on a 2-control patch: 120 B/block -> 0. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
3b43b7bd72
commit
aa45571b3a
1 changed files with 21 additions and 5 deletions
|
|
@ -840,16 +840,32 @@ internal sealed class FaustNativeToolchain : IDisposable
|
|||
|
||||
public void SetControls(IntPtr dsp, IReadOnlyDictionary<string, float> controls, IReadOnlyDictionary<string, IntPtr> map)
|
||||
{
|
||||
foreach (var (path, value) in controls)
|
||||
// Dictionary's struct enumerator avoids boxing one through the interface on every audio block.
|
||||
if (controls is Dictionary<string, float> dictionary)
|
||||
{
|
||||
if (!map.TryGetValue(path, out var zone) &&
|
||||
!map.TryGetValue(path.TrimStart('/'), out zone))
|
||||
foreach (var (path, value) in dictionary)
|
||||
{
|
||||
throw new ArgumentException($"Faust control `{path}` was not exported by the compiled patch.", nameof(controls));
|
||||
WriteControl(map, path, value);
|
||||
}
|
||||
|
||||
Marshal.Copy([value], 0, zone, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var (path, value) in controls)
|
||||
{
|
||||
WriteControl(map, path, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteControl(IReadOnlyDictionary<string, IntPtr> map, string path, float value)
|
||||
{
|
||||
if (!map.TryGetValue(path, out var zone) &&
|
||||
!map.TryGetValue(path.TrimStart('/'), out zone))
|
||||
{
|
||||
throw new ArgumentException($"Faust control `{path}` was not exported by the compiled patch.", "controls");
|
||||
}
|
||||
|
||||
Marshal.WriteInt32(zone, BitConverter.SingleToInt32Bits(value));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
|||
Loading…
Reference in a new issue