How to implement Audio disposal in C2 for use in Cocoon?

  • My mobile game has a lot of sounds in it (voice clips) which drive the memory up a little more than I'd like. I'm using Cocoon Canvas+ to port to mobile, and it is said to contain a dispose() overload on all Audio objects. I'm trying to use this function to dynamically load/unload sounds as I need them.

    I started by adding an "Unload By Name" action to the Audio object of Construct 2, and its code looks like this:

    Acts.prototype.UnloadByName = function (filename)
    {
    	// only unload if we are in CocoonJS
    	if (this.runtime.isCocoonJs)
    	{
    		var src = this.runtime.files_subfolder + filename.toLowerCase() + (useOgg ? ".ogg" : ".m4a");
    		
    		// unload it
    		var instance = this.unloadAudioInstance(src);
    	}
    }
    
    instanceProto.unloadAudioInstance = function (src_)
    {
    	// Try to find existing instance from the same source
    	var i, len, a;		
    	var bufferToDispose, instanceObjectToDispose;
    	var foundInstance = 0;
    	
    	for (i = 0, len = audioInstances.length; i < len; i++)
    	{
    		a = audioInstances[i];
    		
    		if (a.src === src_ && (a.canBeRecycled() || is_music))
    		{
    			// DEBUG:
    			console.log("Found instance");
    			
    			// locate existing instance's objects
    			bufferToDispose = a.buffer.bufferObject;
    			instanceObjectToDispose = a.instanceObject;
    			foundInstance = 1;
    			
    			// now remove this audio instance completely and free it up for 
    			// garbage collection using iterative array slice code on Scirra blog:
    			// 

    scirra.com/blog/76/how-to-write-low-garbage-real-time-javascript[/p] for (var x = i, newLen = len - 1; x < newLen; x++)[/p] {[/p] audioInstances[x] = audioInstances[x + 1];[/p] }[/p] audioInstances.length = newLen;[/p] [/p] console.log("Length is now: " + audioInstances.length);[/p] [/p] // we're done with this loop[/p] break;[/p] }[/p] }[/p] [/p] // now there are no references to audio, dispose it using Canvas+ dispose overload[/p] if (foundInstance == 1)[/p] {[/p] bufferToDispose.dispose();[/p] instanceObjectToDispose.dispose();[/p] console.log("Disposed it.");[/p] }[/p] };[/p] [/code:2hb21i2u][/p] Now I'm sure I didn't do it perfectly, because I don't yet completely understand how Audio works, but I tried to make sure to dispose of anything that could potentially contain loaded audio (i.e the "buffer" and the "instanceObject"). I made a test project which uses this function, and here's what I have working (in essence):[/p] [/p] There are about 30 individual voice clips that can be loaded. To load a voice clip, you select it and then either Press "Play" or "Preload". Both seem to do the same thing in terms of loading a clip into memory. To unload a voice clip, you select it and then press "Unload". Now, here is what happens when I try it out:[/p] [/p] At program start, memory use stabilizes at around: [b]72.14 mb[/b][/p] [/p] Once I load all 30 clips into memory, I get: [b]88.70 mb[/b][/p] [/p] After I unload all of them, I get: [b]81.50 mb[/b][/p] [/p] After loading all 30 again, I get: [b]81.64 mb[/b][/p] [/p] At this point, no matter what I do, memory stays: [b]81.64 mb[/b][/p] [/p] My question, to anyone that knows anything about memory or anything about Cocoon or Construct 2 Audio, such as Ashley or ludei:[/p] [/p] What exactly could be happening here? Why is it that when I unload everything, only half of the allocated space is released? Is there one more secret Audio object that I didn't dispose of? How come once I've unloaded them the memory use doesn't change much? What am I not understanding? I feel like the answer lies in how Ludei's engine works, or how Construct 2 works. I hope either the developers or someone else knowledgeable in this can help me, so I can start better managing memory in my game.[/p] [/p] Thanks!

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • We do not officially support Canvas+ - I recommend you use any platform that uses a real browser engine. In particular you will get support for the Web Audio API which is a far better audio engine for games.

  • Thank you for the reply Ashley !

    I recognize that Canvas+ is not officially supported, but my choice to use it is well-informed. To me, what makes Construct 2 wonderful is not simply the workflow or the 'officially supported platforms', but the open architecture that makes it easy to tailor the output to one's specific needs. In my case, it allows me to easily add features for a deprecated non-browser wrapper. How can Construct 2 be any more awesome?

    That said, could we revisit the code I've written and why it may not be working how I expect? All I wanted here was a push in the right direction or a thumbs-up-that-looks-fine from someone that understands Construct 2's Audio object well and perhaps some of how Cocoon works as well. You are one of the best people to give me this feedback and if you find the time to reply again, your help and general comments on my code would be immensely appreciated.

    In addition, it could be that my code is correct Construct-2-wise, in which case I may have used Canvas+'s dispose() overload incorrectly. I've seen that ludei is sometimes active around here, so some feedback from them would also be very helpful.

  • B...bu...but , DA PERFORMANCE

  • I don't think I can give you any useful advice. The Audio plugin has thousands of lines of code, and it is all written on the assumption audio objects are never disposed, because that is not a feature of HTML5. I can't anticipate the consequences even if your code appears to work in simple cases - there may be strange bugs in some cases, I just couldn't tell you, because you're making unsupported changes directly to the engine.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)