audio memory leak

Testing the app consist of the following code in instrument show that there is memory leak.

local Sound = audio.loadSound("gamemusic1.mp3")  
  
audio.play(Sound)  
  
local function disposeSound()  
 audio.stop(Sound)  
 audio.dispose(Sound)  
 Sound = nil  
end  
  
timer.performWithDelay(10000, disposeSound, 1)  

Look like it is a bug or I’m missing something? Anyone see this issue before? Thanks.

Steve
[import]uid: 84159 topic_id: 14854 reply_id: 314854[/import]

@stevebell009 I think I have the same problem as well. I can’t figure out any other source of my leakage but I’m pretty sure it’s audio related. I could be wrong though. I do things the same as you too. [import]uid: 10361 topic_id: 14854 reply_id: 54860[/import]

I’m seeing a similar issue in an interactive book I’m working on using the Kwik plug-in which uses the same type of method for audio disposal. Everything works fine through the first 9-10 pages (levels) and then audio files start failing to load until no audio can be loaded.

I get the following error in the terminal:
59Testing error: Invalid Operation
59Testing error: Invalid Operation
59Testing error: Invalid Operation
59Testing error: Invalid Operation
59Testing error: Invalid Operation
59Testing error: Invalid Operation
59Testing error: Invalid Operation
59Testing error: Invalid Operation
59Testing error: Invalid Operation
WARNING: Failed to create audio sound(Iis4Iguana.mp3)
59Testing error: Invalid Operation
59Testing error: Invalid Operation
59Testing error: Invalid Operation
59Testing error: Invalid Operation
WARNING: Failed to create audio sound(His4Horse.mp3)
WARNING: Failed to create audio sound(h.mp3)
59Testing error: Invalid Operation
WARNING: Failed to create audio sound(i.mp3)
WARNING: Failed to create audio sound(Iis4Iguana.mp3)
WARNING: Failed to create audio sound(Jis4Jaguar.mp3)
WARNING: Failed to create audio sound(Juice.mp3)
WARNING: Failed to create audio sound(J.mp3)
WARNING: Failed to create audio sound(slurp.mp3)
59Testing error: Invalid Operation
WARNING: Failed to create audio sound(i.mp3)
WARNING: Failed to create audio sound(Iis4Iguana.mp3)
WARNING: Failed to create audio sound(His4Horse.mp3)
WARNING: Failed to create audio sound(h.mp3)
WARNING: Failed to create audio sound(Gis4Giraffe.mp3)
WARNING: Failed to create audio sound(Putt4Fun.mp3)
WARNING: Failed to create audio sound(g.mp3)
WARNING: Failed to create audio sound(Golf_Ball_Putt.wav)
WARNING: Failed to create audio sound(Fis4Frog.mp3)
WARNING: Failed to create audio sound(f.mp3)
WARNING: Failed to create audio sound(FlyBuzzing.mp3)
WARNING: Failed to create audio sound(Eis4Elephant.mp3)
WARNING: Failed to create audio sound(e.mp3)
WARNING: Failed to create audio sound(SentenceD.mp3)
WARNING: Failed to create audio sound(Dis4Dolphin.mp3)
WARNING: Failed to create audio sound(d.mp3)
WARNING: Failed to create audio sound(SentenceC.mp3)
WARNING: Failed to create audio sound(c.mp3)
WARNING: Failed to create audio sound(c.mp3)
WARNING: Failed to create audio sound(Cis4Camel.mp3)
WARNING: Failed to create audio sound(SentenceB.mp3)
WARNING: Failed to create audio sound(SentenceB.mp3)

ETC, ETC.
[import]uid: 37208 topic_id: 14854 reply_id: 54994[/import]

Same here! [import]uid: 66859 topic_id: 14854 reply_id: 55011[/import]

I can dispose the audio and nil it out and still nothing changes to my memUsage as I watch it happen. [import]uid: 10361 topic_id: 14854 reply_id: 55012[/import]

It has to be an issue with audio.loadStream. I changed all my audio calls to audio.loadSound and I am no longer having issues. Obviously that’s not a desired long-term solution, but it has resolved my issue until this bug does get fixed.

