Index: /trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp	(revision 55029)
+++ /trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp	(revision 55030)
@@ -268,5 +268,5 @@
 {
     /** Host stream out. */
-    PDMAUDIOHSTSTRMOUT streamOut;
+    PDMAUDIOHSTSTRMOUT          streamOut;
     /* Stream description which is default on the device */
     AudioStreamBasicDescription deviceFormat;
@@ -274,16 +274,18 @@
     AudioStreamBasicDescription streamFormat;
     /* The audio device ID of the currently used device */
-    AudioDeviceID deviceID;
+    AudioDeviceID               deviceID;
     /* The AudioUnit used */
-    AudioUnit audioUnit;
+    AudioUnit                   audioUnit;
     /* A ring buffer for transferring data to the playback thread. */
-    PRTCIRCBUF pBuf;
+    PRTCIRCBUF                  pBuf;
     /* Temporary buffer for copying over audio data into Core Audio. */
-    void *pvPCMBuf;
+    void                       *pvPCMBuf;
     /** Size of the temporary buffer. */
-    size_t cbPCMBuf;
+    size_t                      cbPCMBuf;
     /* Initialization status tracker. Used when some of the device parameters
      * or the device itself is changed during the runtime. */
-    volatile uint32_t status;
+    volatile uint32_t           status;
+    /** Flag whether the "default device changed" listener was registered. */
+ 	bool                        fDefDevChgListReg;
 } COREAUDIOSTREAMOUT, *PCOREAUDIOSTREAMOUT;
 
@@ -291,5 +293,5 @@
 {
     /** Host stream in. */
-    PDMAUDIOHSTSTRMIN streamIn;
+    PDMAUDIOHSTSTRMIN           streamIn;
     /* Stream description which is default on the device */
     AudioStreamBasicDescription deviceFormat;
@@ -297,20 +299,22 @@
     AudioStreamBasicDescription streamFormat;
     /* The audio device ID of the currently used device */
-    AudioDeviceID deviceID;
+    AudioDeviceID               deviceID;
     /* The AudioUnit used */
-    AudioUnit audioUnit;
+    AudioUnit                   audioUnit;
     /* The audio converter if necessary */
-    AudioConverterRef converter;
+    AudioConverterRef           converter;
     /* A temporary position value used in the caConverterCallback function */
-    uint32_t rpos;
+    uint32_t                    rpos;
     /* The ratio between the device & the stream sample rate */
-    Float64 sampleRatio;
+    Float64                     sampleRatio;
     /* An extra buffer used for render the audio data in the recording thread */
-    AudioBufferList bufferList;
+    AudioBufferList             bufferList;
     /* A ring buffer for transferring data from the recording thread */
-    PRTCIRCBUF pBuf;
+    PRTCIRCBUF                  pBuf;
     /* Initialization status tracker. Used when some of the device parameters
      * or the device itself is changed during the runtime. */
-    volatile uint32_t status;
+    volatile uint32_t           status;
+    /** Flag whether the "default device changed" listener was registered. */
+ 	bool                        fDefDevChgListReg;
 } COREAUDIOSTREAMIN, *PCOREAUDIOSTREAMIN;
 
@@ -1227,4 +1231,16 @@
     if (RT_SUCCESS(rc))
     {
+        /* Allocate temporary buffer. */
+        pStreamOut->cbPCMBuf = _4K; /** @todo Make this configurable. */
+        pStreamOut->pvPCMBuf = RTMemAlloc(pStreamOut->cbPCMBuf);
+        if (!pStreamOut->pvPCMBuf)
+            rc = VERR_NO_MEMORY;
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Register callbacks.
+         */
 #ifdef DEBUG
         propAdr.mSelector = kAudioDeviceProcessorOverload;
@@ -1243,10 +1259,4 @@
         if (err != noErr)
             LogRel(("CoreAudio: Failed to register sample rate changed listener for output stream (%RI32)\n", err));
-
-        /* Allocate temporary buffer. */
-        pStreamOut->cbPCMBuf = _4K; /** @todo Make this configurable. */
-        pStreamOut->pvPCMBuf = RTMemAlloc(pStreamOut->cbPCMBuf);
-        if (!pStreamOut->pvPCMBuf)
-            rc = VERR_NO_MEMORY;
     }
 
