Javascript 动态创建振荡器会导致p5声音中的内存问题
在我的代码中(下面的代码是一个非常简短的版本),我在draw中创建了振荡器()。最终,音频开始噼啪作响,变得很奇怪,我想这是因为振荡器没有被垃圾收集?当查看Inspect元素中的Memory选项卡时,它会不断上升,最终音频会发出噼啪声 我尝试使用断开变量/函数中的两个函数来解引用振荡器。这将在我希望的特定时间后将振荡器设置为空。我不确定如何将引用参数设置为null 也许p5声音库仍然为他们保留参考资料Javascript 动态创建振荡器会导致p5声音中的内存问题,javascript,audio,p5.js,Javascript,Audio,P5.js,在我的代码中(下面的代码是一个非常简短的版本),我在draw中创建了振荡器()。最终,音频开始噼啪作响,变得很奇怪,我想这是因为振荡器没有被垃圾收集?当查看Inspect元素中的Memory选项卡时,它会不断上升,最终音频会发出噼啪声 我尝试使用断开变量/函数中的两个函数来解引用振荡器。这将在我希望的特定时间后将振荡器设置为空。我不确定如何将引用参数设置为null 也许p5声音库仍然为他们保留参考资料 function createOsc(grid) { let osc = new p5.O
function createOsc(grid) {
let osc = new p5.Oscillator();
if (grids[grid].type == 1) {
osc.setType("triangle");
} else if (grids[grid].type == 2) {
osc.setType("sawtooth");
} else if (grids[grid].type == 3) {
osc.setType("square");
}
return osc;
}
function createEnv(grid) {
let env = new p5.Envelope();
env.set(grids[grid].ADSR.attack, grids[grid].vol, grids[grid].ADSR.decay, grids[grid].ADSR.sustain * grids[grid].vol, grids[grid].ADSR.release, 0);
return env;
}
let disconnect = {
list: [],
osc: function(osc, time) {
this.list.push([osc, time, 0]);
},
update: function() {
for (i = 0; i < this.list.length; i++) {
this.list[i][2] += 1 / 60.0;
if (this.list[i][2] >= this.list[i][1]) {
this.list[i][0].a.disconnect();
this.list[i][0].a = null;
this.list.splice(i, 1);
i += -1;
}
}
}
}
function draw() {
let osc = createOsc(0);
let env = createEnv(0);
osc.start();
osc.freq(420);
env.triggerAttack(osc);
env.triggerRelease(osc, env.aTime + env.dTime);
osc.stop(env.aTime + env.dTime + env.rTime);
disconnect.osc({a: osc}, env.aTime + env.dTime + env.rTime);
}
函数createOsc(网格){
设osc=新的p5.振荡器();
if(网格[grid].type==1){
osc.集合类型(“三角形”);
}else if(网格[grid]。类型==2){
osc.setType(“锯齿”);
}else if(网格[grid]。类型==3){
osc.设置类型(“方形”);
}
返回osc;
}
函数createEnv(网格){
设env=new p5.Envelope();
环境集合(网格[grid].ADSR.attack,网格[grid].vol,网格[grid].ADSR.decay,网格[grid].ADSR.sustain*grids[grid].vol,网格[grid].ADSR.release,0);
返回环境;
}
让我们断开连接={
名单:[],
osc:功能(osc,时间){
这个.list.push([osc,time,0]);
},
更新:函数(){
对于(i=0;i=this.list[i][1]){
此.list[i][0].a.disconnect();
此.list[i][0].a=null;
本列表拼接(i,1);
i+=-1;
}
}
}
}
函数绘图(){
设osc=createOsc(0);
设env=createEnv(0);
osc.start();
操作频率(420);
环境触发攻击(osc);
环境触发释放(osc、环境时间+环境数据时间);
osc.stop(环境时间+环境数据时间+环境时间);
disconnect.osc({a:osc},env.aTime+env.dTime+env.rTime);
}
我试图使用PolySynth()对象,但由于缺乏清晰的文档,我无法弄清楚如何更改波形或任何东西
编辑:
这个新的独立代码会在一段时间后产生相同的噼啪声。我现在也按照建议使用Millis()。同样的问题是记忆在不断增加
let disconnect = {
list: [],
osc: function(osc, time) {
this.list.push([osc, time, millis()]);
},
update: function() {
for (i = 0; i < this.list.length; i++) {
if (millis() - this.list[i][2] >= this.list[i][1]) {
this.list[i][0].a.disconnect();
this.list[i][0].a = null;
this.list.splice(i, 1);
i += -1;
}
}
}
}
function createOsc() {
let osc = new p5.Oscillator();
osc.setType("triangle");
return osc;
}
function createEnv() {
let env = new p5.Envelope();
env.set(0.1, 1, 0.1, 0.8, 0.1, 0);
return env;
}
function setup() {
frameRate(60);
}
function draw() {
disconnect.update();
print(disconnect.list.length);
if (frameCount % 2 == 0) {
let osc = createOsc();
let env = createEnv();
osc.start();
osc.freq(420);
env.triggerAttack(osc);
env.triggerRelease(osc, 0.2);
osc.stop(0.3);
disconnect.osc({a: osc}, 300);
}
}
let disconnect={
名单:[],
osc:功能(osc,时间){
this.list.push([osc,time,millis()]);
},
更新:函数(){
对于(i=0;i=this.list[i][1]){
此.list[i][0].a.disconnect();
此.list[i][0].a=null;
本列表拼接(i,1);
i+=-1;
}
}
}
}
函数createOsc(){
设osc=新的p5.振荡器();
osc.集合类型(“三角形”);
返回osc;
}
函数createEnv(){
设env=new p5.Envelope();
环境组(0.1,1,0.1,0.8,0.1,0);
返回环境;
}
函数设置(){
帧率(60);
}
函数绘图(){
断开连接。更新();
打印(断开连接。列表。长度);
如果(帧数%2==0){
设osc=createOsc();
设env=createEnv();
osc.start();
操作频率(420);
环境触发攻击(osc);
环境触发释放(osc,0.2);
osc.停止(0.3);
断开连接.osc({a:osc},300);
}
}
1)您可能在未显示的地方调用update,因为如果不这样做,断开连接.list
将无限增长。2) 断开连接的逻辑似乎有点奇怪。为什么要假设每秒会精确调用60次更新?当实时时间(从millis()
或newdate()
或其他内容)超过该时间时,为什么不计算期望振荡器停止的时间并将其移除。3) 在每次调用draw时创建一个新的振荡器似乎有点奇怪,除非您显著限制帧速率。。。。。。如果包络持续时间长于帧之间的间隔,那么您将积累越来越多的同时运行的振荡器(并且您的disconnect.list
数组将不断增长)。如果您能够提供一个最小的工作示例,重现问题,并且没有中断/丢失代码,这将非常有用(什么是网格
?您的设置
功能在哪里?您在哪里/如何调用断开连接.更新
?)。在创建最小复制的过程中,您很有可能会发现导致内存泄漏的原因。@a.Rad出于好奇,为什么您每帧需要30-60个振荡器?(在设置中创建一些并重新使用它们是否还不够)?@GeorgeProfenza我的项目让用户放下音符并播放给他们,一个音乐网格。我可以通过制作一个限制最大声音和内容的系统来重复使用振荡器,但我想知道我是否遗漏了一些明显的可以修复的东西,直到我尝试为止。