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) {
if (trackExists()) {
trackEnded = false;
if (loop)
player.loop();
else

View File

@ -49,6 +49,9 @@ public class Music {
/** The music currently being played or null if none */
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
* 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
*/
public static void poll(int delta) {
if (currentMusic != null) {
SoundStore.get().poll(delta);
if (!SoundStore.get().isMusicPlaying()) {
if (!currentMusic.positioning && !currentMusic.playing) {
Music oldMusic = currentMusic;
currentMusic = null;
oldMusic.fireMusicEnded();
synchronized (musicLock) {
if (currentMusic != null) {
SoundStore.get().poll(delta);
if (!SoundStore.get().isMusicPlaying()) {
if (!currentMusic.positioning) {
Music oldMusic = currentMusic;
currentMusic = null;
oldMusic.fireMusicEnded();
}
} else {
currentMusic.update(delta);
}
} else {
currentMusic.update(delta);
}
}
}
@ -155,7 +160,9 @@ public class Music {
try {
if (ref.toLowerCase().endsWith(".ogg") || ref.toLowerCase().endsWith(".mp3")) {
if (streamingHint) {
sound = SoundStore.get().getOggStream(url);
synchronized (musicLock) {
sound = SoundStore.get().getOggStream(url);
}
} else {
sound = SoundStore.get().getOgg(url.openStream());
}
@ -187,7 +194,12 @@ public class Music {
try {
if (ref.toLowerCase().endsWith(".ogg") || ref.toLowerCase().endsWith(".mp3")) {
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 {
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
*/
private void startMusic(float pitch, float volume, boolean loop) {
if (currentMusic != null) {
currentMusic.stop();
currentMusic.fireMusicSwapped(this);
}
if (volume < 0.0f)
volume = 0.0f;
if (volume > 1.0f)
volume = 1.0f;
playing = true;
currentMusic = this;
sound.playAsMusic(pitch, volume, loop);
setVolume(volume);
if (requiredPosition != -1) {
setPosition(requiredPosition);
synchronized (musicLock) {
if (currentMusic != null) {
currentMusic.stop();
currentMusic.fireMusicSwapped(this);
}
if (volume < 0.0f)
volume = 0.0f;
if (volume > 1.0f)
volume = 1.0f;
playing = true;
currentMusic = this;
sound.playAsMusic(pitch, volume, loop);
setVolume(volume);
if (requiredPosition != -1) {
setPosition(requiredPosition);
}
}
}
@ -317,7 +331,10 @@ public class Music {
* Stop the music playing
*/
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
*/
public boolean setPosition(float position) {
if (playing) {
requiredPosition = -1;
positioning = true;
playing = false;
boolean result = sound.setPosition(position);
playing = true;
positioning = false;
return result;
} else {
requiredPosition = position;
return false;
synchronized (musicLock) {
if (playing) {
requiredPosition = -1;
positioning = true;
playing = false;
boolean result = sound.setPosition(position);
playing = true;
positioning = false;
return result;
} else {
requiredPosition = position;
return false;
}
}
}

View File

@ -36,6 +36,7 @@ import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.openal.AL10;
import org.lwjgl.openal.OpenALException;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.util.Log;
import org.newdawn.slick.util.ResourceLoader;
@ -67,7 +68,7 @@ public class OpenALStreamPlayer {
private int remainingBufferCount;
/** True if we should loop the track */
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;
/** The stream we're currently reading from */
private AudioInputStream audio;
@ -158,6 +159,7 @@ public class OpenALStreamPlayer {
sampleSize = 2; // AL10.AL_FORMAT_MONO16
// positionOffset = 0;
streamPos = 0;
playedPos = 0;
}
@ -180,6 +182,10 @@ public class OpenALStreamPlayer {
while (AL10.alGetSourcei(source, AL10.AL_BUFFERS_QUEUED) > 0) {
AL10.alSourceUnqueueBuffers(source, buffer);
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
* @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;
initStreams();
@ -261,6 +268,10 @@ public class OpenALStreamPlayer {
if (state != AL10.AL_PLAYING) {
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;
try {
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) {
Log.error("Failed to loop buffer: "+bufferId+" "+format+" "+count+" "+audio.getRate(), e);
return false;

View File

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