Skip to content

Commit

Permalink
update record impl to record exact number of samples
Browse files Browse the repository at this point in the history
  • Loading branch information
terryzfeng committed Jul 6, 2024
1 parent 16b13fc commit c4df71c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 23 deletions.
40 changes: 20 additions & 20 deletions src/tests/playwright/pages/processors/recorder/recorder-main.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
import concat from '../../util/concat.js';

export default async (ctx, length) => {
console.assert(ctx instanceof AudioContext);
console.assert(typeof length === 'number' && length > 0);

const mutex = new Promise((resolve) =>
setTimeout(resolve, 1000 * length));
const maxSamps = length * ctx.sampleRate;

await ctx.audioWorklet.addModule('./processors/recorder/recorder-processor.js');

const recorder = new AudioWorkletNode(ctx, 'recorder');
const recorder = new AudioWorkletNode(ctx, 'recorder', {
processorOptions: {
maxSamps
}
});

const arrays = [];
let bufferResolve;
recorder.port.onmessage = (e) => {
!(e.data.channel in arrays) && (arrays[e.data.channel] = []);
arrays[e.data.channel].push(e.data.data);
if (e.data.message === 'RECORD_DONE') {
// Resolve bufferData to buffer
const bufferData = e.data.buffer;
const audioBuffer = new AudioBuffer({
length: maxSamps,
sampleRate: ctx.sampleRate,
numberOfChannels: bufferData.length
})
bufferData.forEach((array, i) => audioBuffer.copyToChannel(array, i));

bufferResolve(audioBuffer)
}
};

// eslint-disable-next-line no-async-promise-executor
const buffer = new Promise(async (resolve) => {
await mutex;
const res = [];
arrays.forEach((array, i) => res[i] = concat(array));

const buf = new AudioBuffer({
length: res[0].length,
sampleRate: ctx.sampleRate,
numberOfChannels: res.length,
});

res.forEach((array, i) => buf.copyToChannel(array, i));
resolve(buf);
bufferResolve = resolve;
});

return {recorder, buffer};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
const MAX_RENDER_QUANTUM = 128;

// bypass-processor.js
class RecorderProcessor extends AudioWorkletProcessor {
constructor() {
constructor(options) {
super();
this._pos = 0;
this._maxSamps = options.processorOptions.maxSamps;
this._recordingBuffer = new Array(this.numberOfChannels)
.fill(new Float32Array(this._maxSamps));
}

process(inputs, outputs) {
const input = inputs[0];
const output = outputs[0];

// how many samps to record
const advance = Math.min(MAX_RENDER_QUANTUM, this._maxSamps - this._pos);

for (let channel = 0; channel < input.length; channel++) {
// pass-through
output[channel].set(input[channel]);
this.port.postMessage({channel, data: input[channel]});
// record `advance` samps
this._recordingBuffer[channel].set(input[channel].subarray(0, advance), this._pos)
}

this._pos += advance;
if (this._pos >= this._maxSamps) {
this.port.postMessage({
message: 'RECORD_DONE',
buffer: this._recordingBuffer
})
}


return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/tests/playwright/pages/realtime-sine.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
helloSine.connect(recorder).connect(ctx.destination);

helloSine.start();
helloSine.stop(ctx.currentTime + 1);
// helloSine.stop(ctx.currentTime + 1);

const audioBuffer = await buffer;
const float32Buffer = audioBuffer.getChannelData(0);
Expand Down

0 comments on commit c4df71c

Please sign in to comment.