ALmixer_FreeData: alDeleteBuffers failed. Invalid Operation - Again

I have been working on this OpenAL problem many times and I can’t find the best way to ensure audio reproduction in the application.

This is the story: I have music, speech narration and sound effects as far as 150 different sound files in .caf and .mp3 format (only for music/narrations).

The application is an interactive-book, therefore each screen has different graphics and sounds, none of them are repeated (I didn’t make the design and concept, so… I am just coding).

The way that I use the sounds is in this format:

First, each screen is switched by using Director Class, after that I use to load the sound by: audio.loadSound (for short sounds) and audio.loadStream (for narration). Sound files for narrations are between 550Kb and 1.2Mb uncompressed.

To reproduce sounds, I use to call audio.play(sound, params)

Then (here I guess the problem reside) when the screen has to be switched to another one, the Clean (director function in the lua code) is invoked with the following lines:

audio.stop(channel)
audio.dispose(sound)
sound=nil

Now, if the sound is reproduced until the end and then the user switch the screen, there is no problem. The channel is liberated and the sound is eliminated (I guess from the memory, but I am not really sure). Then if the user switch the screen in the middle of a sound, (playing) sometimes the stop works well, but dispose seems to not free the resource from the memory, therefore ALmixer_FreeData: alDeleteBuffers failed. Invalid Operation is raised. Some times, after several screens the sound, music or narrations are totally lost. Some times, the volume (really I don’t know why…), goes down without any reason. If the application still running at the end, a crash is produced either in the simulator (including Corona exception and close) or device (app crash).

So, I did some workarounds like add audio.stop(0) on the start of every screen, after the switch. It helps only if there was a previous sound played. If not, it will stop sounds and no more reproductions are executed. (strange behaviour, but happens).

I tried to stop only the active channel, paused or playing one but it seems that it does not work as expected.

In my code the line check if the channel is active by using:

if audio.isChannelPlaying(soundChannel) or audio.isChannelActive(soundChannel) then
audio.pause(soundChannel)

But even so, the audio is not stopped and therefore is not disposed as it is supposed to be. So, at the end, the problem persists.

I tried different scenarios without to much result. I saw there was/is a bug in the Apple OpenAl implementation, but I am also saw applications running well without this problem, so where is the problem? In the Apple OpenAl mixer implementation, in the Corona wrapper or in my code?

I even saw many threats about this issue in the forum without to many clues and I guess Ansca help is required here to put an example code on how to deal with this situation (different screens with Director class, with different sounds loaded, played and disposed in every screen).

Flavio.

[import]uid: 3022 topic_id: 16935 reply_id: 316935[/import]

Sorry this is the right code of the stop rutine:

if soundChannel~=nil and soundChannel~=0 then
if audio.isChannelPlaying(soundChannel) or audio.isChannelPaused(soundChannel) or audio.isChannelActive(soundChannel) then
audio.stop(soundChannel)
end
end

Thx. [import]uid: 3022 topic_id: 16935 reply_id: 63497[/import]

I am using Corona Build 2011.645

Flavio [import]uid: 3022 topic_id: 16935 reply_id: 63498[/import]

And sometimes I even get this: 1133 Segmentation fault where Corona Simulator close.

Flavio.

[import]uid: 3022 topic_id: 16935 reply_id: 63499[/import]

Providing simple, isolated example programs really help us fix problems. We can’t verify and fix problems unless we can reproduce them. And the more complicated the sample program, the harder it is for us to isolate the problem.

Yes, there have been bugs in Apple’s OpenAL implementation. As you may have seen iOS 5.0, has a very bad one. However, there have been other ones in other versions of iOS. (iOS 4.3.x has probably been the best so far.) What version of iOS have you had your problem on? And does it happen on Mac or Android or Windows? What versions?

If the bug happens on all the platforms, it probably is not an OpenAL bug but a Corona bug.
[import]uid: 7563 topic_id: 16935 reply_id: 63516[/import]

I am just testing and developing for iOS devices.

It fails on the Mac version simulator and ipod (4.3.3), iphone 3G (4.1), iphone 4 (4.3.5) and iPad 1 (version 4.3.2).

I didn’t test it on iOS 5. But I need the sounds working on those versions.

Flavio. [import]uid: 3022 topic_id: 16935 reply_id: 63547[/import]

We really need a simple reproducible test case to help you further. I can only give you general advice without it. The general advice is that audio.dispose() will only work correctly if nothing is currently using the handle you are disposing. The most common mistake that can lead to the failures and crashes you see is if you call dispose while the file is still being used. For example, a paused channel is still using the file so it is NOT safe to call dispose yet. Calling audio.stop() on everything should make it safe to dispose the handle.

A new mistake I’ve recently seen is people using timer.performWithDelay to tell them when a sound finishes playing. timer.performWithDelay doesn’t have perfect accuracy so if you are not careful, you might get the performWithDelay callback before the audio finishes playing and calling dispose will create errors/crashes. Instead, the audio completion callbacks are designed to do this kind of work and are guaranteed to fire after the audio completes.
[import]uid: 7563 topic_id: 16935 reply_id: 63590[/import]

Ewing,

Thanks for your guideline.

I would like to share my code, but it has more than 75 .lua files as each section of the e-book is loaded by Director Class. And I guess even if I put a small code, that small code would work, because it doesn’t have the load of the application, files opened, stack of callbacks, sounds loaded in the memory and so on. That’s why I asked a proper example on how to deal with that scenario.

