Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
Dekerta
Posts: 80
Registered: ‎11-25-2010
My Device: 9700
My Carrier: Rogers
Accepted Solution

How to (correctly) play sounds in games?

[ Edited ]

Hi there,

 

What is the correct way to play a sound effect in a game (or any app using a looping thread). I use a method which works fine on 99% of phones, but it seems to cause a small number of my customer's phones to freeze after a few sounds play (I assume this is some kind of memory leak). I've also noticed that it creates an error in my event log (StreamingException: Session not opened in net.rim.device.internal.streamingnatives), even when the game continues to work normally.

 

Obviously something is wrong, but I can't figure out what it is. Here's the code I am using:

 

SoundObject.java:

public class SoundObject {
	Player player;
	VolumeControl vc;

	public SoundObject(String res) {
		Class cl = null;
		try {
			cl = Class.forName("my class path goes here");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}


		InputStream input = null;
		try {
			input = cl.getResourceAsStream(res);
			player = Manager.createPlayer(input,"audio/mpeg");
			player.realize();
			player.prefetch();
			vc = (VolumeControl) player.getControl("VolumeControl");
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				if(input != null){
					input.close();
					input = null;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void setVolume(int val){
		try{
			if(this.vc != null){
				vc.setLevel(val);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	public void Play(){
		if(Settings.getSoundVolume() == 0) return;
		try {
			if(player != null){
				player.stop();
			}
			player.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

To load the sound I do this:

public static SoundObject sound_boing = new SoundObject("/boing.mp3");
sound_boing.setVolume(50);

 

And in my game thread, I play the sound like this:

sound_boing.Play();

 

Can anyone tell me what I'm doingwrong? Does this code cause a memory leak? Is there a particular format of audio file that I should avoid? What could be causing the StreamingException: Session not opened error?

 

Thanks!

 

 

__________________________________________________
If my post helped you, make sure to give me kudos by clicking the star below my name! :smileyhappy:
Please use plain text.
BlackBerry Development Advisor (Retired)
BlackBerry Development Advisor (Retired)
BVP
Posts: 150
Registered: ‎10-19-2010
My Device: Not Specified
My Carrier: Rogers

Re: How to (correctly) play sounds in games?

Hi Dekerta!

 

If I am reading your code correctly you are creating an InputStream to a sound file, and then closing that stream before you play it which would seem to be the problem.  The prefetch call below will read from the InputStream and pre-load the Player with data - if the file is quite small (which I'm assuimg yours is) then this may in fact read the entire file from the stream. 

 

The key point that you don't know is that this loading is done asynchronously.  Since you close the stream in your finally block you are introducing a race condition - if the finally is run before the player is prefetched then you will get the Exception you see (the stream is not open because you closed it).  If the player finishes prefetching before you close the stream then the sound will play, which appears to be the case 99% of the time :smileywink:.

 

Rather than close the stream immediately, why not keep it open until the Player becomes closed.  That way it is always available to the Player and becomes unavailable when you can guarantee that the Player no longer needs it.  You can save it to a field in your SoundObject and close it in a PlayerListener implementation when you get the PlayerListener.CLOSED event.

 

As an alternative approach to playing 'one-off' sounds, check out the sample in this post.  It's optimized to work for both CDMA-based and GSM-based devices universally, while keeping resource usage as minimal as possible and clean-up as efficient as possible.  The only other approach I've used that works well is to mix your own sounds, but I won't get into that here since it's an entire topic in itself (although the DEV04 session from last years' DevCon2010 conference tells you how... just sayin' :Whistling:).

Please use plain text.