Is there a soundInstance equivalent function of texture.destroy? I know I can free up asset memory but I’d like to free up all other uncompressed memory that is used to play the sound. For example, I know that the source attribute of the soundInstance is of type AudioBufferSourceNode and that this AudioBufferSourceNode is garbage collected automatically. I’d rather destroy it myself
Is soundAsset.unload(); supposed to reclaim memory immediately or is that left to garbage collector?
The reason being, is that I load the new soundAsset after releasing the old soundAsset
I am not able to test with the iPad that I have.regarding errors. I only know that the app crashes at that point when a new sound is replaced with an older sound
It would be nice to have the inspector show more memory information for sounds while I develop like it did with texture assets so that I can be sure if it is the sound giving this crash on the old iPad or some other reason. Here is the SoundManager class I’ve created, maybe you can see something I’m doing wrong. When a person wants to go to a specific location in the game, I call SoundManager.prototype.play(this.entity.findByName(“Cross Mountain”)); where the entity named ‘Cross Mountain’ is the entity that has the sound component as shown in the screenshot below
var SoundManager = pc.createScript('soundManager');
SoundManager.prototype.backgroundSoundEntity = null;
SoundManager.prototype.currentlyPlayingSlot = null;
// SOUNDMANAGER IS CREATED TO OPTIMIZE FOR LOW-END DEVICES
// SO THAT ONLY SONGS THAT PLAY ARE IN DEVICE MEMORY
// SO TO GET BEST OPTIMIZATION, YOU SHOULD DESTROY ALL OTHER LARGE SOUND FILES AND REMOVE FROM CACHE IF NOT PLAYING
SoundManager.prototype.initialize = function() {
//SoundManager.prototype.play(this.entity.findByName("Intro"));
};
SoundManager.prototype.destroyCurrentPlayedSlotAndSystemSoundContext = function(pfunctionToCallAfterPromiseReturnsFromContextCloseFunctionExecutes) {
// alert('destroyCurrentPlayedSlotAndSystemSoundContext');
if (SoundManager.prototype.currentlyPlayingSlot) {
// alert('SoundManager.prototype.currentlyPlayingSlot.instances BEFORE STOP = ' + SoundManager.prototype.currentlyPlayingSlot.instances);
for (var counter=0; counter< SoundManager.prototype.currentlyPlayingSlot.instances.length; counter++) {
this.soundInstancePlayedBySlot = SoundManager.prototype.currentlyPlayingSlot.instances[counter];
// this.soundInstancePlayedBySlot.source = null;
this.soundInstancePlayedBySlot.stop();// ALALOGOUS TO UPDATING MATERIAL AFTER DELETING IT'S TEXTURE MEMORY
this.soundInstancePlayedBySlot.clearExternalNodes();
}
SoundManager.prototype.currentlyPlayingSlot.stop();
SoundManager.prototype.currentlyPlayingSlot.clearExternalNodes();
this.theAsset = app.assets.get(SoundManager.prototype.currentlyPlayingSlot.asset);
if (this.theAsset) {
app.loader.clearCache(this.theAsset.getFileUrl(), this.theAsset.type); // clear old sound from loader cache
this.theAsset.unload();
}
SoundManager.prototype.backgroundSoundEntity.sound.system.context.close().then(
function(){
// alert('DESTROYED SoundManager.prototype.backgroundSoundEntity.name = ' + SoundManager.prototype.backgroundSoundEntity.name);
SoundManager.prototype.backgroundSoundEntity.sound.enabled = false;
SoundManager.prototype.backgroundSoundEntity.enabled = false;
SoundManager.prototype.currentlyPlayingSlot = null;
SoundManager.prototype.backgroundSoundEntity = null;
pfunctionToCallAfterPromiseReturnsFromContextCloseFunctionExecutes();
}.bind({pfunctionToCallAfterPromiseReturnsFromContextCloseFunctionExecutes: pfunctionToCallAfterPromiseReturnsFromContextCloseFunctionExecutes})
); // Closes the audio context, releasing any system audio resources that it uses.]
// SoundManager.prototype.backgroundSoundEntity.sound.enabled = false;
// SoundManager.prototype.backgroundSoundEntity.enabled = false;
SoundManager.prototype.backgroundSoundEntity.sound.removeSlot(SoundManager.prototype.currentlyPlayingSlot.name);
}else{
pfunctionToCallAfterPromiseReturnsFromContextCloseFunctionExecutes();
}
// SoundManager.prototype.currentlyPlayingSlot = null;
// SoundManager.prototype.backgroundSoundEntity = null;
};
SoundManager.prototype.createSystemSoundContextToLaterDelete = function(pEnityWithSoundComponent) {
newApp = app;
var newSoundManager = new pc.SoundManager({volume: 1, forceWebAudioApi: true});
newApp.systems.sound.manager = newSoundManager;
var newEntity = new pc.Entity('bla', newApp);
try {
newSoundComponent = newEntity.addComponent("sound", {
slots: []
});
} catch(err){
alert('err creating newSoundComponent = ' + err);
}
var getAsset = app.assets.get(SoundManager.prototype.currentlyPlayingSlot.asset);
var newSoundSlot;
try {
newSoundSlot = newSoundComponent.addSlot(SoundManager.prototype.currentlyPlayingSlot.name + '', {
asset: getAsset,
loop: SoundManager.prototype.currentlyPlayingSlot.loop
});
newSoundSlot.play();
} catch(err){
alert('err 2= ' + err);
}
//SWAP TO DELETE CONTEXT LATER
SoundManager.prototype.currentlyPlayingSlot = newSoundSlot;
SoundManager.prototype.backgroundSoundEntity = newEntity;
};
SoundManager.prototype.play = function(pEnityWithSoundComponent) {
SoundManager.prototype.destroyCurrentPlayedSlotAndSystemSoundContext(function(){
SoundManager.prototype.backgroundSoundEntity = pEnityWithSoundComponent;
SoundManager.prototype.currentlyPlayingSlot = SoundManager.prototype.backgroundSoundEntity.sound.slot("BackgroundSound");
SoundManager.prototype.currentlyPlayingSlot.autoplay = false; //MUST ALWAYS SET FALSE SO THAT PLAY IS NOT CALLED TWICE AFTER LOADING ASSET
SoundManager.prototype.currentlyPlayingSlot.loop = true; //MUST ALWAYS SET FALSE FOR LATER OPTIMIZATION (MY CODE HANDLES LOOPS)
SoundManager.prototype.currentlyPlayingSlot.on("load", SoundManager.prototype.onSlotLoadHandler, SoundManager.prototype.currentlyPlayingSlot);
SoundManager.prototype.currentlyPlayingSlot.on("play", SoundManager.prototype.onSlotPlayHandler, SoundManager.prototype.currentlyPlayingSlot);
SoundManager.prototype.currentlyPlayingSlot.load();
}
);
};
SoundManager.prototype.onSlotLoadHandler = function(evt) {
SoundManager.prototype.currentlyPlayingSlot.off("load", SoundManager.prototype.onSlotLoadHandler, SoundManager.prototype.currentlyPlayingSlot);
SoundManager.prototype.createSystemSoundContextToLaterDelete(SoundManager.prototype.backgroundSoundEntity);
};
SoundManager.prototype.onSlotPlayHandler = function(evt) {
SoundManager.prototype.currentlyPlayingSlot.off("play", SoundManager.prototype.onSlotPlayHandler, SoundManager.prototype.currentlyPlayingSlot);
};
SoundManager.prototype.onSoundInstanceAudioBufferSourceNodeInstanceEndHandler = function(evt) {
};
SoundManager.prototype.onSoundInstanceAudioBufferSourceNodeInstanceStopHandler = function(evt) {
};