我是web音频API的新手,我使用了一个演示,并设法将PC音频输入源的两个通道分开,并驱动双演示分析器视图。我已经意识到大多数功能通过自动处理整个音频数据流来工作,但我的问题是:
当我想要它(编程)并将其放在变量上时,我如何从立体声输入源的每个通道获得单个样本,然后在不同的时间另一个?
var input = audioContext.createMediaStreamSource(stream);
var options = {
numberOfOutputs : 2
}
var splitter = new ChannelSplitterNode(audioContext, options);
input.connect( splitter );
splitter.connect(analyser1, 0, 0);
splitter.connect(analyser2, 1, 0);
如果您不太关心延迟,MediaRecorder接口可以用于从流输入源(如AudioContext.createMediaStreamSource返回的源)捕获原始音频数据。使用数据可用事件或MediaRecorder。方法来访问作为Blob的原始数据。GitHub上的samdutton/simple有一个相当简单的例子。(在StackOverflow上也有一个相关的问题)
更一般地,如果你能得到你想要分析的音频到AudioBuffer, AudioBuffer。getChannelData方法可用于提取与音频通道相关的原始PCM样本数据。
然而,如果你在"实时"-也就是说,如果你试图处理实时输入音频为"live";播放或可视化-然后你可能会想看看AudioWorklet API。具体来说,您将需要创建一个AudioWorkletProcessor,它将检查单个示例作为流程处理程序的一部分。
。,像这样:
// For this example we'll compute the average level (PCM value) for the frames
// in the audio sample we're processing.
class ExampleAudioWorkletProcessor extends AudioWorkletProcessor {
process (inputs, outputs, parameters) {
// the running total
sum = 0
// grab samples from the first channel of the first input connected to this node
pcmData = inputs[0][0]
// process each individual sample (frame)
for (i = 0; i < pcmData.length; i++ ) {
sum += pcmData[i]
}
// write something to the log just to show it's working at all
console.log("AVG:", (sum / pcmData.length).toFixed(5))
// be sure to return `true` to keep the worklet running
return true
}
}
但这既不是防弹的也不是特别有效的代码。(值得注意的是,你并不想在这里使用console.log
。你可能要么(a)写一些东西到outputs
数组发送音频数据到链中的下一个AudioNode或(b)使用postMessage发送数据回主(非音频)线程。
注意,由于AudioWorkletProcessor是在"音频线程"中执行的。而不是主UI线程与其他代码一样,要设置worklet并与主执行上下文通信,您必须跳过一些障碍。这可能超出了这里合理描述的范围,但这里有一个来自MDN的完整示例,如果您搜索"audioworkletprocessor"、"audioworkletnode"等关键字,有大量教程可以指导您完成步骤。或者只是"audioworklet"。这里有一个例子。