Преглед изворни кода

Fixed various assertion errors in audio renderer
Added additional assertions and other checks where appropriate

shadowislord пре 10 година
родитељ
комит
9e02ef0d5d
1 измењених фајлова са 53 додато и 14 уклоњено
  1. 53 14
      jme3-core/src/main/java/com/jme3/audio/openal/ALAudioRenderer.java

+ 53 - 14
jme3-core/src/main/java/com/jme3/audio/openal/ALAudioRenderer.java

@@ -652,7 +652,7 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
             ib.position(0).limit(1);
             ib.position(0).limit(1);
             al.alSourceUnqueueBuffers(sourceId, 1, ib);
             al.alSourceUnqueueBuffers(sourceId, 1, ib);
             buffer = ib.get(0);
             buffer = ib.get(0);
-
+            
             boolean active = fillBuffer(stream, buffer);
             boolean active = fillBuffer(stream, buffer);
             
             
             if (!active && !stream.isEOF()) {
             if (!active && !stream.isEOF()) {
@@ -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.setChannel(-1);
-                        }
+                        src.setStatus(Status.Stopped);
+                        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();
+                    }
                 }
                 }
             }
             }
         }
         }