- memory leak
I found memory problem while using jme sound streaming.
http://www.jmonkeyengine.com/jmeforum/index.php?topic=10835.0
Maybe we could fix it by cleaning up OpenAL buffers but I couldn't find the solution.
I suggest another approach which reuses OpenAL buffers.
In this approach, we should call AudioTrack.release() when the track is not used anymore. (for streaming source)
It can be done by TrackStateListener
- OpenALExceptions
Current implementation uses same pool for memory source and stream source.
So when we use memory player and stream player at once it throws OpenALException.
I split it with two source pool.
patch file
http://mulova.tistory.com/attachment/cfile5.uf@165F15234A08C48E267F4E.patch
Test Code (without sound file)
package test;
import java.net.URL;
import com.jme.app.SimpleGame;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jmex.audio.AudioSystem;
import com.jmex.audio.AudioTrack;
import com.jmex.audio.AudioTrack.TrackType;
public class TestOggStreaming extends SimpleGame {
private static final String MEMORY = "Memory";
private static final String STREAM_STOP = "Stream Stop";
private static final String STREAM = "Stream";
private int c;
private AudioSystem audio;
private AudioTrack streamTrack;
private String[] paths;
@Override
protected void simpleInitGame() {
paths = new String[10];
for (int i = 0; i < paths.length; i++) {
paths[i] = "/test/"+i+").ogg";
}
KeyBindingManager.getKeyBindingManager().add(STREAM_STOP, KeyInput.KEY_1);
KeyBindingManager.getKeyBindingManager().add(STREAM, KeyInput.KEY_2);
KeyBindingManager.getKeyBindingManager().add(MEMORY, KeyInput.KEY_3);
audio = AudioSystem.getSystem();
}
@Override
protected void simpleUpdate() {
if(KeyBindingManager.getKeyBindingManager().isValidCommand(STREAM_STOP, false)) {
play(true, true);
} else if(KeyBindingManager.getKeyBindingManager().isValidCommand(STREAM, false)) {
play(true, false);
} else if(KeyBindingManager.getKeyBindingManager().isValidCommand(MEMORY, false)) {
play(false, false);
}
audio.update();
}
private void play(boolean stream, boolean stop) {
if (c >= paths.length) {
c = 0;
}
URL url = TestOggStreaming.class.getResource(paths[c]);
if (stream) {
if (streamTrack != null && stop) {
streamTrack.stop();
streamTrack.release();
}
streamTrack = getSFX(url, stream);
streamTrack.play();
} else {
AudioTrack memoryTrack = getSFX(url, stream);
memoryTrack.play();
}
c++;
}
private AudioTrack getSFX(URL resource, boolean stream) {
audio = AudioSystem.getSystem();
// final boolean stream = FastMath.rand.nextBoolean();
AudioTrack sound = audio.createAudioTrack(resource, stream);
sound.setType(TrackType.MUSIC);
sound.setVolume(1f);
sound.setRelative(false);
sound.setLooping(false);
return sound;
}
public static void main(String[] args) {
TestOggStreaming app = new TestOggStreaming();
app.start();
}
}