From 999590a38cf9438f36046d3f7942c452218e1594 Mon Sep 17 00:00:00 2001
From: kkostiuk <kateryna.kostiuk@savoirfairelinux.com>
Date: Wed, 26 May 2021 19:56:41 -0400
Subject: [PATCH] core audio: listen to device events

Change-Id: If31c502b0afa6a476ed9b538512784ed94778cbe
---
 src/media/audio/coreaudio/osx/corelayer.h  |  4 ++++
 src/media/audio/coreaudio/osx/corelayer.mm | 19 +++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/src/media/audio/coreaudio/osx/corelayer.h b/src/media/audio/coreaudio/osx/corelayer.h
index f5c7ba339f..79aaed596d 100644
--- a/src/media/audio/coreaudio/osx/corelayer.h
+++ b/src/media/audio/coreaudio/osx/corelayer.h
@@ -125,6 +125,10 @@ private:
                                           UInt32 inNumberAddresses,
                                           const AudioObjectPropertyAddress inAddresses[],
                                           void* inRefCon);
+    static OSStatus devicesChangedCallback(AudioObjectID inObjectID,
+                                           UInt32 inNumberAddresses,
+                                           const AudioObjectPropertyAddress inAddresses[],
+                                           void* inRefCon);
 
     void read(AudioUnitRenderActionFlags* ioActionFlags,
               const AudioTimeStamp* inTimeStamp,
diff --git a/src/media/audio/coreaudio/osx/corelayer.mm b/src/media/audio/coreaudio/osx/corelayer.mm
index fc91bd1e7c..0240029478 100644
--- a/src/media/audio/coreaudio/osx/corelayer.mm
+++ b/src/media/audio/coreaudio/osx/corelayer.mm
@@ -175,6 +175,7 @@ CoreLayer::initAudioLayerIO(AudioDeviceType stream)
                                                  &size,
                                                  &playbackDeviceID);
     }
+
     // add listener for detecting when devices are removed
     const AudioObjectPropertyAddress aliveAddress = {kAudioDevicePropertyDeviceIsAlive,
                                                      kAudioObjectPropertyScopeGlobal,
@@ -182,6 +183,12 @@ CoreLayer::initAudioLayerIO(AudioDeviceType stream)
     AudioObjectAddPropertyListener(playbackDeviceID, &aliveAddress, &deviceIsAliveCallback, this);
     AudioObjectAddPropertyListener(inputDeviceID, &aliveAddress, &deviceIsAliveCallback, this);
 
+    // add listener to detect when devices changed
+    const AudioObjectPropertyAddress changedAddress = {kAudioHardwarePropertyDevices,
+                                                     kAudioObjectPropertyScopeGlobal,
+                                                     kAudioObjectPropertyElementMaster};
+    AudioObjectAddPropertyListener(kAudioObjectSystemObject, &changedAddress, &devicesChangedCallback, this);
+
     // Set stream format
     AudioStreamBasicDescription info;
     size = sizeof(info);
@@ -360,6 +367,18 @@ CoreLayer::deviceIsAliveCallback(AudioObjectID inObjectID,
     return kAudioServicesNoError;
 }
 
+OSStatus
+CoreLayer::devicesChangedCallback(AudioObjectID inObjectID,
+                                 UInt32 inNumberAddresses,
+                                 const AudioObjectPropertyAddress inAddresses[],
+                                 void* inRefCon)
+{
+    if (static_cast<CoreLayer*>(inRefCon)->status_ != Status::Started)
+        return kAudioServicesNoError;
+    static_cast<CoreLayer*>(inRefCon)->devicesChanged();
+    return kAudioServicesNoError;
+}
+
 OSStatus
 CoreLayer::outputCallback(void* inRefCon,
                           AudioUnitRenderActionFlags* ioActionFlags,
-- 
GitLab