From 7ac3aeda651e693372f33234548cc4afb3f91ec4 Mon Sep 17 00:00:00 2001
From: Lyubomir Marinov <lyubomir.marinov@jitsi.org>
Date: Thu, 1 Aug 2013 01:08:51 +0300
Subject: [PATCH] Addresses issues with hotplugging and playback device
 selections during calls in the Windows Audio Session API (WASAPI) integration
 when acoustic echo cancellation (AEC) is enabled.

---
 .../media/protocol/wasapi/WASAPIStream.java   | 26 ++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/wasapi/WASAPIStream.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/wasapi/WASAPIStream.java
index 94353ecc..eb4993d6 100644
--- a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/wasapi/WASAPIStream.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/wasapi/WASAPIStream.java
@@ -2197,8 +2197,21 @@ private synchronized void propertyChange(PropertyChangeEvent ev)
          * The propertyChangeListener this invokes the method will be added only
          * when acoustic echo cancellation (AEC) is enabled. 
          */
+        String propertyName = ev.getPropertyName();
+        boolean renderDeviceDidChange;
 
-        if (DeviceSystem.PROP_DEVICES.equals(ev.getPropertyName()))
+        if (DeviceSystem.PROP_DEVICES.equals(propertyName))
+        {
+            /*
+             * Testing shows that the acoustic echo cancellation (AEC) feature
+             * may fail to actually cancel echo if a device is unplugged even if
+             * it was not in use by this instance prior to the unplugging.
+             * Unfortunately, even re-initializing the voice capture DSP may not
+             * save the AEC from failing to actual cancel the echo.
+             */
+            renderDeviceDidChange = true;
+        }
+        else if (PlaybackDevices.PROP_DEVICE.equals(propertyName))
         {
             MediaLocator oldRenderDevice = this.renderDevice;
             WASAPISystem audioSystem = dataSource.audioSystem;
@@ -2226,10 +2239,17 @@ private synchronized void propertyChange(PropertyChangeEvent ev)
                                 newRenderDevice.getRemainder(),
                                 eRender);
 
-                if (oldRenderDeviceIndex == newRenderDeviceIndex)
-                    return;
+                renderDeviceDidChange
+                    = (oldRenderDeviceIndex != newRenderDeviceIndex);
             }
+            else
+                renderDeviceDidChange = true;
+        }
+        else
+            renderDeviceDidChange = false;
 
+        if (renderDeviceDidChange)
+        {
             /*
              * If there are changes either to the MediaLocators or to the
              * indexes within the IMMDeviceCollection interface, re-connect this
-- 
GitLab