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)
{
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)
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;
+}
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();
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