diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-11-20 06:46:36 +0100 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-11-20 06:46:36 +0100 |
commit | b1b1383304bfa981ce61beb5c6531d6160a75a6b (patch) | |
tree | 3a86ca7f6155bb4f94994a2144c19683d1f7db8b /index.htm | |
parent | 0a8c2f838fcbb219c54e9a313608f389d403548d (diff) | |
download | reduced_system_layer-b1b1383304bfa981ce61beb5c6531d6160a75a6b.zip |
Web audio ring buffer impl
Diffstat (limited to 'index.htm')
-rw-r--r-- | index.htm | 112 |
1 files changed, 90 insertions, 22 deletions
@@ -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, |