using System; using System.Runtime.InteropServices.JavaScript; using System.Threading.Tasks; namespace Susurrus.WebAudio { /// /// The thin layer between C# and the browser's Web Audio API, mirroring Susurrus.WebAudio.js. /// public static partial class WebAudioInterop { private static Task loadTask; /// /// Must be awaited once, from the browser host's own startup code, before any other member of this class or of /// is used. JSHost.ImportAsync can't be awaited synchronously, since nothing can /// pump the browser's microtask queue while the single WASM thread is blocked on it. /// public static Task EnsureLoadedAsync() { return loadTask ??= JSHost.ImportAsync("susurrus-webaudio", "../Susurrus.WebAudio.js"); } [JSImport("isAvailable", "susurrus-webaudio")] public static partial bool IsAvailable(); [JSImport("newAudioContext", "susurrus-webaudio")] public static partial JSObject NewAudioContext(); [JSImport("create", "susurrus-webaudio")] public static partial JSObject Create(JSObject context, int voiceCount, bool limit); [JSImport("setLimiterEnabled", "susurrus-webaudio")] public static partial void SetLimiterEnabled(JSObject engine, bool enabled); [JSImport("isRunning", "susurrus-webaudio")] public static partial bool IsRunning(JSObject engine); [JSImport("destroy", "susurrus-webaudio")] public static partial void Destroy(JSObject engine, bool closeContext); [JSImport("decode", "susurrus-webaudio")] [return: JSMarshalAs>] public static partial Task Decode(JSObject engine, byte[] encoded); [JSImport("makeBuffer", "susurrus-webaudio")] public static partial JSObject MakeBuffer( JSObject engine, byte[] samples, int sampleRate, int channelCount, bool isFloat); [JSImport("getDuration", "susurrus-webaudio")] public static partial double GetDuration(JSObject buffer); [JSImport("getChannelCount", "susurrus-webaudio")] public static partial int GetChannelCount(JSObject buffer); [JSImport("play", "susurrus-webaudio")] public static partial void Play(JSObject engine, int slot, JSObject buffer, double volume, double pitch, double pan, bool loop, double loopStart, double loopEnd); [JSImport("streamStart", "susurrus-webaudio")] public static partial void StreamStart(JSObject engine, int slot, double volume, double pitch, double pan); [JSImport("streamQueue", "susurrus-webaudio")] public static partial void StreamQueue(JSObject engine, int slot, byte[] samples, int byteCount, int sampleRate, int channelCount, bool isFloat); [JSImport("streamQueued", "susurrus-webaudio")] public static partial int StreamQueued(JSObject engine, int slot); [JSImport("streamEnd", "susurrus-webaudio")] public static partial void StreamEnd(JSObject engine, int slot); [JSImport("stop", "susurrus-webaudio")] public static partial void Stop(JSObject engine, int slot); [JSImport("setVolume", "susurrus-webaudio")] public static partial void SetVolume(JSObject engine, int slot, double volume); [JSImport("setPitch", "susurrus-webaudio")] public static partial void SetPitch(JSObject engine, int slot, double pitch); [JSImport("setPan", "susurrus-webaudio")] public static partial void SetPan(JSObject engine, int slot, double pan); [JSImport("setPaused", "susurrus-webaudio")] public static partial void SetPaused(JSObject engine, int slot, bool paused); [JSImport("takeEnded", "susurrus-webaudio")] public static partial int TakeEnded(JSObject engine, int word); } }