PlaySound crash

Monkey Targets Forums/Android/PlaySound crash

siread(Posted 2012) [#1]
I have my own function to play sounds to ensure that the sample is loaded...
Function PlayMySound(snd:Sound, chn:Int = 0, flags:Int = 0)
	If Not snd Then Print "Could not play sound!"; Return
	
	PlaySound(snd, chn, flags)
End

However, it seems on certain phones a sound file that has been loaded can suddenly fail to play and crash the app. Occasionally I get a Monkey runtime error "PlaySample failed to play sound" (audio.monkey <69>). This has happened to me on a Samsung Galaxy S but I've also had customers complaining of Monkey sound errors occurring at random. Any ideas?


muddy_shoes(Posted 2012) [#2]
Internally, that error message is thrown after just repeatedly trying to play the sample a hundred times. That doesn't help much in terms of why it's failing but it doesn't seem like erroring the whole app is necessary just for the sake of one sound failing to play (or even all the sound).

I'd be tempted to remove the error and see about returning a failure code and possibly trying to reload the sound.


siread(Posted 2012) [#3]
Okay, so it's this code in mojo.android.java...
//Ugly as hell, but seems to work for now...pauses 10 secs max...
		for( int i=0;i<100;++i ){
			chan.stream=pool.play( sample.sound,lv,rv,0,loops,chan.rate );
			if( chan.stream!=0 ){
				chan.state=1;
				return 0;
			}

			try{
				Thread.sleep( 100 );
			}catch( java.lang.InterruptedException ex ){
			}
		}
		throw new Error( "PlaySample failed to play sound" );


So it tries 100 times to play a sample and if it fails it throws an error. I'd rather the sound simply didn't play at all than crash the app. Most sounds are loaded as and when they are needed, so it will barely be noticed if one fails to play. I'll try commenting out the try/catch/throw stuff...


secondgear(Posted 2012) [#4]
Mark, if you're reading this:

I'd also vote for removing the 100x loop. I'd rather live with the game working without sound, than the game throwing an error message after a long delay.

In my experience, some Android devices have problems with some mp3 sound effects. 100 attempts to play them doesn't help. I had this problem with Logitech Revue and with BlackBerry PlayBook. Replacing mp3s with oggs solved the problem.


siread(Posted 2012) [#5]
I'm using oggs here and they can still fail. Since removing that loop and try/catch/fail I have noticed very occasionally that a sound fails but no crash so that's good.


frank(Posted 2013) [#6]
This is still the case and it still doesn't work. Does anyone know what the problem is? Some ogg/mp3 sounds do play, some do not. On my Galaxy S2/S3 they just don't play but the game works fine (and other sounds do too), on Nexus 4/7 the game crashes entirely with the above exception. I think none of these things is correct/acceptable but I know too little about why it happens. Anyone have a clue ?

I also have random 'stalls' with my games on Android which are related to sound; if I load a few sounds in a row the app is 'stuck' (OS reports that it's stuck) ; when I debug it, it works fine because then they don't load 'in a row' but further apart which seems to be the problem.

Edit: Nexus 7 doesn't want to play any sound in Monkey and thus crashes on the thrown error in PlaySample.


Midimaster(Posted 2013) [#7]
I never had problems in playing my sounds a android. Tested on 2.3 upto 4.2, also Nexus. The sound files are always recorded on audacity with stereo 44100 Hz and 32bit float, then exported to OGG files stereo on compression level 2.

In monkey I load the sound sources asynchron and wait for loading the next until the last has called back success. The app is waiting in a splash screen until all sound sources are loaded. I often play a lot of sounds together, but never the same sound twice at the same time. But in test I had only problems in HTML5 when doing that...

The sound sources are stored in an array and all fired sound will be stored in a TList to control them later. Each fired sound gets its independent Channel:

Class MySound Implements IOnLoadSoundComplete

	Global ChannelStep%=0
	Global Liste:List<MySound> = New List<MySound>
	Field Channel%,ChannelTimer%

	Function PlayOne:Void(Id%)
		ChannelStep=(ChannelStep+1)Mod 8
		StopChannel ChannelStep

		Local loc:MySound = New MySound
		loc.Channel=ChannelStep
		loc.ChannelTimer=Millisecs()
		Liste.AddLast loc

		SetChannelVolume ChannelStep,1
		PlaySound MyOgg[Id],ChannelStep
	End
	...


So I assume it has to do something with your code o with your sound files.


frank(Posted 2013) [#8]
That would not explain why it works fine on S2 and S3 and not on Nexus 7 with the same code. Nor does it explain while the entire internet is crying that SoundPool sucks and is unreliable :)

Anyway; first of all that loop wich is in the Monkey PlaySample code now blocks the UI thread, so I suggest replacing that with https://gist.github.com/tluyben/5472601 . I did and that's a whole lot nicer.

Then secondly; how do you you know if they have finished loading? When LoadSound was executed (it finished then obviously) executing PlaySound generates n times "Sample x not ready" (which, if you Google SoundPool is why everyone is crying about it). On the S2/S3 it shows it a few times, on Nexus 7 it shows it 100x and then doesn't play the sound.

My files are indeed 44.1kHz, 32 bit and compression level 2. They are also VERY small/short which is apparently the only thing SoundPool can do. Yet they work on S2/S3, not on Nexus 7 and I just tested Nexus 10 ; same issue.

So maybe if you can show me how you 'wait' for them ; maybe that's the solution.


Midimaster(Posted 2013) [#9]
It did not want to explain anything, why yours is not working... I only want to tell you, that there is a way working without problems on all this devices....

SoundPool? What's that? UI thread? What? Internet crying? What exactly are you doing?



I published an article about this async sound loading a few days ago:

moment...


frank(Posted 2013) [#10]
I'm not saying you are :)

SoundPool is the thing which plays the sound for you in Android, if you Google things like:

Android Soundpool not working
Android Soundpool sample not ready

you get 1000s of results of people not getting it to work or working only flaky.

If you have resolved it, I think it should go into Monkey or at least in a module because it seems a lot of people are struggling with it in the Android world and some just never get it done and revert to tricks with the Android MediaPlayer class (which actually always works).


Midimaster(Posted 2013) [#11]
here is the link:

http://www.monkeycoder.co.nz/Community/post.php?topic=4306&post=54733


frank(Posted 2013) [#12]
Thanks ; going to try that now! (didn't know there were Async commands actually)

Edit: Actually I think soundpool always loads async so although Monkey makes you think this is not happening (by immediately returning) is an issue; I think this should happen 'under the hood' or be renamed. It seems in other platforms (the ones I tried at least) it's correct.


frank(Posted 2013) [#13]
Cool managed to get it working indeed! I used your method and it still didn't work; after some more reading, I made the sound files as tiny as I could with Audacity. After some (?) threshold of a few kb per file it suddenly worked.

Still think that 100-play-try loop should go into a thread though.


Midimaster(Posted 2013) [#14]
ah...

under android 2.xx monkey's LoadSound() waited until the sound was aviable. Under 4.xx it returned immediately, which causes problems when try to play the sound.


because I never had problems with sounds, I never heard about SoundPool and your 100-play-try-problem...

What do youz mean with "as tiny as"? What size had the sounds before? How did you shrink them now?

But perhaps my user did not tell me about missing sounds? ... upps... I will start an survey about this...

so I now have to relativate my statement, that everything works fine...

I will call back with results in some days...


frank(Posted 2013) [#15]
Well maybe it does work fine for you, but I'm a native iOS/Android dev by trade so I debug what is happening in Java/Dalvik in this case. And when it cannot play a sound it will wait for 10 secs (blocking everything, making Android upset :) and then crash the app. That is very undesired behavior and it has been asked before to remove that (the throw Error). If you run it in a separate Thread and don't throw the Error it is fine and a minor issue. Now it's instable/app crashing behavior.

One of the sound files was over 100k ; I used Audacity compression to get it to 15k and didn't really hear the difference :) And then it worked. Still Gooooogle needs to work on their bloody error messages...


slenkar(Posted 2015) [#16]
after getting a new tablet I just ran into this issue
I inserted the async code into android.mojo.java and now the game doesnt crash.

None of the sounds play at all though, Ill try shrinking them or should I convert them to ogg?

EDIT-
I converted them to ogg and changed the large files to soundquality:1
and now everything works ;)