gpt4 book ai didi

javascript - 如何创建并正确调度AudioBufferSource节点?

转载 作者:行者123 更新时间:2023-12-03 07:24:49 24 4
gpt4 key购买 nike

我正在尝试使用 Javascript 开发一个节拍器。我按照 this article 中的说明进行操作我创建了一个调度程序,它经常被调用并调度“ticks”,这些“ticks”存在于一个名为 ticksInQueue 的数组中。我希望“滴答声”是节拍器的实际声音,而不是振荡器生成的频率。

振荡器

function scheduler() {
while (nextTickTime < audioContext.currentTime + lookahead) { // while there are notes that will need to play before the next interval
ticksInQueue.push({tick: currentTick, time: nextTickTime}); // push the note on the queue, even if we're not playing.
//create an oscillator
var osc = audioContext.createOscillator();
osc.connect(audioContext.destination);
osc.frequency.value = 440.0;
osc.start(nextTickTime);
osc.stop(nextTickTime + 0.1);
nextTickTime += 60.0 / tempo; // Add beat length to last beat time
currentTick = currentTick + 1; // Advance the beat number, wrap to zero
if (currentTick === 5) {
currentTick = 0;
}
}
}

已关注 this video tutorial关于如何创建 AudioBufferSource 节点,我编写了这段代码,该代码在加载窗口时执行。

audioContext = new AudioContext();
request = new XMLHttpRequest();
request.open("GET", "tick.mp3", true);
request.responseType = "arraybuffer";
function onDecoded(buffer) {
bufferSource = audioContext.createBufferSource();
bufferSource.buffer = buffer;
bufferSource.connect(audioContext.destination);
}
request.onload = function () {
// audio data is in request.response
audioContext.decodeAudioData(request.response, onDecoded);
};
request.send();

但是,如果我用缓冲区替换振荡器,如下所示,控制台会告诉我“未捕获 InvalidStateError:无法在“AudioBufferSourceNode”上执行“start”:无法多次调用 start。

AudioBufferSource

function scheduler() {
while (nextTickTime < audioContext.currentTime + lookahead) {
ticksInQueue.push({tick: currentTick, time: nextTickTime});
//Changed code
bufferSource.start(nextTickTime);
bufferSource.stop(nextTickTime + 0.1);
nextTickTime += 60.0 / tempo; // Add beat length to last beat time
currentTick = currentTick + 1; // Advance the beat number, wrap to zero
if (currentTick === 5) {
currentTick = 0;
}
}
}

最佳答案

是的,您需要为每个“tick”创建一个 BufferSource。 (它们共享缓冲区,但缓冲区源是一次性节点。)

所以,像这样:

var the_buffer=null;

function onDecoded(buffer) {
the_buffer=buffer;
}

function playTick() {
if (the_buffer) { // make sure it's been decoded
var bufferSource = audioContext.createBufferSource();
bufferSource.buffer = the_buffer;
bufferSource.connect(audioContext.destination);
bufferSource.start(0);
// bufferSource will get auto-garbage-collected when it's done playing.
}
}

现在,用对 playTick() 的调用替换调度程序中的振荡器代码;

关于javascript - 如何创建并正确调度AudioBufferSource节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36044948/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com