[AE/osxsink/coreaudio] - split registration for the devicelist changed callback and...
authorMemphiz <memphis@machzwo.de>
Sun, 20 Jul 2014 15:51:43 +0000 (17:51 +0200)
committerMemphiz <memphis@machzwo.de>
Sun, 20 Jul 2014 15:51:43 +0000 (17:51 +0200)
xbmc/cores/AudioEngine/Sinks/AESinkDARWINOSX.cpp
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioDevice.cpp
xbmc/cores/AudioEngine/Sinks/osx/CoreAudioDevice.h

index d390368..4923614 100644 (file)
@@ -535,34 +535,6 @@ OSStatus deviceChangedCB(AudioObjectID                       inObjectID,
   return noErr;
 }
 
-void RegisterDeviceChangedCB(bool bRegister, void *ref)
-{
-  OSStatus ret = noErr;
-  AudioObjectPropertyAddress inAdr =
-  {
-    kAudioHardwarePropertyDevices,
-    kAudioObjectPropertyScopeGlobal,
-    kAudioObjectPropertyElementMaster
-  };
-
-  if (bRegister)
-  {
-    ret = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &inAdr, deviceChangedCB, ref);
-    inAdr.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
-    ret = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &inAdr, deviceChangedCB, ref);
-  }
-  else
-  {
-    ret = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &inAdr, deviceChangedCB, ref);
-    inAdr.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
-    ret = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &inAdr, deviceChangedCB, ref);
-  }
-
-  if (ret != noErr)
-    CLog::Log(LOGERROR, "CCoreAudioAE::Deinitialize - error %s a listener callback for device changes!", bRegister?"attaching":"removing");
-}
-
-
 ////////////////////////////////////////////////////////////////////////////////////////////
 CAESinkDARWINOSX::CAESinkDARWINOSX()
 : m_latentFrames(0), m_outputBitstream(false), m_outputBuffer(NULL), m_planar(false), m_planarBuffer(NULL), m_buffer(NULL)
@@ -583,14 +555,16 @@ CAESinkDARWINOSX::CAESinkDARWINOSX()
   {
     CLog::Log(LOGERROR, "CCoreAudioAE::constructor: kAudioHardwarePropertyRunLoop error.");
   }
-  RegisterDeviceChangedCB(true, this);
+  CCoreAudioDevice::RegisterDeviceChangedCB(true, deviceChangedCB, this);
+  CCoreAudioDevice::RegisterDefaultOutputDeviceChangedCB(true, deviceChangedCB, this);
   m_started = false;
   m_planar = false;
 }
 
 CAESinkDARWINOSX::~CAESinkDARWINOSX()
 {
-  RegisterDeviceChangedCB(false, this);
+  CCoreAudioDevice::RegisterDeviceChangedCB(false, deviceChangedCB, this);
+  CCoreAudioDevice::RegisterDefaultOutputDeviceChangedCB(false, deviceChangedCB, this);
 }
 
 float scoreSampleRate(Float64 destinationRate, unsigned int sourceRate)
index 2fe3bb9..c4a3a7c 100644 (file)
@@ -724,3 +724,69 @@ bool CCoreAudioDevice::SetBufferSize(UInt32 size)
 
   return (ret == noErr);
 }
+
+XbmcThreads::EndTime CCoreAudioDevice::m_callbackSuppressTimer;
+AudioObjectPropertyListenerProc CCoreAudioDevice::m_defaultOutputDeviceChangedCB = NULL;
+
+
+OSStatus CCoreAudioDevice::defaultOutputDeviceChanged(AudioObjectID                       inObjectID,
+                                                      UInt32                              inNumberAddresses,
+                                                      const AudioObjectPropertyAddress    inAddresses[],
+                                                      void*                               inClientData)
+{
+  if (m_callbackSuppressTimer.IsTimePast() && m_defaultOutputDeviceChangedCB != NULL)
+    return m_defaultOutputDeviceChangedCB(inObjectID, inNumberAddresses, inAddresses, inClientData);
+  return 0;
+}
+
+void CCoreAudioDevice::RegisterDeviceChangedCB(bool bRegister, AudioObjectPropertyListenerProc callback, void *ref)
+{
+  OSStatus ret = noErr;
+  AudioObjectPropertyAddress inAdr =
+  {
+    kAudioHardwarePropertyDevices,
+    kAudioObjectPropertyScopeGlobal,
+    kAudioObjectPropertyElementMaster
+  };
+  
+  if (bRegister)
+    ret = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &inAdr, callback, ref);
+  else
+    ret = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &inAdr, callback, ref);
+  
+  if (ret != noErr)
+    CLog::Log(LOGERROR, "CCoreAudioAE::Deinitialize - error %s a listener callback for device changes!", bRegister?"attaching":"removing");
+}
+
+void CCoreAudioDevice::RegisterDefaultOutputDeviceChangedCB(bool bRegister, AudioObjectPropertyListenerProc callback, void *ref)
+{
+  OSStatus ret = noErr;
+  static int registered = -1;
+  
+  //only allow registration once
+  if (bRegister == (registered == 1))
+    return;
+  
+  AudioObjectPropertyAddress inAdr =
+  {
+    kAudioHardwarePropertyDefaultOutputDevice,
+    kAudioObjectPropertyScopeGlobal,
+    kAudioObjectPropertyElementMaster
+  };
+  
+  if (bRegister)
+  {
+    ret = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &inAdr, defaultOutputDeviceChanged, ref);
+    m_defaultOutputDeviceChangedCB = callback;
+  }
+  else
+  {
+    ret = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &inAdr, defaultOutputDeviceChanged, ref);
+    m_defaultOutputDeviceChangedCB = NULL;
+  }
+  
+  if (ret != noErr)
+    CLog::Log(LOGERROR, "CCoreAudioAE::Deinitialize - error %s a listener callback for default output device changes!", bRegister?"attaching":"removing");
+  else
+    registered = bRegister ? 1 : 0;
+}
index afe90a1..e3cc71a 100644 (file)
@@ -68,6 +68,11 @@ public:
   UInt32        GetNumLatencyFrames();
   UInt32        GetBufferSize();
   bool          SetBufferSize(UInt32 size);
+  
+  static void   RegisterDeviceChangedCB(bool bRegister, AudioObjectPropertyListenerProc callback,  void *ref);
+  static void   RegisterDefaultOutputDeviceChangedCB(bool bRegister, AudioObjectPropertyListenerProc callback, void *ref);
+  // suppresses the default output device changed callback for given time in ms
+  static void   SuppressDefaultOutputDeviceCB(unsigned int suppressTimeMs){ m_callbackSuppressTimer.Set(suppressTimeMs); }
 
   bool          AddIOProc(AudioDeviceIOProc ioProc, void* pCallbackData);
   bool          RemoveIOProc();
@@ -84,6 +89,13 @@ protected:
   unsigned int      m_frameSize;
   unsigned int      m_OutputBufferIndex;
   unsigned int      m_BufferSizeRestore;
+  
+  static XbmcThreads::EndTime m_callbackSuppressTimer;
+  static AudioObjectPropertyListenerProc m_defaultOutputDeviceChangedCB;
+  static OSStatus defaultOutputDeviceChanged(AudioObjectID                       inObjectID,
+                                             UInt32                              inNumberAddresses,
+                                             const AudioObjectPropertyAddress    inAddresses[],
+                                             void*                               inClientData);
 };
 
 #endif