| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| const AudioRecordingWorklet = ` |
| class AudioProcessingWorklet extends AudioWorkletProcessor { |
| |
| // send and clear buffer every 2048 samples, |
| // which at 16khz is about 8 times a second |
| buffer = new Int16Array(2048); |
| |
| // current write index |
| bufferWriteIndex = 0; |
| |
| constructor() { |
| super(); |
| this.hasAudio = false; |
| } |
| |
| /** |
| * @param inputs Float32Array[][] [input#][channel#][sample#] so to access first inputs 1st channel inputs[0][0] |
| * @param outputs Float32Array[][] |
| */ |
| process(inputs) { |
| if (inputs[0].length) { |
| const channel0 = inputs[0][0]; |
| this.processChunk(channel0); |
| } |
| return true; |
| } |
| |
| sendAndClearBuffer(){ |
| this.port.postMessage({ |
| event: "chunk", |
| data: { |
| int16arrayBuffer: this.buffer.slice(0, this.bufferWriteIndex).buffer, |
| }, |
| }); |
| this.bufferWriteIndex = 0; |
| } |
| |
| processChunk(float32Array) { |
| const l = float32Array.length; |
| |
| for (let i = 0; i < l; i++) { |
| // convert float32 -1 to 1 to int16 -32768 to 32767 |
| const int16Value = float32Array[i] * 32768; |
| this.buffer[this.bufferWriteIndex++] = int16Value; |
| if(this.bufferWriteIndex >= this.buffer.length) { |
| this.sendAndClearBuffer(); |
| } |
| } |
| |
| if(this.bufferWriteIndex >= this.buffer.length) { |
| this.sendAndClearBuffer(); |
| } |
| } |
| } |
| `; |
|
|
| export default AudioRecordingWorklet; |
|
|