| /** |
| * @class RecorderProcessor |
| * @extends AudioWorkletProcessor |
| * |
| * A simple recorder AudioWorkletProcessor. Returns the recorded buffer to the |
| * node when recording is finished. |
| */ |
| class RecorderProcessor extends AudioWorkletProcessor { |
| /** |
| * @param {*} options |
| * @param {number} options.duration A duration to record in seconds. |
| * @param {number} options.channelCount A channel count to record. |
| */ |
| constructor(options) { |
| super(); |
| this._createdAt = currentTime; |
| this._elapsed = 0; |
| this._recordDuration = options.duration || 1; |
| this._recordChannelCount = options.channelCount || 1; |
| this._recordBufferLength = sampleRate * this._recordDuration; |
| this._recordBuffer = []; |
| for (let i = 0; i < this._recordChannelCount; ++i) { |
| this._recordBuffer[i] = new Float32Array(this._recordBufferLength); |
| } |
| } |
| |
| process(inputs, outputs) { |
| if (this._recordBufferLength <= currentFrame) { |
| this.port.postMessage({ |
| type: 'recordfinished', |
| recordBuffer: this._recordBuffer |
| }); |
| this.port.close(); |
| return false; |
| } |
| |
| // Records the incoming data from |inputs| and also bypasses the data to |
| // |outputs|. |
| const input = inputs[0]; |
| const output = outputs[0]; |
| for (let channel = 0; channel < input.length; ++channel) { |
| const inputChannel = input[channel]; |
| const outputChannel = output[channel]; |
| outputChannel.set(inputChannel); |
| |
| const buffer = this._recordBuffer[channel]; |
| const capacity = buffer.length - currentFrame; |
| buffer.set(inputChannel.slice(0, capacity), currentFrame); |
| } |
| |
| return true; |
| } |
| } |
| |
| registerProcessor('recorder-processor', RecorderProcessor); |