@@ -1694,4 +1704,8 @@
     {
         ASMAtomicXchgU32(&pStreamIn->status, CA_STATUS_IN_UNINIT);
+
+        /*
+         * Unregister input device callbacks.
+         */
         AudioObjectPropertyAddress propAdr = { kAudioDeviceProcessorOverload, kAudioUnitScope_Global,
                                                kAudioObjectPropertyElementMaster };
@@ -1703,4 +1717,5 @@
             LogRel(("CoreAudio: Failed to remove the processor overload listener (%RI32)\n", err));
 #endif /* DEBUG */
+
         propAdr.mSelector = kAudioDevicePropertyNominalSampleRate;
         err = AudioObjectRemovePropertyListener(pStreamIn->deviceID, &propAdr,
@@ -1710,4 +1725,16 @@
             LogRel(("CoreAudio: Failed to remove the sample rate changed listener (%RI32)\n", err));
 
+        if (pStreamIn->fDefDevChgListReg)
+        {
+            err = AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDefaultInputDevice,
+                                                      drvHostCoreAudioDefaultDeviceChanged);
+            if (RT_LIKELY(err == noErr))
+            {
+                pStreamIn->fDefDevChgListReg = false;
+            }
+            else
+                LogRel(("CoreAudio: [Output] Failed to remove the default input device changed listener (%RI32)\n", err));
+        }
+
         if (pStreamIn->converter)
         {
@@ -1715,4 +1742,5 @@
             pStreamIn->converter = NULL;
         }
+
         err = AudioUnitUninitialize(pStreamIn->audioUnit);
         if (RT_LIKELY(err == noErr))
@@ -1722,4 +1750,5 @@
             {
                 RTCircBufDestroy(pStreamIn->pBuf);
+
                 pStreamIn->audioUnit   = NULL;
                 pStreamIn->deviceID    = kAudioDeviceUnknown;
@@ -1727,4 +1756,5 @@
                 pStreamIn->sampleRatio = 1;
                 pStreamIn->rpos        = 0;
+
                 ASMAtomicXchgU32(&pStreamIn->status, CA_STATUS_UNINIT);
             }
@@ -1771,12 +1801,19 @@
     {
         ASMAtomicXchgU32(&pStreamOut->status, CA_STATUS_IN_UNINIT);
-#if 0
-        err = AudioDeviceRemovePropertyListener(pStreamOut->audioDeviceId, 0, false,
-                                                kAudioDeviceProcessorOverload, drvHostCoreAudioPlaybackAudioDevicePropertyChanged);
-        /* Not Fatal */
-        if (RT_UNLIKELY(err != noErr))
-            LogRel(("CoreAudio: Failed to remove the processor overload listener (%RI32)\n", err));
-#endif /* DEBUG */
-        OSStatus err = AudioUnitUninitialize(pStreamOut->audioUnit);
+
+        OSStatus err;
+        if (pStreamOut->fDefDevChgListReg)
+        {
+            err = AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDefaultOutputDevice,
+                                                      drvHostCoreAudioDefaultDeviceChanged);
+            if (RT_LIKELY(err == noErr))
+            {
+                pStreamOut->fDefDevChgListReg = false;
+            }
+            else
+                LogRel(("CoreAudio: [Output] Failed to remove the default playback device changed listener (%RI32)\n", err));
+        }
+
+        err = AudioUnitUninitialize(pStreamOut->audioUnit);
         if (err == noErr)
         {
@@ -1860,6 +1897,10 @@
                                                           drvHostCoreAudioDefaultDeviceChanged, (void *)pStreamIn);
             /* Not fatal. */
-            if (err != noErr)
-                LogRel(("CoreAudio: Failed to register the default input device changed listener (%RI32)\n", err));
+            if (RT_LIKELY(err == noErr))
+            {
+                pStreamIn->fDefDevChgListReg = true;
+            }
+            else
+                LogRel(("CoreAudio: Failed to add the default input device changed listener (%RI32)\n", err));
         }
     }
@@ -1916,6 +1957,10 @@
                                              drvHostCoreAudioDefaultDeviceChanged, (void *)pStreamOut);
         /* Not fatal. */
-        if (err != noErr)
-            LogRel(("CoreAudio: Failed to register default device changed listener (%RI32)\n", err));
+        if (RT_LIKELY(err == noErr))
+        {
+            pStreamOut->fDefDevChgListReg = true;
+        }
+        else
+            LogRel(("CoreAudio: Failed to add the default output device changed listener (%RI32)\n", err));
     }
 