In my case, I believe that the garbage collection routines weren’t doing anything and eventually the 32 available audio channels were consumed, preventing audio.loadStream from creating new audio.

Good luck fellas. [import]uid: 37208 topic_id: 14854 reply_id: 55013[/import]

I’m not using audio.loadStream. I’ve been using audio.loadSound. Not entirely sure the disposal is working properly. [import]uid: 10361 topic_id: 14854 reply_id: 55086[/import]

I tested my app for about two hours and although Instrument reported leaking, collectgarbage(“count”) didn’t exceed 600.

I hope Ansca developer can clarify this.

Steve [import]uid: 84159 topic_id: 14854 reply_id: 55089[/import]

http://developer.anscamobile.com/forum/2011/04/27/memory-leaks-possible-corona-bug [import]uid: 87611 topic_id: 14854 reply_id: 55142[/import]

"I’m seeing a similar issue in an interactive book I’m working on using the Kwik plug-in which uses the same type of method for audio disposal. Everything works fine through the first 9-10 pages (levels) and then audio files start failing to load until no audio can be loaded. "
Same issue in my Butterfly Counting app. I’m going to try your solution.
[import]uid: 57860 topic_id: 14854 reply_id: 55525[/import]

I suspect you are out of memory on your device. If you are on iOS, you should be checking for the low memory warnings.

Your code looks suspicious though. It looks like you might be loading some files more than once (e.g. Iis4Iguana.mp3). If you are doing this, you need to be very careful about how you are calling audio.dispose(). For loadStream, you get back unique handles for each load (meaning you load a new entire instance), so you must dispose() each one separately. loadSound used to be the same way, but at some point, in the last cycle, we introduced a caching system so you don’t waste memory loading the same file multiple times. But the number of times you call dispose() must balance the number of times you call loadSound() because we still pretend you load multiple instances of the sound. So if you load same sound twice in a row, you must call dispose on it twice; otherwise the memory is not unloaded.

[import]uid: 7563 topic_id: 14854 reply_id: 55542[/import]

By the way, the initial memory leak that some of you see from the code at the very top of this thread is a leak in Apple’s OpenAL implementation. As the other thread explains, it is a known Apple issue and only a small one-time leak.
[import]uid: 7563 topic_id: 14854 reply_id: 55551[/import]

Ewing,

The log does make it look like the sound is being loaded multiple times, but that’s because the log traverses multiple pages (levels) and you’re not seeing the cleanup that’s happening. For this log capture, the sounds are initialized via audio.loadStream at start-up and only one time. When the user leaves the page, the following is called for each audio handle…

audio.stop( AUDIOHANDLE ); audio.dispose( AUDIOHANDLE ); AUDIOHANDLE = nil

I changed the audio.loadStream to audio.loadSound and my issues with sound no longer playing were largely resolved (still 1 issue, but may not be related). I noticed that when using audio.loadStream, the game would always stop producing sound about halfway through. My suspicion is that the 32 available audio channels were being consumed and not released. So at a certain point, there were no longer any channels available to create new audio handles.

In regards to the the memory consumption, no other activities in the application seem to be performing poorly. All animations and events trigger appropriately and are responsive. I’m not sure exactly how you are proposing to monitor memory issues but would like to learn. I did check the logs created in XCode for anything suspicious, but couldn’t find anything.

[import]uid: 37208 topic_id: 14854 reply_id: 55561[/import]

While it is not impossible, I’m skeptical that loadStream and loadSound would produce the differences you are seeing. Though if this is iOS, try testing with the latest iOS release.

To prove your channel theory, you can use functions like findFreeChannel and freeChannels to see what the system has available.

Memory leaks can be monitored with Instruments on Mac/iOS. (Might be able to use Valgrind on Android…not sure.) But beware that these tools give false positives and also show you leaks deep in Apple’s frameworks too so there is a lot of noise you need to ignore.
[import]uid: 7563 topic_id: 14854 reply_id: 55574[/import]

You’re suggestion to use findFreeChannel is a good one for troubleshooting. I will give it a try to prove my theory.

