Sfoglia il codice sorgente

Restart audio context if current device is "disconnected" (#1593)

* Restart audio context if current device is "disconnected"

* Better method name
Toni Helenius 4 anni fa
parent
commit
edc7cdee87

+ 31 - 4
jme3-core/src/main/java/com/jme3/audio/openal/ALAudioRenderer.java

@@ -33,10 +33,10 @@ package com.jme3.audio.openal;
 
 import com.jme3.audio.*;
 import com.jme3.audio.AudioSource.Status;
+import static com.jme3.audio.openal.AL.*;
 import com.jme3.math.Vector3f;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.NativeObjectManager;
-
 import java.nio.ByteBuffer;
 import java.nio.FloatBuffer;
 import java.nio.IntBuffer;
@@ -44,8 +44,6 @@ import java.util.ArrayList;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import static com.jme3.audio.openal.AL.*;
-
 public class ALAudioRenderer implements AudioRenderer, Runnable {
 
     private static final Logger logger = Logger.getLogger(ALAudioRenderer.class.getName());
@@ -70,6 +68,7 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
     private boolean audioDisabled = false;
     private boolean supportEfx = false;
     private boolean supportPauseDevice = false;
+    private boolean supportDisconnect = false;
     private int auxSends = 0;
     private int reverbFx = -1;
     private int reverbFxSlot = -1;
@@ -146,7 +145,11 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
         if (!supportPauseDevice) {
             logger.log(Level.WARNING, "Pausing audio device not supported.");
         }
-        
+
+        // Disconnected audio devices (such as USB sound cards, headphones...)
+        // never reconnect, the whole context must be re-created
+        supportDisconnect = alc.alcIsExtensionPresent("ALC_EXT_disconnect");
+
         supportEfx = alc.alcIsExtensionPresent("ALC_EXT_EFX");
         if (supportEfx) {
             ib.position(0).limit(1);
@@ -250,6 +253,7 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
             }
 
             synchronized (threadLock) {
+                checkDevice();
                 updateInDecoderThread(UPDATE_RATE);
             }
 
@@ -858,6 +862,29 @@ public class ALAudioRenderer implements AudioRenderer, Runnable {
         }
     }
 
+    private void checkDevice() {
+
+        // If the device is disconnected, pick a new one
+        if (isDisconnected()) {
+            logger.log(Level.INFO, "Current audio device disconnected.");
+            restartAudioRenderer();
+        }
+    }
+
+    private boolean isDisconnected() {
+        if (!supportDisconnect) {
+            return false;
+        }
+
+        alc.alcGetInteger(ALC.ALC_CONNECTED, ib, 1);
+        return ib.get(0) == 0;
+    }
+
+    private void restartAudioRenderer() {
+        destroyOpenAL();
+        initOpenAL();
+    }
+
     public void updateInRenderThread(float tpf) {
         if (audioDisabled) {
             return;

+ 1 - 0
jme3-core/src/main/java/com/jme3/audio/openal/ALC.java

@@ -61,6 +61,7 @@ public interface ALC {
     public static final int ALC_ALL_DEVICES_SPECIFIER = 0x1013;
 
     //public static ALCCapabilities createCapabilities(long device);
+    public static final int ALC_CONNECTED = 0x313;
 
     /**
      * Creates an AL context.