我是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);
发布于 2021-09-07 20:05:20
如果您不太关心延迟,可以使用MediaRecorder接口从流输入源(如AudioContext.createMediaStreamSource返回的输入源)捕获原始音频数据。使用dataavailable事件或MediaRecorder.requestData方法将原始数据作为Blob进行访问。在GitHub上的samdutton/simpl中有一个相当简单的例子。(在StackOverflow here上也有相关的问答。)
更一般的情况是,如果您可以将想要分析的音频转换为AudioBuffer,则可以使用AudioBuffer.getChannelData方法提取与音频通道关联的原始PCM样本数据。
然而,如果你是在“实时”做这件事--也就是说,如果你试图处理实时输入的音频以进行“实时”回放或可视化--那么你可能会想看看the AudioWorklet API。具体地说,您需要创建一个AudioWorkletProcessor,作为process处理程序的一部分来检查各个样本。
例如,就像这样:
// 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线程”内执行,因此您必须跳过一些障碍来设置工作小程序并与主执行上下文进行通信。这可能超出了这里合理描述的范围,但是如果你搜索像"AudioWorkletProcessor","AudioWorkletNode“或者只是"AudioWorklet”这样的关键字,有大量的教程可以指导你完成这些步骤。Here's one example.
https://stackoverflow.com/questions/69055451
复制相似问题