Just to give you an idea of the project that I have, it contains more than 1000 files (.png, jpg, mp3, .caf and .lua). Of course not all of them are opened at the same time, but could be useful to know how can I verify that load (printing to standard output/terminal) to see what is happening there. Because for me they should be downloaded from the memory after each dispose and nilling. May be they still in the memory and they don’t allow any other sound in the memory, causing no reproduction. But in that case, I guess channel if ch is assigned after a ch=audio.play(soundHandler), but the sound is not reproduced, does it mean that soundHandler is already loaded? If not, why audio library assign a valid channel if the sound is not present?

However the general rule that I use is exactly what you mention above. Even so, let’s say I wish to cancel a sound immediately and dispose that sound from the memory, even if that sound will be played again seconds later (because is user-driven between pages of the e-book) so I play the sound, but when it is playing, the user changes the screen to see another page, therefore everything from that previous page has to be cleared. Therefore the Clean function is called from Director class, where I’ve put audio.stop(soundChannel) and the audio.dispose(handleSound) and finally handleSound=nil.

I’ve noticed that if I put an audio.stop() or audio.stop(0) at the beginning of each page, all sounds will be stop abrupt (which is not so ideal) but when the next page tries to reproduce a sound or music, even if a channel is assigned (I did a wrapper to intercept each call and see if the channel is assigned to the sound handler) to that particular sound, the sound is not heard.

Sometimes music is not heard but short-sound effects are reproduced and sometimes the general volume for the music channel is too low (I really don’t know why that thing happens), it seems like a funnel is eating the sounds after several retries.

So, may be there is other way to load, play and dispose sounds or any other available function to monitor that situation???

Thx…

Flavio.
[import]uid: 3022 topic_id: 16935 reply_id: 63653[/import]

local cleanSounds = function()

audio.stop()
if fallingsound then
audio.dispose( fallingsound )
fallingsound = nil
end
if chesthitsound then
audio.dispose( chesthitsound )
chesthitsound = nil
end
if headhitsound then
audio.dispose( headhitsound )
headhitsound = nil
end
if cheerssound then
audio.dispose( cheerssound )
cheerssound = nil
end
if(leghitsound) then
audio.dispose( leghitsound )
leghitsound = nil

end
end

write this cleansounds function and call it in the clean function [import]uid: 95072 topic_id: 16935 reply_id: 67458[/import]

If using background music, this last example is no good. audio.stop() will stop all audio. Not a real fix. [import]uid: 21331 topic_id: 16935 reply_id: 99365[/import]

Interesting. So I believe I’ve run into the same problem as the OP.

I posted my issue here:

http://developer.anscamobile.com/forum/2012/05/18/sound-error-crashes-corona-simulator-mac-app-ios-never-crashes-windows-or-android

As you’ll note the issue I posted has a different error and totally crashes the simulator and the app on iOS and OSX but not on Windows or Android.

But I changed one thing. Previously in my main.lua I reserved channel 1 and played my Background music on that channel.

Out of curiosity (since I could not find a single line of code out of place that would explain this problem) I removed the reservation, and started specifying sound effects to be played on specific channels.

Low and behold, the error that the OP gets appears instead, and after searching for that error, I end up here. Interestingly enough, his description seems to be nearly identical to my situation.

There is definitely something odd going on with playing background music while using director.lua on Apple devices. [import]uid: 37122 topic_id: 16935 reply_id: 108124[/import]

ewing,

I have a project with this error happening, very easy to reproduce. Would you like to take a look? If so, send me your email and I will forward it to you with instructions.

Thanks,
Alex [import]uid: 4883 topic_id: 16935 reply_id: 115548[/import]

Is the code simple to look at? I’m swamped at the moment and I can’t really be looking at bugs that aren’t ours. As explained earlier, that is caused by disposing a handle while something is still using it. That is almost always caused by a bug in your own code. (In a few specific instances, I know how to trigger it with Apple’s specific OpenAL implementations due to race conditions in their code.)

[import]uid: 7563 topic_id: 16935 reply_id: 115828[/import]

I remember having this issue. I haven’t read your whole post so mind me if I’m wrong. My problem I had before is that I would have a button that had a “click” sound when pressed and would then switch scenes. The problem was that the sound all tough short was still playing when I was exiting the scene and calling audio.dispose(). This wasn’t crashing me on windows but was spitting errors. On android it crashed and sometimes it didn’t. The solution is to first stop all audio channels before disposing of them. Use audio.stop(0) to stop ALL channels and then dispose. You can dispose right on the next lien with no errors. Hope this helps.

Edit:I saw that if it was background music and that you don’t want to remove it? If so then you coudl use a global to remove it later in another scene? [import]uid: 118482 topic_id: 16935 reply_id: 115850[/import]

If you don’t need to mix channels, try to use channel=1 option for play.
It resolved problem for me.
[import]uid: 162148 topic_id: 16935 reply_id: 123817[/import]

If you don’t need to mix channels, try to use channel=1 option for play.
It resolved problem for me.
[import]uid: 162148 topic_id: 16935 reply_id: 123817[/import]

I had the same problem. Many sounds and random crashes. The solution is this code:

local filePath = "some/sound.wav" local sound = audio.loadSound(soundName) if audio.play(sound, {onComplete = function ( event ) audio.dispose(event.handle) event.handle = nil end}) == 0 then print("didn't play sound:" .. filePath) end [import]uid: 96906 topic_id: 16935 reply_id: 140026[/import]

I had the same problem. Many sounds and random crashes. The solution is this code:

local filePath = "some/sound.wav" local sound = audio.loadSound(soundName) if audio.play(sound, {onComplete = function ( event ) audio.dispose(event.handle) event.handle = nil end}) == 0 then print("didn't play sound:" .. filePath) end [import]uid: 96906 topic_id: 16935 reply_id: 140026[/import]