| Lift freeq's AV media plane out of sleek 90f8b89 nandi 19d ago | 1 | registerProcessor("CpalProcessor", class WasmProcessor extends AudioWorkletProcessor { |
| 2 | constructor(options) { |
| 3 | super(); |
| 4 | let [module, memory, handle] = options.processorOptions; |
| 5 | bindgen.initSync({ module, memory }); |
| 6 | this.processor = bindgen.WasmAudioProcessor.unpack(handle); |
| 7 | this.memory = memory; |
| 8 | this.wasm_memory = new Float32Array(memory.buffer); |
| 9 | } |
| 10 | |
| 11 | process(inputs, outputs) { |
| 12 | // Check if memory grew and update view |
| 13 | if (this.wasm_memory.buffer !== this.memory.buffer) { |
| 14 | this.wasm_memory = new Float32Array(this.memory.buffer); |
| 15 | } |
| 16 | |
| 17 | const channels = outputs[0]; |
| 18 | const channels_count = channels.length; |
| 19 | const frame_size = channels[0].length; |
| 20 | const interleaved_ptr = this.processor.process( |
| 21 | channels_count, |
| 22 | frame_size, |
| 23 | sampleRate, |
| 24 | currentTime |
| 25 | ); |
| 26 | |
| 27 | const interleaved_start = interleaved_ptr / 4; // Convert byte offset to f32 index |
| 28 | const interleaved = this.wasm_memory; |
| 29 | |
| 30 | const total_samples = frame_size * channels_count; |
| 31 | if (interleaved_start + total_samples > this.wasm_memory.length) { |
| 32 | console.error("CpalProcessor: Audio buffer out of bounds! Ptr:", interleaved_ptr, "Len:", total_samples); |
| 33 | return false; // Safely stop the node |
| 34 | } |
| 35 | |
| 36 | // Deinterleave: read strided from Wasm, write sequential to output |
| 37 | for (let ch = 0; ch < channels_count; ch++) { |
| 38 | const channel = channels[ch]; |
| 39 | let read_pos = interleaved_start + ch; |
| 40 | |
| 41 | for (let i = 0; i < frame_size; i++) { |
| 42 | channel[i] = interleaved[read_pos]; |
| 43 | read_pos += channels_count; |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | return true; |
| 48 | } |
| 49 | }); |