Hello everyone,
I came across a problem using midi sound playback with j2me on Series 60 phones.
I am using the
- javax.microedition.media.*;
- javax.microedition.media.control.*;
packages.
Inside the game I want to switch the sound that is currently playing to another sound (e.g. when in fight mode, a more dramatic sound should play).
Now the problem is, after switching sound playbacl for a couple of times, I will not be able to playback a sound again. No exception or such, all code is executed properly but no sound is heard.
I discovered that the problem is somehow related to the maximum number of times a player can aquire exclusive resources (calling prefetch or start).
Though I call deallocate() before I start playback of another sound, it seems the resources are NOT freed.
After EXACTLY 16 times of doing
1.) stopping + deallocating old sound playbacl
2.) prefetching + starting new sound playack
The playback will result in no sound you can hear.
The volume is set properly each time. The above is true for the emulator as it is for physical devices such as the Nokia N-Gage.
If you have any input on this, I would be very thankful!
Kind regards,
J. Papke
--------------
--------------
Some details:
- I tried using multiple players making sure only one at a time will have aquired exclusive ressources. Each player is initialized with an input stream at the very beginning of the game.
It still seems stop() / deallocate() + prefetch() / start() will not work more than the stated 16 times.
- In contrast to that, I also tried using only one Player object which will be created anew using Manager.createPlayer(..). once I change the sound. (See the code for this below)
- I never receive any events like DEVICE_UNAVAILABLE, using a player listener.
- I tried many things such as omitting prefetch() or waiting certain amounts of time/frames before starting a new sound etc.
I also assured being in the correct states at any time and did lots of debug output and exception tracking, but no success.
This is some of the code I use for stopping the current sound and starting the new sound (all using one player, I disabled volume stuff to keep things simpler):
// ### IN THE GAME:
// ### by calling initSound(), the player is stopped and closed,
// ### a new player is then created
// ### startSound() will prefetch and start
//...
if (soundPossible) {
soundPlayer = new GSoundTools();
}
//...
soundPlayer.initSound(soundStreams[nextSound]);
soundPlayer.startSound(-1, curSoundVolume);
//...
// ### IN CLASS GSoundTools:
/**
* The player for MIDI files.
*/
public Player midiPlayer;
/**
* The volume control for the player.
*/
public VolumeControl volume;
public GSoundTools() {
}
/**
* Initializes a player and a volume control.
*/
public synchronized void initSound(InputStream is) {
try {
if(midiPlayer != null) {
midiPlayer.stop();
midiPlayer.setMediaTime(0);
midiPlayer.close();
midiPlayer = null;
System.gc();
}
is.reset();
midiPlayer = Manager.createPlayer(is, "audio/midi");
midiPlayer.realize();
//volume = (VolumeControl)midiPlayer.getControl("javax.microedition.media.control.VolumeControl");
} catch(Exception e) {
System.out.println(e.toString());
}
}
/**
* Starts and plays a sound with the amount of loops. -1 is infinite.
*/
public synchronized boolean startSound(int loops, int level) {
if (midiPlayer==null) {
return false;
}
try {
if (midiPlayer.getState() == Player.STARTED) {
midiPlayer.stop();
}
if (midiPlayer.getState() == Player.PREFETCHED) {
midiPlayer.deallocate();
}
System.gc();
midiPlayer.prefetch();
midiPlayer.setMediaTime(0);
midiPlayer.setLoopCount(loops);
midiPlayer.start();
} catch (Exception e) {
System.out.println(e);
return false;
}
return true;
}

Reply With Quote

