循环释放 WEB 音频缓冲区



这是这个线程的后续问题: 发布音频缓冲区 Web 音频 API 因为我无法弄清楚如何使答案适应我的代码。 到目前为止,我有这段代码,它是在循环中运行的,当它播放时,CPU 使用率随着时间的推移而增长,直到它变得不可用。 我猜,在Webview中,节点似乎保持活动状态。

我的代码:

function n_BufferLoader(n_context, n_urlList, callback) {
this.context = n_context;
this.n_urlList = n_urlList;
this.onload = callback;
this.n_bufferList = new Array();
this.loadCount = 0;
}
n_BufferLoader.prototype.n_loadBuffer = function(url, index) {
// Load buffer asynchronously
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";
var n_loader = this;
request.onload = function() {
// Asynchronously decode the audio file data in request.response
n_loader.context.decodeAudioData(
request.response,
function(n_buffer) {
if (!n_buffer) {
alert('error decoding file data: ' + url);
return;
}
n_loader.n_bufferList[index] = n_buffer;
if (++n_loader.loadCount == n_loader.n_urlList.length)
n_loader.onload(n_loader.n_bufferList);
},
function(error) {
console.error('decodeAudioData error', error);
}
);
}
request.onerror = function() {
alert('n_BufferLoader: XHR error');
}
request.send();
}
n_BufferLoader.prototype.load = function() {
for (i = 0; i < this.n_urlList.length; ++i)
this.n_loadBuffer(this.n_urlList[i], i);
}
// Keep track of all loaded buffers.
n_BUFFERS = {};
// Page-wide audio context.
n_context = null;
// An object to track the buffers to load {name: path}
n_BUFFERS_TO_LOAD = {
noise_01: '/android_asset/www/audio/b.mp3',
noise_02: '/android_asset/www/audio/b.mp3',
};
// Loads all sound samples into the buffers object.
function n_loadBuffers() {
// Array-ify
n_names = [];
n_paths = [];
for (n_name in n_BUFFERS_TO_LOAD) {
n_path = n_BUFFERS_TO_LOAD[n_name];
n_names.push(n_name);
n_paths.push(n_path);
}
n_bufferLoader = new n_BufferLoader(n_context, n_paths, function(n_bufferList) {
for (i = 0; i < n_bufferList.length; i++) {
n_buffer = n_bufferList[i];
n_name = n_names[i];
n_BUFFERS[n_name] = n_buffer;
}
});
n_bufferLoader.load();
}
document.addEventListener('DOMContentLoaded', function() {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
n_context = new AudioContext();
n_loadBuffers();
});
NoisePlaylistSample = {
FADE_TIME: 3, // Seconds
playing: false
};
NoisePlaylistSample.play = function() {
n_ctx = this;
n_playHelper(n_BUFFERS.noise_01, n_BUFFERS.noise_02);
function createSource(n_buffer) {
n_source = n_context.createBufferSource();
n_gainNode = n_context.createGain ? n_context.createGain() : n_context.createGainNode();
noise_gainNode = n_context.createGain ? n_context.createGain() : n_context.createGainNode();
main_n_gainNode = n_context.createGain ? n_context.createGain() : n_context.createGainNode();
noise_filter = n_context.createBiquadFilter();
noise_filter.type = "lowpass"; // LOWPASS
noise_filter.frequency.value = $('#fil-noise').val() * 2;
n_source.buffer = n_buffer;
// Connect source to gain.
n_source.connect(n_gainNode);
n_gainNode.connect(noise_gainNode);
// Connect gain to destination.
noise_gainNode.connect(noise_filter);
noise_filter.connect(main_n_gainNode);
main_n_gainNode.connect(n_context.destination);
return {
n_source: n_source,
n_gainNode: n_gainNode,
noise_gainNode: noise_gainNode,
noise_filter: noise_filter,
};
}
function n_playHelper(n_bufferNow, n_bufferLater) {
n_playNow = createSource(n_bufferNow);
n_source = n_playNow.n_source;
n_ctx.n_source = n_source;
n_gainNode = n_playNow.n_gainNode;
n_duration = n_bufferNow.duration;
n_currTime = n_context.currentTime;
// Fade the playNow track in.
n_gainNode.gain.linearRampToValueAtTime(0, n_currTime);
n_gainNode.gain.linearRampToValueAtTime(endvol_noise, n_currTime + n_ctx.FADE_TIME);
// Play the playNow track.
n_source.start ? n_source.start(0) : n_source.noteOn(0);
// At the end of the track, fade it out.
n_gainNode.gain.linearRampToValueAtTime(endvol_noise, n_currTime + n_duration-n_ctx.FADE_TIME);
n_gainNode.gain.linearRampToValueAtTime(0, n_currTime + n_duration);
// Schedule a recursive track change with the tracks swapped.
var n_recurse = arguments.callee;
n_ctx.timer = setTimeout(function() {
n_recurse(n_bufferLater, n_bufferNow);
}, (n_duration - n_ctx.FADE_TIME-1) * 1000);
}
};

有人知道每次循环/循环/递归跟踪运行时我能做些什么来释放旧的缓冲区/节点,以便可以对其进行垃圾回收?

非常感谢您的帮助!!

如果停止缓冲区,则应对其进行垃圾回收。 => 注意关闭早期版本停止永远不会意识到。 在缓冲区的 .duration(( 之后停止缓冲区 试过了吗?

最新更新