AudioWorklet除了节点之外还返回处理过的数据,如何?

问题描述

我正在尝试使用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