sysaudio: webaudio: Add intitial implementation and boilerplate
This commit is contained in:
parent
a3b9bb7469
commit
21f3efe78e
2 changed files with 89 additions and 1 deletions
88
sysaudio/src/webaudio.zig
Normal file
88
sysaudio/src/webaudio.zig
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
const std = @import("std");
|
||||
const Mode = @import("main.zig").Mode;
|
||||
const DeviceDescriptor = @import("main.zig").DeviceDescriptor;
|
||||
const js = @import("sysjs");
|
||||
|
||||
const Audio = @This();
|
||||
|
||||
pub const Device = struct {
|
||||
context: js.Object,
|
||||
|
||||
pub fn deinit(device: Device) void {
|
||||
device.context.deinit();
|
||||
}
|
||||
};
|
||||
|
||||
pub const DeviceIterator = struct {
|
||||
ctx: *Audio,
|
||||
mode: Mode,
|
||||
|
||||
pub fn next(_: DeviceIterator) IteratorError!?DeviceDescriptor {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
pub const IteratorError = error{};
|
||||
|
||||
pub const Error = error{
|
||||
AudioUnsupported,
|
||||
};
|
||||
|
||||
context_constructor: js.Function,
|
||||
|
||||
pub fn init() Error!Audio {
|
||||
const context = js.global().get("AudioContext");
|
||||
if (context.is(.undef))
|
||||
return error.AudioUnsupported;
|
||||
|
||||
return Audio{ .context_constructor = context.view(.func) };
|
||||
}
|
||||
|
||||
pub fn deinit(audio: Audio) void {
|
||||
audio.context_constructor.deinit();
|
||||
}
|
||||
|
||||
pub fn waitEvents(_: Audio) void {}
|
||||
|
||||
pub fn requestDevice(audio: Audio, config: DeviceDescriptor) Error!Device {
|
||||
const context = audio.context_constructor.construct(&.{});
|
||||
_ = context.call("suspend", &.{});
|
||||
|
||||
const input_channels = if (config.mode.? == .input) js.createNumber(@intToFloat(f64, config.channels.?)) else js.createUndefined();
|
||||
const output_channels = if (config.mode.? == .output) js.createNumber(@intToFloat(f64, config.channels.?)) else js.createUndefined();
|
||||
|
||||
const node = context.call("createScriptProcessor", &.{ js.createNumber(4096), input_channels, output_channels }).view(.object);
|
||||
defer node.deinit();
|
||||
|
||||
context.set("node", node.toValue());
|
||||
|
||||
{
|
||||
const audio_process_event = js.createFunction(audioProcessEvent);
|
||||
defer audio_process_event.deinit();
|
||||
node.set("onaudioprocess", audio_process_event.toValue());
|
||||
}
|
||||
|
||||
{
|
||||
const destination = context.get("destination").view(.object);
|
||||
defer destination.deinit();
|
||||
_ = node.call("connect", &.{destination.toValue()});
|
||||
}
|
||||
|
||||
return Device{
|
||||
.context = context,
|
||||
};
|
||||
}
|
||||
|
||||
fn audioProcessEvent(args: js.Object, _: usize) js.Value {
|
||||
const audio_event = args.getIndex(0).view(.object);
|
||||
_ = audio_event;
|
||||
return js.createUndefined();
|
||||
}
|
||||
|
||||
pub fn outputDeviceIterator(audio: Audio) DeviceIterator {
|
||||
return .{ .audio = audio, .mode = .output };
|
||||
}
|
||||
|
||||
pub fn inputDeviceIterator(audio: Audio) DeviceIterator {
|
||||
return .{ .audio = audio, .mode = .input };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue