summaryrefslogtreecommitdiff
path: root/index.htm
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-11-20 06:46:36 +0100
committerMitya Selivanov <automainint@guattari.tech>2024-11-20 06:46:36 +0100
commitb1b1383304bfa981ce61beb5c6531d6160a75a6b (patch)
tree3a86ca7f6155bb4f94994a2144c19683d1f7db8b /index.htm
parent0a8c2f838fcbb219c54e9a313608f389d403548d (diff)
downloadreduced_system_layer-b1b1383304bfa981ce61beb5c6531d6160a75a6b.zip
Web audio ring buffer impl
Diffstat (limited to 'index.htm')
-rw-r--r--index.htm112
1 files changed, 90 insertions, 22 deletions
diff --git a/index.htm b/index.htm
index e2e9d55..6624c78 100644
--- a/index.htm
+++ b/index.htm
@@ -14,18 +14,37 @@
class Sound_Ring extends AudioWorkletProcessor {
constructor(options) {
super();
- this.state = options.processorOptions.state;
- }
- process(input, output, parameters) {
- // TODO
- let sample_rate = sampleRate;
- let num_channels = output[0].length;
- let num_samples = output[0][0].length;
- let max_num_frames = this.state.max_num_frames;
+ this.ring = options.processorOptions.ring;
- let position = this.state.program.instance.exports.js_sound_playback(num_samples);
+ this.position = 0;
+ this.max_num_frames = this.ring.byteLength / 4;
+ }
+ process(input, output, parameters) {
+ let num_channels = output[0].length;
+ let num_samples = output[0][0].length;
+ let num_frames = num_samples * num_channels;
+
+ let frames = new Float32Array(this.ring);
+
+ if (num_frames <= this.max_num_frames - this.position)
+ for (let j = 0; j < num_channels; ++j)
+ for (let i = 0; i < num_samples; ++i)
+ output[0][j][i] = frames[this.position + i * num_channels + j];
+ else {
+ let part_one = this.max_num_frames - this.position;
+ let part_two = num_frames - part_one;
+
+ for (let j = 0; j < num_channels; ++j) {
+ for (let i = 0; i < part_one; ++i)
+ output[0][j][i] = frames[this.position + i * num_channels + j];
+ for (let i = 0; i < part_two; ++i)
+ output[0][j][part_one + i] = frames[i * num_channels + j];
+ }
+ }
+
+ this.position = (this.position + num_frames) % this.max_num_frames;
return true;
}
}
@@ -165,13 +184,12 @@
let sound_context;
let sound_init;
let sound_node;
+ let sound_num_channels;
+ let sound_buffer_address;
+ let sound_max_num_frames;
- let sound_state = {
- program : null,
- memory : null,
- max_num_frames : 0,
- buffer_address : 0,
- };
+ let sound_shared_ring;
+ let sound_position = 0;
canvas = attrs.canvas;
context = canvas.getContext("2d");
@@ -191,21 +209,24 @@
await sound_context.audioWorklet.addModule(URL.createObjectURL(blob));
- sound_state.program = program;
- sound_state.memory = memory;
- sound_state.max_num_frames = program.instance.exports.js_max_num_audio_frames();
- sound_state.buffer_address = program.instance.exports.js_sound_buffer();
+ sound_num_channels = program.instance.exports.js_num_channels();
+ sound_max_num_frames = program.instance.exports.js_max_num_audio_frames();
+ sound_buffer_address = program.instance.exports.js_sound_buffer();
+
+ sound_shared_ring = new SharedArrayBuffer(sound_max_num_frames * 4);
sound_node = new AudioWorkletNode(
sound_context,
"Sound_Ring",
- { numberOfInputs : 0,
- outputChannelCount : [ program.instance.exports.js_num_channels() ],
- processorOptions : { state : sound_state }, }
+ { numberOfInputs : 0,
+ outputChannelCount : [ sound_num_channels ],
+ processorOptions : { ring : sound_shared_ring, }, }
);
sound_node.connect(sound_context.destination);
+ program.instance.exports.js_sound_sync();
+
sound_ready = true;
};
@@ -252,6 +273,53 @@
p_sleep_for : (time) => { sleep_duration += time; },
p_time : Date.now,
+ p_handle_audio_impl : (samples_elapsed) => {
+ let num_frames = samples_elapsed * sound_num_channels;
+
+ if (num_frames <= sound_max_num_frames - sound_position)
+ new Uint8Array(
+ sound_shared_ring.slice(
+ sound_position * 4,
+ sound_position * 4 + num_frames * 4
+ )
+ ).set(
+ memory.subarray(
+ sound_buffer_address + sound_position * 4,
+ sound_buffer_address + sound_position * 4 + num_frames * 4
+ )
+ );
+ else {
+ let part_one = sound_max_num_frames - sound_position;
+ let part_two = num_frames - part_one;
+
+ new Uint8Array(
+ sound_shared_ring.slice(
+ sound_position * 4,
+ sound_position * 4 + part_one * 4
+ )
+ ).set(
+ memory.subarray(
+ sound_buffer_address + sound_position * 4,
+ sound_buffer_address + sound_position * 4 + part_one * 4
+ )
+ );
+
+ new Uint8Array(
+ sound_shared_ring.slice(
+ 0,
+ part_two * 4
+ )
+ ).set(
+ memory.subarray(
+ sound_buffer_address,
+ sound_buffer_address + part_two * 4
+ )
+ );
+ }
+
+ sound_position = (sound_position + samples_elapsed * sound_num_channels) % sound_max_num_frames;
+ },
+
floor : Math.floor,
ceil : Math.ceil,
sqrt : Math.sqrt,