How to prevent audio from being force stopped?

Hi,

I have an educational app for children. In the app, i play a background sound track on a continuous loop. The sound track audio is declared as follows:

local function stListener(event) if event.completed then print("sound track stopped normally") else print("sound track forced to stop") end end local st = audio.loadSound ( "audio/soundTrack.mp3") audio.reserveChannels( 2 ) local stPlay = audio.play ( st, { channel=1, loops=-1, onComplete=stListener } )

As you can see, the channel the audio plays on is reserved and the audio is set to loop. Also, at no point do i call or use:

audio.stop()

to stop all audio. Nor do i call or use:

audio.stop(stPlay) 

to stop the soundtrack.

However, there are two scenarios that force the audio to stop by itself and i would like to know if i can prevent that.

scenario 1 (happens sometimes):

If there are too many other audios played. For example, in the scene where this sound track is played, the child has the opportunity to tap different objects. If the correct object is tapped a certain audio is played (call it ‘correctAudio’). If the wrong object is tapped a ‘wrongAudio’ is played. Now if a child keeps tapping repetitively on different objects (as children tend to do), the ‘correctAudio’ and ‘wrongAudio’ will play many times (as many as the child taps) and thus, sometimes, forcing the background sound track to stop.

scenario 2 (happens always)

At the end of the above mentioned scene, when the child taps the correct sequence of objects, he/she is rewarded by a display of fireworks. I use Particle Candy to display fireworks. Whenever the fireworks start, the sound track is stopped.

Regarding scenario 2, i have searched the Particle Candy library to see if they explicitly call audio.stop() to stop all channels but they don’t. They only use audio.stop to stop emitter attached sounds and they pass the emitter sound handle to audio.stop().

Has anyone else faced a similar problem? Is there a way to protect a channel from being forced to stop? I am thinking that maybe (just guessing here) the audio is being stopped to free channels for other audios to play (this is my thinking regarding scenario 1). But who or what is stopping the audio? Aren’t reserved channels ‘reserved’ and you can’t use that channel unless you specify that particular channel number in audio.play? Another thought is that this could be a bug.

And by the way, the problem occurs on the device as well as the simulator (windows).

Does anyone have a solution? Is there a way to prevent an audio from being stopped?

Many thanks for your help.

Luay

Hi Luay,

#1) The audio on reserved channels shouldn’t be stopping even if the max channels are reached. But, it’s possible that the repeated taps and playing of sounds are overloading the system. You might want to use the “findFreeChannel” function to test if one is available, so if the child keeps tapping relentlessly, it simply won’t play another sound if there’s not a channel free.

http://docs.coronalabs.com/api/library/audio/findFreeChannel.html

#2) I don’t know how ParticleCandy works with audio, but can you specify a channel for it to play a sound on? If not, I suggest you try to de-associate the sound from the P.C. call, and just play it yourself in your Lua code, and make sure to fully respect the reserved channels.

Hope this helps,

Brent

Particle Candy tends to just play the sound without any additional parameters, i.e. audio.play(sound).  No channels, looping, onComplete’s etc.

I concur with Brent regarding the overloading.  I would use onComplete’s on the right and wrong sounds that clear a flag that you set when you start to play the sound:

local function donePlaying()        soundPlaying = false end   if not soundPlaying then      soundPlaying = true      audio.play(rightSound, { onComplete=donePlaying } ) end

That way the sounds won’t overplay.

The other think I don’t see here is out put from your console log.  If the audio system is having issues, it tends to throw errors and you might learn what’s going on by looking there fore errors.  If you don’t know how to get to that log information, please read:

http://www.coronalabs.com/blog/2013/07/09/tutorial-basic-debugging/

Rob

Thanks @Brent and @Rob for your input.

I have implemented both approaches and tested it on some kindergarten kids. They seemed to enjoy the results of Brent’s approach more (Sorry Rob :( ).

So, to avoid scenario 1, I search for a free channel before playing the target audio like this:

-- first two channels are reserved for sound track -- so find a free channel after that to play audio local fc = audio.findFreeChannel(2) buzzerAudioPlay = audio.play(buzzerAudio, { channel=fc})

I used the same approach to resolve scenario 2. In Particle Candy, you can pass a sound settings table to ‘SetEmitterSound’. So for my fireworks, the line:

Particles.SetEmitterSound("EmLauncher" , fireworks.SndLaunch)

became as follows:

local fc1 = audio.findFreeChannel(2) Particles.SetEmitterSound("EmLauncher" , fireworks.SndLaunch, 0, false, { channel=fc1})

and that did the trick.

Again, many thanks for your help.

Hi Luay,

#1) The audio on reserved channels shouldn’t be stopping even if the max channels are reached. But, it’s possible that the repeated taps and playing of sounds are overloading the system. You might want to use the “findFreeChannel” function to test if one is available, so if the child keeps tapping relentlessly, it simply won’t play another sound if there’s not a channel free.

http://docs.coronalabs.com/api/library/audio/findFreeChannel.html

#2) I don’t know how ParticleCandy works with audio, but can you specify a channel for it to play a sound on? If not, I suggest you try to de-associate the sound from the P.C. call, and just play it yourself in your Lua code, and make sure to fully respect the reserved channels.

Hope this helps,

Brent

Particle Candy tends to just play the sound without any additional parameters, i.e. audio.play(sound).  No channels, looping, onComplete’s etc.

I concur with Brent regarding the overloading.  I would use onComplete’s on the right and wrong sounds that clear a flag that you set when you start to play the sound:

local function donePlaying()        soundPlaying = false end   if not soundPlaying then      soundPlaying = true      audio.play(rightSound, { onComplete=donePlaying } ) end

That way the sounds won’t overplay.

The other think I don’t see here is out put from your console log.  If the audio system is having issues, it tends to throw errors and you might learn what’s going on by looking there fore errors.  If you don’t know how to get to that log information, please read:

http://www.coronalabs.com/blog/2013/07/09/tutorial-basic-debugging/

Rob

Thanks @Brent and @Rob for your input.

I have implemented both approaches and tested it on some kindergarten kids. They seemed to enjoy the results of Brent’s approach more (Sorry Rob :( ).

So, to avoid scenario 1, I search for a free channel before playing the target audio like this:

-- first two channels are reserved for sound track -- so find a free channel after that to play audio local fc = audio.findFreeChannel(2) buzzerAudioPlay = audio.play(buzzerAudio, { channel=fc})

I used the same approach to resolve scenario 2. In Particle Candy, you can pass a sound settings table to ‘SetEmitterSound’. So for my fireworks, the line:

Particles.SetEmitterSound("EmLauncher" , fireworks.SndLaunch)

became as follows:

local fc1 = audio.findFreeChannel(2) Particles.SetEmitterSound("EmLauncher" , fireworks.SndLaunch, 0, false, { channel=fc1})

and that did the trick.

Again, many thanks for your help.