Fixed various assertion errors in audio renderer

Added additional assertions and other checks where appropriate
experimental
shadowislord 10 years ago
parent 9ce69eee62
commit 9e02ef0d5d
  1. 65
      jme3-core/src/main/java/com/jme3/audio/openal/ALAudioRenderer.java

@ -662,6 +662,10 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
if (!active && looping) { if (!active && looping) {
stream.setTime(0); stream.setTime(0);
active = fillBuffer(stream, buffer); active = fillBuffer(stream, buffer);
if (!active) {
throw new IllegalStateException("Looping streaming source " +
"was rewinded but could not be filled");
}
} }
if (active) { if (active) {
@ -679,7 +683,7 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
return success; return success;
} }
private boolean attachStreamToSource(int sourceId, AudioStream stream, boolean looping) { private void attachStreamToSource(int sourceId, AudioStream stream, boolean looping) {
boolean success = false; boolean success = false;
// Reset the stream. Typically happens if it finished playing on // Reset the stream. Typically happens if it finished playing on
@ -698,6 +702,10 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
if (!active && looping) { if (!active && looping) {
stream.setTime(0); stream.setTime(0);
active = fillBuffer(stream, id); active = fillBuffer(stream, id);
if (!active) {
throw new IllegalStateException("Looping streaming source " +
"was rewinded but could not be filled");
}
} }
if (active) { if (active) {
ib.position(0).limit(1); ib.position(0).limit(1);
@ -706,7 +714,11 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
success = true; success = true;
} }
} }
return success;
if (!success) {
// should never happen
throw new IllegalStateException("No valid data could be read from stream");
}
} }
private boolean attachBufferToSource(int sourceId, AudioBuffer buffer) { private boolean attachBufferToSource(int sourceId, AudioBuffer buffer) {
@ -714,13 +726,14 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
return true; return true;
} }
private boolean attachAudioToSource(int sourceId, AudioData data, boolean looping) { private void attachAudioToSource(int sourceId, AudioData data, boolean looping) {
if (data instanceof AudioBuffer) { if (data instanceof AudioBuffer) {
return attachBufferToSource(sourceId, (AudioBuffer) data); attachBufferToSource(sourceId, (AudioBuffer) data);
} else if (data instanceof AudioStream) { } else if (data instanceof AudioStream) {
return attachStreamToSource(sourceId, (AudioStream) data, looping); attachStreamToSource(sourceId, (AudioStream) data, looping);
} else {
throw new UnsupportedOperationException();
} }
throw new UnsupportedOperationException();
} }
private void clearChannel(int index) { private void clearChannel(int index) {
@ -786,6 +799,21 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
boolean reclaimChannel = false; boolean reclaimChannel = false;
Status oalStatus = convertStatus(al.alGetSourcei(sourceId, AL_SOURCE_STATE)); Status oalStatus = convertStatus(al.alGetSourcei(sourceId, AL_SOURCE_STATE));
if (!boundSource) {
// Rules for instanced playback vary significantly.
// Handle it here.
if (oalStatus == Status.Stopped) {
// Instanced audio stopped playing. Reclaim channel.
clearChannel(i);
freeChannel(i);
} else if (oalStatus == Status.Paused) {
throw new AssertionError("Instanced audio cannot be paused");
}
continue;
}
Status jmeStatus = src.getStatus(); Status jmeStatus = src.getStatus();
// Check if we need to sync JME status with OAL status. // Check if we need to sync JME status with OAL status.
@ -806,25 +834,31 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
} }
} else { } else {
// Buffer finished playing. // Buffer finished playing.
reclaimChannel = true; if (src.isLooping()) {
throw new AssertionError("Unexpected state: " +
"A looping sound has stopped playing");
} else {
reclaimChannel = true;
}
} }
if (reclaimChannel) { if (reclaimChannel) {
if (boundSource) { src.setStatus(Status.Stopped);
src.setStatus(Status.Stopped); src.setChannel(-1);
src.setChannel(-1);
}
clearChannel(i); clearChannel(i);
freeChannel(i); freeChannel(i);
} }
} else { } else {
// jME3 state does not match OAL state. // jME3 state does not match OAL state.
throw new AssertionError(); // This is only relevant for bound sources.
throw new AssertionError("Unexpected sound status. "
+ "OAL: " + oalStatus
+ ", JME: " + jmeStatus);
} }
} else { } else {
// Stopped channel was not cleared correctly. // Stopped channel was not cleared correctly.
if (oalStatus == Status.Stopped) { if (oalStatus == Status.Stopped) {
throw new AssertionError(); throw new AssertionError("Channel " + i + " was not reclaimed");
} }
} }
} }
@ -860,6 +894,11 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
al.alSourcePlay(sourceId); al.alSourcePlay(sourceId);
} else { } else {
// Buffers were filled, stream continues to play. // Buffers were filled, stream continues to play.
if (oalStatus == Status.Playing && jmeStatus == Status.Playing) {
// Nothing to do.
} else {
throw new AssertionError();
}
} }
} }
} }

Loading…
Cancel
Save