Fixes Music Ended (hopefully)

This commit is contained in:
fd 2015-02-21 20:14:48 -05:00
parent 00b98e07d6
commit 2825f4c885
4 changed files with 79 additions and 44 deletions

View File

@ -252,6 +252,7 @@ public class MusicController {
*/ */
public static void play(boolean loop) { public static void play(boolean loop) {
if (trackExists()) { if (trackExists()) {
trackEnded = false;
if (loop) if (loop)
player.loop(); player.loop();
else else

View File

@ -49,6 +49,9 @@ public class Music {
/** The music currently being played or null if none */ /** The music currently being played or null if none */
private static Music currentMusic; private static Music currentMusic;
/** The lock object for synchronized modification to Music*/
private static Object musicLock = new Object();
/** /**
* Poll the state of the current music. This causes streaming music * Poll the state of the current music. This causes streaming music
* to stream and checks listeners. Note that if you're using a game container * to stream and checks listeners. Note that if you're using a game container
@ -57,16 +60,18 @@ public class Music {
* @param delta The amount of time since last poll * @param delta The amount of time since last poll
*/ */
public static void poll(int delta) { public static void poll(int delta) {
if (currentMusic != null) { synchronized (musicLock) {
SoundStore.get().poll(delta); if (currentMusic != null) {
if (!SoundStore.get().isMusicPlaying()) { SoundStore.get().poll(delta);
if (!currentMusic.positioning && !currentMusic.playing) { if (!SoundStore.get().isMusicPlaying()) {
Music oldMusic = currentMusic; if (!currentMusic.positioning) {
currentMusic = null; Music oldMusic = currentMusic;
oldMusic.fireMusicEnded(); currentMusic = null;
oldMusic.fireMusicEnded();
}
} else {
currentMusic.update(delta);
} }
} else {
currentMusic.update(delta);
} }
} }
} }
@ -155,7 +160,9 @@ public class Music {
try { try {
if (ref.toLowerCase().endsWith(".ogg") || ref.toLowerCase().endsWith(".mp3")) { if (ref.toLowerCase().endsWith(".ogg") || ref.toLowerCase().endsWith(".mp3")) {
if (streamingHint) { if (streamingHint) {
sound = SoundStore.get().getOggStream(url); synchronized (musicLock) {
sound = SoundStore.get().getOggStream(url);
}
} else { } else {
sound = SoundStore.get().getOgg(url.openStream()); sound = SoundStore.get().getOgg(url.openStream());
} }
@ -187,7 +194,12 @@ public class Music {
try { try {
if (ref.toLowerCase().endsWith(".ogg") || ref.toLowerCase().endsWith(".mp3")) { if (ref.toLowerCase().endsWith(".ogg") || ref.toLowerCase().endsWith(".mp3")) {
if (streamingHint) { if (streamingHint) {
sound = SoundStore.get().getOggStream(ref); synchronized (musicLock) {
//getting a stream ends the current stream....
//which may cause a MusicEnded instead of of MusicSwap
//Not that it really matters for MusicController use
sound = SoundStore.get().getOggStream(ref);
}
} else { } else {
sound = SoundStore.get().getOgg(ref); sound = SoundStore.get().getOgg(ref);
} }
@ -286,22 +298,24 @@ public class Music {
* @param loop if false the music is played once, the music is looped otherwise * @param loop if false the music is played once, the music is looped otherwise
*/ */
private void startMusic(float pitch, float volume, boolean loop) { private void startMusic(float pitch, float volume, boolean loop) {
if (currentMusic != null) { synchronized (musicLock) {
currentMusic.stop(); if (currentMusic != null) {
currentMusic.fireMusicSwapped(this); currentMusic.stop();
} currentMusic.fireMusicSwapped(this);
}
if (volume < 0.0f)
volume = 0.0f; if (volume < 0.0f)
if (volume > 1.0f) volume = 0.0f;
volume = 1.0f; if (volume > 1.0f)
volume = 1.0f;
playing = true;
currentMusic = this; playing = true;
sound.playAsMusic(pitch, volume, loop); currentMusic = this;
setVolume(volume); sound.playAsMusic(pitch, volume, loop);
if (requiredPosition != -1) { setVolume(volume);
setPosition(requiredPosition); if (requiredPosition != -1) {
setPosition(requiredPosition);
}
} }
} }
@ -317,7 +331,10 @@ public class Music {
* Stop the music playing * Stop the music playing
*/ */
public void stop() { public void stop() {
sound.stop(); synchronized (musicLock) {
playing = false;
sound.stop();
}
} }
/** /**
@ -414,19 +431,21 @@ public class Music {
* @return True if the seek was successful * @return True if the seek was successful
*/ */
public boolean setPosition(float position) { public boolean setPosition(float position) {
if (playing) { synchronized (musicLock) {
requiredPosition = -1; if (playing) {
requiredPosition = -1;
positioning = true;
playing = false; positioning = true;
boolean result = sound.setPosition(position); playing = false;
playing = true; boolean result = sound.setPosition(position);
positioning = false; playing = true;
positioning = false;
return result;
} else { return result;
requiredPosition = position; } else {
return false; requiredPosition = position;
return false;
}
} }
} }

View File

@ -36,6 +36,7 @@ import java.nio.IntBuffer;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.openal.AL10; import org.lwjgl.openal.AL10;
import org.lwjgl.openal.OpenALException; import org.lwjgl.openal.OpenALException;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.util.Log; import org.newdawn.slick.util.Log;
import org.newdawn.slick.util.ResourceLoader; import org.newdawn.slick.util.ResourceLoader;
@ -67,7 +68,7 @@ public class OpenALStreamPlayer {
private int remainingBufferCount; private int remainingBufferCount;
/** True if we should loop the track */ /** True if we should loop the track */
private boolean loop; private boolean loop;
/** True if we've completed play back */ /** True if we've completed streaming to buffer (but may not be done playing) */
private boolean done = true; private boolean done = true;
/** The stream we're currently reading from */ /** The stream we're currently reading from */
private AudioInputStream audio; private AudioInputStream audio;
@ -158,6 +159,7 @@ public class OpenALStreamPlayer {
sampleSize = 2; // AL10.AL_FORMAT_MONO16 sampleSize = 2; // AL10.AL_FORMAT_MONO16
// positionOffset = 0; // positionOffset = 0;
streamPos = 0; streamPos = 0;
playedPos = 0;
} }
@ -180,6 +182,10 @@ public class OpenALStreamPlayer {
while (AL10.alGetSourcei(source, AL10.AL_BUFFERS_QUEUED) > 0) { while (AL10.alGetSourcei(source, AL10.AL_BUFFERS_QUEUED) > 0) {
AL10.alSourceUnqueueBuffers(source, buffer); AL10.alSourceUnqueueBuffers(source, buffer);
buffer.clear(); buffer.clear();
int exc = AL10.alGetError();
if (exc != AL10.AL_NO_ERROR) {
System.out.println("removeBuffers AL ERROR, err: " + exc);
}
} }
} }
@ -189,7 +195,8 @@ public class OpenALStreamPlayer {
* @param loop True if the stream should loop * @param loop True if the stream should loop
* @throws IOException Indicates a failure to read from the stream * @throws IOException Indicates a failure to read from the stream
*/ */
public void play(boolean loop) throws IOException { public synchronized void play(boolean loop) throws IOException {
this.loop = loop; this.loop = loop;
initStreams(); initStreams();
@ -261,6 +268,10 @@ public class OpenALStreamPlayer {
if (state != AL10.AL_PLAYING) { if (state != AL10.AL_PLAYING) {
AL10.alSourcePlay(source); AL10.alSourcePlay(source);
} }
int exc = AL10.alGetError();
if (exc != AL10.AL_NO_ERROR) {
System.out.println("update AL ERROR, err: " + exc);
}
} }
/** /**
@ -282,6 +293,10 @@ public class OpenALStreamPlayer {
int format = audio.getChannels() > 1 ? AL10.AL_FORMAT_STEREO16 : AL10.AL_FORMAT_MONO16; int format = audio.getChannels() > 1 ? AL10.AL_FORMAT_STEREO16 : AL10.AL_FORMAT_MONO16;
try { try {
AL10.alBufferData(bufferId, format, bufferData, audio.getRate()); AL10.alBufferData(bufferId, format, bufferData, audio.getRate());
int exc = AL10.alGetError();
if (exc != AL10.AL_NO_ERROR) {
System.out.println("stream AL ERROR, err: " + exc);
}
} catch (OpenALException e) { } catch (OpenALException e) {
Log.error("Failed to loop buffer: "+bufferId+" "+format+" "+count+" "+audio.getRate(), e); Log.error("Failed to loop buffer: "+bufferId+" "+format+" "+count+" "+audio.getRate(), e);
return false; return false;

View File

@ -918,7 +918,7 @@ public class SoundStore {
return; return;
} }
if (this.stream != null) { if (this.stream != null && this.stream != stream) {
this.stream.close(); this.stream.close();
} }
currentMusic = sources.get(0); currentMusic = sources.get(0);