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