tav-media
Version:
Cross platform media editing framework
79 lines (71 loc) • 2.27 kB
JavaScript
export const movieAudioProcessorCode = `class MovieAudioProcessor extends AudioWorkletProcessor {
static get parameterDescriptors() {
return [
{ name: 'bitDepth', defaultValue: 16, minValue: 1, maxValue: 32 },
];
}
constructor() {
super();
this.bitDepth_ = 16;
this.paused = false;
this.inputIndexes = [];
this.port.onmessage = (e) => {
const { operation, index } = e.data;
if (operation === 'pause') {
this.paused = true;
} else if (operation === 'play') {
this.paused = false;
} else if (operation === 'connect') {
this.inputIndexes.push(index);
} else if (operation === 'disconnect') {
this.inputIndexes.splice(this.inputIndexes.indexOf(index), 1);
}
}
}
handleMessage() {
this.port.postMessage('received');
}
process(inputs, outputs, parameters) {
if (this.paused) return true;
if (inputs.length === 0) {
return true;
}
const { bitDepth } = parameters;
const factor = 2 ** (bitDepth - 1);
const range = 25000;
const outBuffers = [];
const outDataList = {};
for (const inputIndex of this.inputIndexes) {
const input = inputs[inputIndex];
if (!input || input.length === 0) {
continue;
};
const sampleCount = input[0].length;
const outData = [];
for (let channel = 0; channel < input.length; ++channel) {
for (let dataIndex = 0; dataIndex < input[channel].length; dataIndex++) {
let transformedValue = Math.floor(input[channel][dataIndex] * factor + 0.5);
if (transformedValue >= range ) {
transformedValue = range;
} else
if (transformedValue <= -range) {
transformedValue = -range;
}
outData[input.length * dataIndex + channel] = transformedValue;
}
}
const arrayBuffer = new Int16Array(outData);
outDataList[inputIndex] = {
bytes: arrayBuffer.buffer,
sampleCount,
channelCount: input.length,
};
outBuffers.push(arrayBuffer.buffer);
}
this.port.postMessage({
outDataList
}, outBuffers);
return true;
}
}
registerProcessor('movie-audio-processor', MovieAudioProcessor);`;