Javascript Web音频API,操作节点
如果我想在声音已经播放时更改立体声平移值,正确的方法是什么 据我所知,这些节点是火和遗忘的,所以我不应该在代码中保留对它们的引用,这样它们就可以被垃圾收集。但是,当我没有对源节点的引用时,我以后无法修改它 我是否必须开始在数组中保存引用,观察它们何时完成并实现我自己的节点清理,或者在运行它们之后是否有更干净的方法来访问它们Javascript Web音频API,操作节点,javascript,web-audio-api,Javascript,Web Audio Api,如果我想在声音已经播放时更改立体声平移值,正确的方法是什么 据我所知,这些节点是火和遗忘的,所以我不应该在代码中保留对它们的引用,这样它们就可以被垃圾收集。但是,当我没有对源节点的引用时,我以后无法修改它 我是否必须开始在数组中保存引用,观察它们何时完成并实现我自己的节点清理,或者在运行它们之后是否有更干净的方法来访问它们 我期望从音频上下文中获得某种getActiveNodes方法,但这显然不是一件事。假设您将来需要更改它们,将元素存储在数组或单个变量中没有什么错。您可以在创建元素时执行此操作
我期望从
音频上下文中获得某种getActiveNodes
方法,但这显然不是一件事。假设您将来需要更改它们,将元素存储在数组或单个变量中没有什么错。您可以在创建元素时执行此操作,也可以使用document.querySelect
等简单地选择所有元素。例如,您可以选择所有。还可以查看它。假设将来需要更改它们,将元素存储在数组或单个变量中没有什么错。您可以在创建元素时执行此操作,也可以使用document.querySelect
等简单地选择所有元素。例如,您可以选择所有。还可以查看它。我假设您的代码中有一个函数,它可以播放AudioBufferSourceNode
,还可以创建StereoPannerNode
。也许它看起来像这样:
function playAudioBuffer (audioContext, audioBuffer) {
const audioBufferSourceNode = new AudioBufferSourceNode(audioContext, { buffer: audioBuffer });
const sterePannerNode = new StereoPannerNode(audioContext);
audioBufferSourceNode
.connect(sterePannerNode)
.connect(audioContext.destination);
audioBufferSourceNode.start();
}
function playAudioBuffer (audioContext, audioBuffer) {
const audioBufferSourceNode = new AudioBufferSourceNode(audioContext, { buffer: audioBuffer });
const sterePannerNode = new StereoPannerNode(audioContext);
audioBufferSourceNode
.connect(sterePannerNode)
.connect(audioContext.destination);
audioBufferSourceNode.start();
const audioNodes = { audioBufferSourceNode, sterePannerNode };
activeAudioNodes.push(audioNodes);
audioBufferSourceNode.onended = () => {
audioBufferSourceNode.disconnect();
sterePannerNode.disconnect();
activeAudioNodes.splice(activeAudioNodes.indexOf(audioNodes), 1);
};
}
您可以定义一个变量,该变量可在该函数内访问,并保存对所有活动AudioNode的引用
const activeAudioNodes = [ ];
它只是一个数组。您可以使用AudioBufferSourceNode
触发的end
事件来管理它。然后,您的playAudioBuffer()
函数将如下所示:
function playAudioBuffer (audioContext, audioBuffer) {
const audioBufferSourceNode = new AudioBufferSourceNode(audioContext, { buffer: audioBuffer });
const sterePannerNode = new StereoPannerNode(audioContext);
audioBufferSourceNode
.connect(sterePannerNode)
.connect(audioContext.destination);
audioBufferSourceNode.start();
}
function playAudioBuffer (audioContext, audioBuffer) {
const audioBufferSourceNode = new AudioBufferSourceNode(audioContext, { buffer: audioBuffer });
const sterePannerNode = new StereoPannerNode(audioContext);
audioBufferSourceNode
.connect(sterePannerNode)
.connect(audioContext.destination);
audioBufferSourceNode.start();
const audioNodes = { audioBufferSourceNode, sterePannerNode };
activeAudioNodes.push(audioNodes);
audioBufferSourceNode.onended = () => {
audioBufferSourceNode.disconnect();
sterePannerNode.disconnect();
activeAudioNodes.splice(activeAudioNodes.indexOf(audioNodes), 1);
};
}
activeAudioNodes
数组将保存对每个播放AudioNode
的引用。我假设您的代码中有一个函数,它播放AudioBufferSourceNode
,并创建一个StereoPannerNode
。也许它看起来像这样:
function playAudioBuffer (audioContext, audioBuffer) {
const audioBufferSourceNode = new AudioBufferSourceNode(audioContext, { buffer: audioBuffer });
const sterePannerNode = new StereoPannerNode(audioContext);
audioBufferSourceNode
.connect(sterePannerNode)
.connect(audioContext.destination);
audioBufferSourceNode.start();
}
function playAudioBuffer (audioContext, audioBuffer) {
const audioBufferSourceNode = new AudioBufferSourceNode(audioContext, { buffer: audioBuffer });
const sterePannerNode = new StereoPannerNode(audioContext);
audioBufferSourceNode
.connect(sterePannerNode)
.connect(audioContext.destination);
audioBufferSourceNode.start();
const audioNodes = { audioBufferSourceNode, sterePannerNode };
activeAudioNodes.push(audioNodes);
audioBufferSourceNode.onended = () => {
audioBufferSourceNode.disconnect();
sterePannerNode.disconnect();
activeAudioNodes.splice(activeAudioNodes.indexOf(audioNodes), 1);
};
}
您可以定义一个变量,该变量可在该函数内访问,并保存对所有活动AudioNode的引用
const activeAudioNodes = [ ];
它只是一个数组。您可以使用AudioBufferSourceNode
触发的end
事件来管理它。然后,您的playAudioBuffer()
函数将如下所示:
function playAudioBuffer (audioContext, audioBuffer) {
const audioBufferSourceNode = new AudioBufferSourceNode(audioContext, { buffer: audioBuffer });
const sterePannerNode = new StereoPannerNode(audioContext);
audioBufferSourceNode
.connect(sterePannerNode)
.connect(audioContext.destination);
audioBufferSourceNode.start();
}
function playAudioBuffer (audioContext, audioBuffer) {
const audioBufferSourceNode = new AudioBufferSourceNode(audioContext, { buffer: audioBuffer });
const sterePannerNode = new StereoPannerNode(audioContext);
audioBufferSourceNode
.connect(sterePannerNode)
.connect(audioContext.destination);
audioBufferSourceNode.start();
const audioNodes = { audioBufferSourceNode, sterePannerNode };
activeAudioNodes.push(audioNodes);
audioBufferSourceNode.onended = () => {
audioBufferSourceNode.disconnect();
sterePannerNode.disconnect();
activeAudioNodes.splice(activeAudioNodes.indexOf(audioNodes), 1);
};
}
然后,activeAudioNodes
数组将保存对每个播放的audionodes
的引用。我不使用元素,我正在获取音频缓冲区。我的观点是,当我有一个链时,例如sourceNode->gainNode->panNode->ConvalverNode->masterGainNode->output,根据规范,当声音停止播放时,它们会被垃圾收集,但如果我将它们存储在数组中,我会创建引用,将所有这些节点保留在内存中。在玩了一个小时的网络游戏后,创建了数千个节点,内存一团糟。从数组中手动删除它们是有问题的。例如,当我使用回声效果时,我不知道回声何时结束。我不使用元素,而是获取音频缓冲区。我的观点是,当我有一个链时,例如sourceNode->gainNode->panNode->ConvalverNode->masterGainNode->output,根据规范,当声音停止播放时,它们会被垃圾收集,但如果我将它们存储在数组中,我会创建引用,将所有这些节点保留在内存中。在玩了一个小时的网络游戏后,创建了数千个节点,内存一团糟。从数组中手动删除它们是有问题的。例如,当我使用回声效果时,我不知道回声何时完成。