I think it is quite possible that audio.loadStream and audio.loadSound ARE behaving differently and causing the issue I’m experiencing. Perhaps it is just tied to a particular set of circustances we don’t yet understand (build, versions, etc.)

If I use audio.loadStream my application fails to produce sound after a finite number of audio events.

When I change the audio method to loadSound (and it is the only app change), the app plays through in its entirety without audio issues.

This suggests there is a difference in how they behave and that audio.loadStream may have an issue.

I am seeing this behavior in both the Simulator on a Mac and on the device (iPad and iPhone 3GS).

I will do a test with the freeChannel to see if this is indeed what is happening. [import]uid: 37208 topic_id: 14854 reply_id: 55580[/import]

Remember that you may not play multiple simultaneous instances of the same loadStream. This would be one area where loadSound and loadStream behave differently.
[import]uid: 7563 topic_id: 14854 reply_id: 55583[/import]

I just wanted to add some support to RobMabry’s findings. I have about 100 .wav narration clips, and for some reason, around the 50th clip the audio would just stop playing. I spent countless hours trying to figure out why this was happening, before I came across the above suggestion to change all instances of audio.loadStream to audio.loadSound. And voila! All 100 of my sound clips are now playing! There must be a bug in the system, but I know for sure I am going to use loadSound instead of loadStream from now on. [import]uid: 82194 topic_id: 14854 reply_id: 56612[/import]

There is a high possibility you are hitting operating system limits. Operating systems limit the number of simultaneous open files you may have. audio.loadStream() opens a file and reads little bits of it at a time as you need it. It must keep the file open to do this. So every loadStream instance you have means you have another open file.

In contrast, audio.loadSound() loads the entire file into RAM and then closes the file.

I argue you are abusing/misusing the audio.loadStream() API. 50 files open is excessive. You can’t play that many files simultaneously. With that many files, you should close the audio.loadStreams you are not actively using with audio.dispose() and then reopen them when you need them again.

For best performance and smallest latency, audio.loadSound() is the best API to use. audio.loadStream() is to be used when your files are too big. It is expected that you won’t need more than a few loadStreams at any given time (e.g. background music + speech)

[import]uid: 7563 topic_id: 14854 reply_id: 56620[/import]

Reporting back on my investigation into this and the theory regarding channel consumption.

I put in some debug code to check and see whether channels were getting consumed and not released. That check tells me that this is not the issue. Only one channel was in use at any given time when my code was executed. However, the sound “crash” remained when using audio.loadStream. And by crash, I mean that sound stopped playing after a certain number of events. The performance of the app was fine otherwise.

I am making the following clean up calls: audio.stop( AUDIOHANDLE ); audio.dispose( AUDIOHANDLE ); AUDIOHANDLE = nil
If I were on the Ansca Staff, I would ask for a code example from someone who is having this issue and offer assistance. Perhaps, we could then pinpoint the issue and we could all learn from it.
[import]uid: 37208 topic_id: 14854 reply_id: 56674[/import]

I’m seeing this error with build 619 with my code. I’m not seeing it with build 605 or earlier. This is on the Mac simulator. I haven’t tried building a version for my iPad yet.

Since my code hasn’t changed, this is definitely related to changes you’ve made to the Corona.

As with others, if I change my audio.loadStream calls to audio.loadSound, the error goes away.

From reading the discussion above, I’m probably really pushing the sound system resources, even though I haven’t had any issues before. I have been pre-loading all my sounds (about 75) when the app first starts up. In my initial versions, I used loadSound for all sounds. But when I started working on an iPhone version, pre-loading that many sounds on a iPhone 3G took so long that the app would crash due to long load times.

So I then tried a combination of the two, where I’d use loadSound for the shorter sounds that I use throughout, and loadStream for some of the longer ones.

Anyway, in my current code sample, I’m only loading 24 sounds, 7 are loadSound, and 17 are loadStream. The error seems to trigger with just one of the sounds. If I change that one sound from loadStream to loadSound, the error goes away.

Happy to provide a complete build of this if that would help. [import]uid: 9905 topic_id: 14854 reply_id: 56760[/import]