问题描述
我正在尝试使用AudioWorklet返回缓冲区。 这就是我到目前为止所拥有的。
服务中的方法:
private record(stream: MediaStream): void {
const audioContext = new AudioContext({sampleRate: 16000});
audioContext.audioWorklet.addModule('downsample-processor.js').then(() => {
const src = this.audioContext.createmediastreamsource(stream);
const node = new AudioWorkletNode(this.audioContext,'downsample-processor');
src.connect(node).connect(audioContext.destination);
// do something w. outputData.buffer from the audio worklet (see processor below)
}).catch((err) => console.error(err));
}
down-sample-processor.js:
class DownsampleProcessor extends AudioWorkletProcessor {
constructor() {
super();
}
process(inputs,outputs,parameters) {
const input = inputs[0];
const sampleRate = 16000;
const bufferSize = 8192;
const ratio = input.sampleRate / sampleRate;
const length = Math.floor(bufferSize / ratio);
const inputData = input[0]; // float 32 array
let outputData = new Int16Array(length); // int 16 array
let curSample,newSample;
for (let i = 0; i < length; i++) {
curSample = Math.floor(i * ratio);
newSample = Math.min(inputData[curSample] * 32768,32767);
outputData[i] = Math.floor(newSample);
}
// HOW to return ouputData.buffer?
return true;
}
}
registerProcessor('downsample-processor',DownSampleProcessor);
那么我如何将ouputData.buffer从处理器返回到服务中的方法?
谢谢。
解决方法
outputs
的{{1}}参数是process
输出的位置。因此,将AudioWorkletNode
复制到outputData
。
我还看到,当您计算newSample时,会将值最多限制为32767。这很好。但是您还需要将值限制在-32768以下。不确定为什么要夹紧。 WebAudio可与浮点数一起使用,因此除非您确实希望减少位数,否则不需要这样做。只需将所有内容都保留为浮点数,并进行钳位并转换为16位精度即可。
此外,您的计算似乎假设您在outputs[0][0]
中将有length
个样本。错了inputData
的长度恰好是128。您必须做更多的工作才能进行下采样工作。还要注意,WebAudio仅在一个sampleRate上起作用。如果您希望WebAudio像采样率是16000一样处理工作集的输出,那么您会感到失望。您可能应该通过MessagePort或SharedArrayBuffer将降采样的音频发送到其他地方。 (这实际上可能是另一个AudioContext,其sampleRate设置为16000。)
input[0]
也不存在。您想从inputs.sampleRate
获得sampleRate
。