From 4c2a5eaeede4a45f2faa7466c21ebd5e36c4fbe1 Mon Sep 17 00:00:00 2001 From: Nick Kastellanos Date: Sun, 22 May 2022 21:14:30 +0300 Subject: [PATCH] Wasm.Audio --- Wasm.Audio/Audio/AudioBuffer.cs | 50 +++ Wasm.Audio/Audio/AudioBufferSourceNode.cs | 38 ++ Wasm.Audio/Audio/AudioContext.cs | 47 +++ Wasm.Audio/Audio/AudioDestinationNode.cs | 30 ++ Wasm.Audio/Audio/AudioListener.cs | 84 +++++ Wasm.Audio/Audio/AudioNode.cs | 42 +++ Wasm.Audio/Audio/AudioParam.cs | 67 ++++ Wasm.Audio/Audio/AudioScheduledSourceNode.cs | 62 ++++ Wasm.Audio/Audio/BaseAudioContext.cs | 106 ++++++ Wasm.Audio/Audio/ContextState.cs | 11 + Wasm.Audio/Audio/GainNode.cs | 41 +++ Wasm.Audio/Audio/OscillatorNode.cs | 51 +++ Wasm.Audio/Audio/OscillatorType.cs | 13 + Wasm.Audio/Audio/StereoPannerNode.cs | 41 +++ Wasm.Audio/Wasm.Audio.csproj | 29 ++ Wasm.Audio/wwwroot/js/Audio.6.0.0.js | 356 +++++++++++++++++++ Wasm.sln | 6 + pack.bat | 2 + 18 files changed, 1076 insertions(+) create mode 100644 Wasm.Audio/Audio/AudioBuffer.cs create mode 100644 Wasm.Audio/Audio/AudioBufferSourceNode.cs create mode 100644 Wasm.Audio/Audio/AudioContext.cs create mode 100644 Wasm.Audio/Audio/AudioDestinationNode.cs create mode 100644 Wasm.Audio/Audio/AudioListener.cs create mode 100644 Wasm.Audio/Audio/AudioNode.cs create mode 100644 Wasm.Audio/Audio/AudioParam.cs create mode 100644 Wasm.Audio/Audio/AudioScheduledSourceNode.cs create mode 100644 Wasm.Audio/Audio/BaseAudioContext.cs create mode 100644 Wasm.Audio/Audio/ContextState.cs create mode 100644 Wasm.Audio/Audio/GainNode.cs create mode 100644 Wasm.Audio/Audio/OscillatorNode.cs create mode 100644 Wasm.Audio/Audio/OscillatorType.cs create mode 100644 Wasm.Audio/Audio/StereoPannerNode.cs create mode 100644 Wasm.Audio/Wasm.Audio.csproj create mode 100644 Wasm.Audio/wwwroot/js/Audio.6.0.0.js diff --git a/Wasm.Audio/Audio/AudioBuffer.cs b/Wasm.Audio/Audio/AudioBuffer.cs new file mode 100644 index 0000000..0ecb532 --- /dev/null +++ b/Wasm.Audio/Audio/AudioBuffer.cs @@ -0,0 +1,50 @@ +using System; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class AudioBuffer : JSObject + { + BaseAudioContext _context; + + internal AudioBuffer(int uid, BaseAudioContext context) : base(uid) + { + _context = context; + } + + public int SampleRate + { + get { return InvokeRet("nkAudioBuffer.GetSampleRate"); } + } + + public int Length + { + get { return InvokeRet("nkAudioBuffer.GetLength"); } + } + + public int NumberOfChannels + { + get { return InvokeRet("nkAudioBuffer.GetNumberOfChannels"); } + } + + public void CopyToChannel(float[] source, int channelNumber) + { + Invoke("nkAudioBuffer.CopyToChannel", channelNumber, source); + } + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + _context = null; + + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/Wasm.Audio/Audio/AudioBufferSourceNode.cs b/Wasm.Audio/Audio/AudioBufferSourceNode.cs new file mode 100644 index 0000000..7961a54 --- /dev/null +++ b/Wasm.Audio/Audio/AudioBufferSourceNode.cs @@ -0,0 +1,38 @@ +using System; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class AudioBufferSourceNode : AudioScheduledSourceNode + { + + internal AudioBufferSourceNode(int uid, BaseAudioContext context) : base(uid, context) + { + } + + public AudioBuffer Buffer + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioBufferSourceNode.SetBuffer", value.Uid); } + } + + public bool Loop + { + get { return InvokeRet("nkAudioBufferSourceNode.GetLoop"); } + set { Invoke("nkAudioBufferSourceNode.SetLoop", value ? 1 : 0); } + } + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/Wasm.Audio/Audio/AudioContext.cs b/Wasm.Audio/Audio/AudioContext.cs new file mode 100644 index 0000000..ad462e7 --- /dev/null +++ b/Wasm.Audio/Audio/AudioContext.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using Microsoft.JSInterop.WebAssembly; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class AudioContext : BaseAudioContext + { + public AudioContext() : base(Register()) + { + } + + + private static int Register() + { + WebAssemblyJSRuntime runtime = new WasmJSRuntime(); + int uid = runtime.InvokeUnmarshalled("nkAudioContext.Create"); + return uid; + } + + public void Close() + { + Invoke("nkAudioContext.Close"); + } + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + Close(); + + base.Dispose(disposing); + } + + internal sealed class WasmJSRuntime : WebAssemblyJSRuntime + { + } + + } +} diff --git a/Wasm.Audio/Audio/AudioDestinationNode.cs b/Wasm.Audio/Audio/AudioDestinationNode.cs new file mode 100644 index 0000000..86ca115 --- /dev/null +++ b/Wasm.Audio/Audio/AudioDestinationNode.cs @@ -0,0 +1,30 @@ +using System; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class AudioDestinationNode : AudioNode + { + internal AudioDestinationNode(int uid, BaseAudioContext context) : base(uid, context) + { + } + + public int MaxChannelCount + { + get { return InvokeRet("nkAudioDestinationNode.GetMaxChannelCount"); } + } + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + base.Dispose(disposing); + } + } +} diff --git a/Wasm.Audio/Audio/AudioListener.cs b/Wasm.Audio/Audio/AudioListener.cs new file mode 100644 index 0000000..e5b8692 --- /dev/null +++ b/Wasm.Audio/Audio/AudioListener.cs @@ -0,0 +1,84 @@ +using System; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class AudioListener : JSObject + { + BaseAudioContext _context; + + internal AudioListener(int uid, BaseAudioContext context) : base(uid) + { + _context = context; + } + + public float PositionX + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioListener.SetPositionX", value); } + } + + public float PositionY + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioListener.SetPositionY", value); } + } + + public float PositionZ + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioListener.SetPositionZ", value); } + } + + public float ForwardX + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioListener.SetForwardX", value); } + } + + public float ForwardY + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioListener.SetForwardY", value); } + } + + public float ForwardZ + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioListener.SetForwardZ", value); } + } + + public float UpX + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioListener.SetUpX", value); } + } + + public float UpY + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioListener.SetUpY", value); } + } + + public float UpZ + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioListener.SetUpZ", value); } + } + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + _context = null; + + base.Dispose(disposing); + } + } +} diff --git a/Wasm.Audio/Audio/AudioNode.cs b/Wasm.Audio/Audio/AudioNode.cs new file mode 100644 index 0000000..a580e04 --- /dev/null +++ b/Wasm.Audio/Audio/AudioNode.cs @@ -0,0 +1,42 @@ +using System; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class AudioNode : JSObject + { + BaseAudioContext _context; + + protected BaseAudioContext Context { get { return _context; } } + + internal AudioNode(int uid, BaseAudioContext context) : base(uid) + { + _context = context; + } + + public void Connect(AudioNode destination) + { + Invoke("nkAudioNode.Connect", destination.Uid); + } + + public void Disconnect(AudioNode destination) + { + Invoke("nkAudioNode.Disconnect", destination.Uid); + } + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + _context = null; + + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/Wasm.Audio/Audio/AudioParam.cs b/Wasm.Audio/Audio/AudioParam.cs new file mode 100644 index 0000000..2ea3b4b --- /dev/null +++ b/Wasm.Audio/Audio/AudioParam.cs @@ -0,0 +1,67 @@ +using System; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class AudioParam : JSObject + { + BaseAudioContext _context; + + internal AudioParam(int uid, BaseAudioContext context) : base(uid) + { + _context = context; + } + + public float Value + { + get { throw new NotImplementedException(); } + set { Invoke("nkAudioParam.SetValue", value); } + } + + public void SetValueAtTime(float value, float startTime) + { + Invoke("nkAudioParam.SetValueAtTime", value, startTime); + } + + public void LinearRampToValueAtTime(float value, float endTime) + { + Invoke("nkAudioParam.LinearRampToValueAtTime", value, endTime); + } + + public void ExponentialRampToValueAtTime(float value, float endTime) + { + Invoke("nkAudioParam.ExponentialRampToValueAtTime", value, endTime); + } + + public void SetTargetAtTime(float target, float startTime, float timeConstant) + { + Invoke("nkAudioParam.SetTargetAtTime", target, startTime, timeConstant); + } + + public void SetValueCurveAtTime(float[] values, float startTime, float duration) + { + Invoke("nkAudioParam.SetValueCurveAtTime", startTime, duration, values); + } + + public void CancelScheduledValues(float startTime) + { + Invoke("nkAudioParam.CancelScheduledValues", startTime); + } + + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + _context = null; + + base.Dispose(disposing); + } + } +} diff --git a/Wasm.Audio/Audio/AudioScheduledSourceNode.cs b/Wasm.Audio/Audio/AudioScheduledSourceNode.cs new file mode 100644 index 0000000..907862c --- /dev/null +++ b/Wasm.Audio/Audio/AudioScheduledSourceNode.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using Microsoft.JSInterop; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class AudioScheduledSourceNode : AudioNode + { + static Dictionary> _uidMap = new Dictionary>(); + + public event EventHandler OnEnded; + + + internal AudioScheduledSourceNode(int uid, BaseAudioContext context) : base(uid, context) + { + _uidMap.Add(Uid, new WeakReference(this)); + Invoke("nkAudioScheduledSourceNode.RegisterEvents"); + } + + [JSInvokable] + public static void JsAudioScheduledSourceNodeOnEnded(int uid) + { + if (!_uidMap.TryGetValue(uid, out var jsObjRef)) + return; + if (!_uidMap[uid].TryGetTarget(out var jsObj)) + return; + + AudioScheduledSourceNode bufferSource = (AudioScheduledSourceNode)jsObj; + + var handler = bufferSource.OnEnded; + if (handler != null) + handler(bufferSource, EventArgs.Empty); + } + + public void Start() + { + Invoke("nkAudioScheduledSourceNode.Start"); + } + + public void Stop() + { + Invoke("nkAudioScheduledSourceNode.Stop"); + } + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + Invoke("nkAudioScheduledSourceNode.UnregisterEvents"); + _uidMap.Remove(Uid); + + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/Wasm.Audio/Audio/BaseAudioContext.cs b/Wasm.Audio/Audio/BaseAudioContext.cs new file mode 100644 index 0000000..6e1eef4 --- /dev/null +++ b/Wasm.Audio/Audio/BaseAudioContext.cs @@ -0,0 +1,106 @@ +using System; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class BaseAudioContext : JSObject + { + AudioDestinationNode _destination; + AudioListener _listener; + + public BaseAudioContext(int uid) : base(uid) + { + } + + public int SampleRate + { + get + { + int sampleRate = InvokeRet("nkAudioBaseContext.GetSampleRate"); + return SampleRate; + } + } + + public AudioDestinationNode Destination + { + get + { + if (_destination == null) + { + int uid = InvokeRet("nkAudioBaseContext.GetDestination"); + _destination = new AudioDestinationNode(uid, this); + } + + return _destination; + } + } + + public AudioListener Listener + { + get + { + if (_listener == null) + { + int uid = InvokeRet("nkAudioBaseContext.GetListener"); + _listener = new AudioListener(uid, this); + } + + return _listener; + } + } + + public ContextState State + { + get + { + string str = InvokeRet("nkAudioBaseContext.GetState"); + return Enum.Parse(str, true); + } + set { Invoke("nkAudioBaseContext.SetState", value.ToString().ToLower()); } + } + + public AudioBuffer CreateBuffer(int numOfChannels, int length, int sampleRate) + { + int uid = InvokeRet("nkAudioBaseContext.CreateBuffer", numOfChannels, length, sampleRate); + return new AudioBuffer(uid, this); + } + + public AudioBufferSourceNode CreateBufferSource() + { + int uid = InvokeRet("nkAudioBaseContext.CreateBufferSource"); + return new AudioBufferSourceNode(uid, this); + } + + public OscillatorNode CreateOscillator() + { + int uid = InvokeRet("nkAudioBaseContext.CreateOscillator"); + return new OscillatorNode(uid, this); + } + + public GainNode CreateGain() + { + int uid = InvokeRet("nkAudioBaseContext.CreateGain"); + return new GainNode(uid, this); + } + + public StereoPannerNode CreateStereoPanner() + { + int uid = InvokeRet("nkAudioBaseContext.CreateStereoPanner"); + return new StereoPannerNode(uid, this); + } + + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + base.Dispose(disposing); + } + } +} diff --git a/Wasm.Audio/Audio/ContextState.cs b/Wasm.Audio/Audio/ContextState.cs new file mode 100644 index 0000000..d341cae --- /dev/null +++ b/Wasm.Audio/Audio/ContextState.cs @@ -0,0 +1,11 @@ +using System; + +namespace nkast.Wasm.Audio +{ + public enum ContextState + { + Suspended = 1, + Running = 2, + Closed = 3, + } +} diff --git a/Wasm.Audio/Audio/GainNode.cs b/Wasm.Audio/Audio/GainNode.cs new file mode 100644 index 0000000..6cde680 --- /dev/null +++ b/Wasm.Audio/Audio/GainNode.cs @@ -0,0 +1,41 @@ +using System; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class GainNode : AudioNode + { + AudioParam _gain; + + internal GainNode(int uid, BaseAudioContext context) : base(uid, context) + { + } + + public AudioParam Gain + { + get + { + if (_gain == null) + { + int uid = InvokeRet("nkAudioGainNode.GetGain"); + _gain = new AudioParam(uid, Context); + } + + return _gain; + } + } + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/Wasm.Audio/Audio/OscillatorNode.cs b/Wasm.Audio/Audio/OscillatorNode.cs new file mode 100644 index 0000000..39a551a --- /dev/null +++ b/Wasm.Audio/Audio/OscillatorNode.cs @@ -0,0 +1,51 @@ +using System; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class OscillatorNode : AudioScheduledSourceNode + { + AudioParam _frequency; + + internal OscillatorNode(int uid, BaseAudioContext context) : base(uid, context) + { + } + + public AudioParam Frequency + { + get + { + if (_frequency == null) + { + int uid = InvokeRet("nkAudioOscillatorNode.GetFrequency"); + _frequency = new AudioParam(uid, Context); + } + + return _frequency; + } + } + + public OscillatorType Type + { + get + { + string str = InvokeRet("nkAudioOscillatorNode.GetType"); + return Enum.Parse(str, true); + } + set { Invoke("nkCanvas2dContext.SetType", value.ToString().ToLower()); } + } + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/Wasm.Audio/Audio/OscillatorType.cs b/Wasm.Audio/Audio/OscillatorType.cs new file mode 100644 index 0000000..cb5df08 --- /dev/null +++ b/Wasm.Audio/Audio/OscillatorType.cs @@ -0,0 +1,13 @@ +using System; + +namespace nkast.Wasm.Audio +{ + public enum OscillatorType + { + Sine = 1, + Square = 2, + Sawtooth = 3, + Triangle = 4, + Custom = 5, + } +} diff --git a/Wasm.Audio/Audio/StereoPannerNode.cs b/Wasm.Audio/Audio/StereoPannerNode.cs new file mode 100644 index 0000000..bdca346 --- /dev/null +++ b/Wasm.Audio/Audio/StereoPannerNode.cs @@ -0,0 +1,41 @@ +using System; +using nkast.Wasm.Dom; + +namespace nkast.Wasm.Audio +{ + public class StereoPannerNode : AudioNode + { + AudioParam _pan; + + internal StereoPannerNode(int uid, BaseAudioContext context) : base(uid, context) + { + } + + public AudioParam Pan + { + get + { + if (_pan == null) + { + int uid = InvokeRet("nkAudioStereoPannerNode.GetPan"); + _pan = new AudioParam(uid, Context); + } + + return _pan; + } + } + + protected override void Dispose(bool disposing) + { + if (IsDisposed) + return; + + if (disposing) + { + + } + + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/Wasm.Audio/Wasm.Audio.csproj b/Wasm.Audio/Wasm.Audio.csproj new file mode 100644 index 0000000..2349550 --- /dev/null +++ b/Wasm.Audio/Wasm.Audio.csproj @@ -0,0 +1,29 @@ + + + + net6.0 + 3.0 + nkast.Wasm.Audio + nkast.Wasm.Audio + + + + nkast.Wasm.Audio + 6.0.0 + Nick Kastellanos + MIT + https://github.com/nkast/Wasm/ + + + + + + + + + + + + + + diff --git a/Wasm.Audio/wwwroot/js/Audio.6.0.0.js b/Wasm.Audio/wwwroot/js/Audio.6.0.0.js new file mode 100644 index 0000000..12c8064 --- /dev/null +++ b/Wasm.Audio/wwwroot/js/Audio.6.0.0.js @@ -0,0 +1,356 @@ +window.nkAudioContext = +{ + Create: function() + { + var ac = new AudioContext(); + return nkJSObject.RegisterObject(ac); + }, + + Close: function(uid,d) + { + var ac = nkJSObject.GetObject(uid); + ac.close(); + } +}; + +window.nkAudioBaseContext = +{ + GetSampleRate: function (uid, d) + { + var ac = nkJSObject.GetObject(uid); + var sr = ac.sampleRate; + return sr; + }, + GetDestination: function (uid, d) + { + var ac = nkJSObject.GetObject(uid); + var ds = ac.destination; + return nkJSObject.RegisterObject(ds); + }, + GetListener: function (uid, d) + { + var ac = nkJSObject.GetObject(uid); + var lr = ac.listener; + return nkJSObject.RegisterObject(lr); + }, + + GetState: function (uid) + { + var ac = nkJSObject.GetObject(uid); + return BINDING.js_to_mono_obj(ac.state); + }, + SetState: function (uid, d) + { + var ac = nkJSObject.GetObject(uid); + ac.state = Blazor.platform.readStringField(d, 0); + }, + + CreateBuffer: function (uid, d) + { + var ac = nkJSObject.GetObject(uid); + var nc = Blazor.platform.readInt32Field(d, 0); + var le = Blazor.platform.readInt32Field(d, 4); + var sr = Blazor.platform.readInt32Field(d, 8); + var ab = ac.createBuffer(nc, le, sr); + return nkJSObject.RegisterObject(ab); + }, + CreateBufferSource: function (uid, d) + { + var ac = nkJSObject.GetObject(uid); + var bs = ac.createBufferSource(); + return nkJSObject.RegisterObject(bs); + }, + CreateOscillator: function (uid, d) + { + var ac = nkJSObject.GetObject(uid); + var os = ac.createOscillator(); + return nkJSObject.RegisterObject(os); + }, + CreateGain: function (uid, d) + { + var ac = nkJSObject.GetObject(uid); + var gn = ac.createGain(); + return nkJSObject.RegisterObject(gn); + }, + CreateStereoPanner: function (uid, d) + { + var ac = nkJSObject.GetObject(uid); + var sp = ac.createStereoPanner(); + return nkJSObject.RegisterObject(sp); + } +}; + +window.nkAudioBuffer = +{ + CopyToChannel: function (uid, d) + { + var ab = nkJSObject.GetObject(uid); + var cn = Blazor.platform.readInt32Field(d, 0); + var arr = Blazor.platform.readInt32Field(d, 4); + + var arrPtr = Blazor.platform.getArrayEntryPtr(arr, 0, 4); + var arrLen = Blazor.platform.getArrayLength(arr); + var sr = new Float32Array(Module.HEAPU8.buffer, arrPtr, arrLen); + + ab.copyToChannel(sr, cn); + }, + GetSampleRate: function (uid, d) + { + var ab = nkJSObject.GetObject(uid); + var sr = ab.sampleRate; + return sr; + }, + GetLength: function (uid, d) + { + var ab = nkJSObject.GetObject(uid); + var ln = ab.length; + return ln; + }, + GetNumberOfChannels: function (uid, d) + { + var ab = nkJSObject.GetObject(uid); + var nc = ab.numberOfChannels; + return nc; + } +}; + +window.nkAudioListener = +{ + SetPositionX: function (uid, d) + { + var lr = nkJSObject.GetObject(uid); + var px = Blazor.platform.readInt32Field(d, 0); + lr.positionX = px; + }, + SetPositionY: function (uid, d) + { + var lr = nkJSObject.GetObject(uid); + var py = Blazor.platform.readInt32Field(d, 0); + lr.positionY = py; + }, + SetPositionZ: function (uid, d) + { + var lr = nkJSObject.GetObject(uid); + var pz = Blazor.platform.readInt32Field(d, 0); + lr.positionZ = pz; + }, + + SetForwardX: function (uid, d) + { + var lr = nkJSObject.GetObject(uid); + var fx = Blazor.platform.readInt32Field(d, 0); + lr.forwardX = fx; + }, + SetForwardY: function (uid, d) + { + var lr = nkJSObject.GetObject(uid); + var fy = Blazor.platform.readInt32Field(d, 0); + lr.forwardY = fy; + }, + SetForwardZ: function (uid, d) + { + var lr = nkJSObject.GetObject(uid); + var fz = Blazor.platform.readInt32Field(d, 0); + lr.forwardZ = fz; + }, + + SetUpX: function (uid, d) + { + var lr = nkJSObject.GetObject(uid); + var ux = Blazor.platform.readInt32Field(d, 0); + lr.upX = ux; + }, + SetUpY: function (uid, d) + { + var lr = nkJSObject.GetObject(uid); + var uy = Blazor.platform.readInt32Field(d, 0); + lr.upY = uy; + }, + SetUpZ: function (uid, d) + { + var lr = nkJSObject.GetObject(uid); + var uz = Blazor.platform.readInt32Field(d, 0); + lr.upZ = uz; + } +}; + +window.nkAudioBufferSourceNode = +{ + SetBuffer: function (uid, d) + { + var bs = nkJSObject.GetObject(uid); + var uid= Blazor.platform.readInt32Field(d, 0); + var ab = nkJSObject.GetObject(uid); + bs.buffer = ab; + }, + + GetLoop: function (uid, d) + { + var bs = nkJSObject.GetObject(uid); + return bs.loop; + }, + SetLoop: function (uid, d) + { + var bs = nkJSObject.GetObject(uid); + var lp = Blazor.platform.readInt32Field(d, 0); + bs.loop = lp !== 0; + } +}; + +window.nkAudioScheduledSourceNode = +{ + Start: function (uid, d) + { + var bs = nkJSObject.GetObject(uid); + bs.start(); + }, + Stop: function (uid, d) + { + var bs = nkJSObject.GetObject(uid); + bs.stop(); + }, + + RegisterEvents: function (uid) + { + var bs = nkJSObject.GetObject(uid); + + bs.onended = function(event) + { + DotNet.invokeMethod('nkast.Wasm.Audio', 'JsAudioScheduledSourceNodeOnEnded', uid); + }; + }, + UnregisterEvents: function (uid) + { + var bs = nkJSObject.GetObject(uid); + bs.onended = null; + } +}; + +window.nkAudioDestinationNode = +{ + GetMaxChannelCount: function (uid, d) + { + var gn = nkJSObject.GetObject(uid); + return gn.maxChannelCount; + } +}; + +window.nkAudioNode = +{ + Connect: function (uid, d) + { + var an = nkJSObject.GetObject(uid); + var uid= Blazor.platform.readInt32Field(d, 0); + var ds = nkJSObject.GetObject(uid); + an.connect(ds); + }, + Disconnect: function (uid, d) + { + var an = nkJSObject.GetObject(uid); + var uid = Blazor.platform.readInt32Field(d, 0); + var ds = nkJSObject.GetObject(uid); + an.disconnect(ds); + }, +}; + +window.nkAudioOscillatorNode = +{ + GetFrequency: function (uid, d) + { + var os = nkJSObject.GetObject(uid); + var ap = os.frequency; + return nkJSObject.RegisterObject(ap); + }, + + GetType: function (uid) + { + var os = nkJSObject.GetObject(uid); + return BINDING.js_to_mono_obj(os.type); + }, + SetType: function (uid, d) + { + var os = nkJSObject.GetObject(uid); + os.type = Blazor.platform.readStringField(d, 0); + } +}; + +window.nkAudioGainNode = +{ + GetGain: function (uid, d) + { + var gn = nkJSObject.GetObject(uid); + var ap = gn.gain; + return nkJSObject.RegisterObject(ap); + } +}; + +window.nkAudioStereoPannerNode = +{ + GetPan: function (uid, d) + { + var sp = nkJSObject.GetObject(uid); + var ap = sp.pan; + return nkJSObject.RegisterObject(ap); + } +}; + +window.nkAudioParam = +{ + SetValue: function (uid, d) + { + var ap = nkJSObject.GetObject(uid); + var vl = Blazor.platform.readFloatField(d, 0); + ap.value = vl; + }, + + SetValueAtTime: function (uid, d) + { + var ap = nkJSObject.GetObject(uid); + var vl = Blazor.platform.readFloatField(d, 0); + var st = Blazor.platform.readFloatField(d, 4); + ap.setValueAtTime(vl, st); + }, + LinearRampToValueAtTime: function (uid, d) + { + var ap = nkJSObject.GetObject(uid); + var vl = Blazor.platform.readFloatField(d, 0); + var et = Blazor.platform.readFloatField(d, 4); + ap.linearRampToValueAtTime(vl, et); + }, + ExponentialRampToValueAtTime: function (uid, d) + { + var ap = nkJSObject.GetObject(uid); + var vl = Blazor.platform.readFloatField(d, 0); + var et = Blazor.platform.readFloatField(d, 4); + ap.exponentialRampToValueAtTime(vl, et); + }, + SetTargetAtTime: function (uid, d) + { + var ap = nkJSObject.GetObject(uid); + var tg = Blazor.platform.readFloatField(d, 0); + var st = Blazor.platform.readFloatField(d, 4); + var tc = Blazor.platform.readFloatField(d, 8); + ap.setTargetAtTime(tg, st, tc); + }, + SetValueCurveAtTime: function (uid, d) + { + var ap = nkJSObject.GetObject(uid); + var st = Blazor.platform.readFloatField(d, 0); + var dt = Blazor.platform.readFloatField(d, 4); + var arr = Blazor.platform.readInt32Field(d, 8); + + var arrPtr = Blazor.platform.getArrayEntryPtr(arr, 0, 4); + var arrLen = Blazor.platform.getArrayLength(arr); + var vs = new Float32Array(Module.HEAPU8.buffer, arrPtr, arrLen); + + ap.setValueCurveAtTime(vs, st, dt); + }, + + CancelScheduledValues: function (uid, d) + { + var ap = nkJSObject.GetObject(uid); + var st = Blazor.platform.readFloatField(d, 0); + ap.cancelScheduledValues(st); + } +}; + diff --git a/Wasm.sln b/Wasm.sln index 0c28129..dabd220 100644 --- a/Wasm.sln +++ b/Wasm.sln @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Canvas", "Wasm.Canvas\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.XHR", "Wasm.XHR\Wasm.XHR.csproj", "{0BE3D70C-A8E1-4EB6-8BEB-20E144534260}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wasm.Audio", "Wasm.Audio\Wasm.Audio.csproj", "{82123812-2A24-4683-A470-89DE71431D28}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +29,10 @@ Global {0BE3D70C-A8E1-4EB6-8BEB-20E144534260}.Debug|Any CPU.Build.0 = Debug|Any CPU {0BE3D70C-A8E1-4EB6-8BEB-20E144534260}.Release|Any CPU.ActiveCfg = Release|Any CPU {0BE3D70C-A8E1-4EB6-8BEB-20E144534260}.Release|Any CPU.Build.0 = Release|Any CPU + {82123812-2A24-4683-A470-89DE71431D28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {82123812-2A24-4683-A470-89DE71431D28}.Debug|Any CPU.Build.0 = Debug|Any CPU + {82123812-2A24-4683-A470-89DE71431D28}.Release|Any CPU.ActiveCfg = Release|Any CPU + {82123812-2A24-4683-A470-89DE71431D28}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/pack.bat b/pack.bat index 19dac07..7b0e224 100644 --- a/pack.bat +++ b/pack.bat @@ -1,7 +1,9 @@ dotnet pack Wasm.Dom\Wasm.Dom.csproj /p:Configuration=Release -o bin\publish dotnet pack Wasm.XHR\Wasm.XHR.csproj /p:Configuration=Release -o bin\publish dotnet pack Wasm.Canvas\Wasm.Canvas.csproj /p:Configuration=Release -o bin\publish +dotnet pack Wasm.Audio\Wasm.Audio.csproj /p:Configuration=Release -o bin\publish "C:\Program Files (x86)\nuget\nuget.exe" add bin\publish\nkast.Wasm.Dom.6.0.0.nupkg -Source "C:\Users\usename\.nuget\localPackages" "C:\Program Files (x86)\nuget\nuget.exe" add bin\publish\nkast.Wasm.XHR.6.0.0.nupkg -Source "C:\Users\usename\.nuget\localPackages" "C:\Program Files (x86)\nuget\nuget.exe" add bin\publish\nkast.Wasm.Canvas.6.0.0.nupkg -Source "C:\Users\usename\.nuget\localPackages" +"C:\Program Files (x86)\nuget\nuget.exe" add bin\publish\nkast.Wasm.Audio.6.0.0.nupkg -Source "C:\Users\usename\.nuget\localPackages"