diff --git a/src/media/audio/coreaudio/Makefile.am b/src/media/audio/coreaudio/Makefile.am
index 10d07d47ea7f2aaac7db875633946755d54e1c20..655f144bb8bc2a1e1c01db077791163c24284ea3 100644
--- a/src/media/audio/coreaudio/Makefile.am
+++ b/src/media/audio/coreaudio/Makefile.am
@@ -2,7 +2,7 @@ include $(top_srcdir)/globals.mk
 
 if HAVE_OSX
 noinst_LTLIBRARIES = libcoreaudiolayer.la
-libcoreaudiolayer_la_SOURCES = osx/corelayer.cpp osx/corelayer.h osx/audiodevice.cpp osx/audiodevice.h
+libcoreaudiolayer_la_SOURCES = osx/corelayer.mm osx/corelayer.h osx/audiodevice.cpp osx/audiodevice.h
 endif
 
 if HAVE_IOS
@@ -11,3 +11,4 @@ libcoreaudiolayer_la_SOURCES = ios/corelayer.mm ios/corelayer.h
 endif
 
 libcoreaudiolayer_la_CXXFLAGS = -I$(top_srcdir)/src
+AM_OBJCXXFLAGS = -std=c++17
diff --git a/src/media/audio/coreaudio/ios/corelayer.h b/src/media/audio/coreaudio/ios/corelayer.h
index 1155f9426181e57eb840ce16dee4c94d2a67d00b..b1dbfb87ca86e27b695d5c46067764b01e0cb414 100644
--- a/src/media/audio/coreaudio/ios/corelayer.h
+++ b/src/media/audio/coreaudio/ios/corelayer.h
@@ -23,7 +23,6 @@
 #define CORE_LAYER_H_
 
 #include "audio/audiolayer.h"
-#include "noncopyable.h"
 #include <AudioToolbox/AudioToolbox.h>
 
 #define checkErr(err) \
@@ -162,6 +161,7 @@ private:
     UInt32 outChannelsPerFrame_;
 
     std::condition_variable readyCv_ {};
+    dispatch_queue_t audioConfigurationQueue;
 };
 
 } // namespace jami
diff --git a/src/media/audio/coreaudio/ios/corelayer.mm b/src/media/audio/coreaudio/ios/corelayer.mm
index 54640bc66da6201ce1642eea7fce4b7207e10ac0..5552e783cefe943b5b1c74bc1cecefd369bb506a 100644
--- a/src/media/audio/coreaudio/ios/corelayer.mm
+++ b/src/media/audio/coreaudio/ios/corelayer.mm
@@ -21,20 +21,20 @@
 
 #include "corelayer.h"
 #include "manager.h"
-#include "noncopyable.h"
-#include "audio/ringbufferpool.h"
-#include "audio/ringbuffer.h"
-#include "libav_utils.h"
-
 #include <AVFoundation/AVAudioSession.h>
 
-#include <cmath>
-#include <vector>
-
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 
 namespace jami {
+dispatch_queue_t audioConfigurationQueueIOS() {
+    static dispatch_once_t queueCreationGuard;
+    static dispatch_queue_t queue;
+    dispatch_once(&queueCreationGuard, ^{
+        queue = dispatch_queue_create("audioConfigurationQueueIOS", DISPATCH_QUEUE_SERIAL);
+    });
+    return queue;
+}
 
 // AudioLayer implementation.
 CoreLayer::CoreLayer(const AudioPreference &pref)
@@ -43,11 +43,19 @@ CoreLayer::CoreLayer(const AudioPreference &pref)
     , indexOut_(pref.getAlsaCardout())
     , indexRing_(pref.getAlsaCardring())
     , playbackBuff_(0, audioFormat_)
-{}
+{
+     audioConfigurationQueue = dispatch_queue_create("com.savoirfairelinux.audioConfigurationQueueIOS", DISPATCH_QUEUE_SERIAL);
+}
 
 CoreLayer::~CoreLayer()
 {
-    stopStream();
+    dispatch_sync(audioConfigurationQueueIOS(), ^{
+        if (status_ != Status::Started)
+            return;
+        destroyAudioLayer();
+        flushUrgent();
+        flushMain();
+    });
 }
 
 std::vector<std::string>
@@ -317,29 +325,25 @@ CoreLayer::bindCallbacks() {
 void
 CoreLayer::startStream(AudioDeviceType stream)
 {
-    std::lock_guard<std::mutex> lock(mutex_);
-    JAMI_DBG("iOS CoreLayer - Start Stream");
-    auto currentCategoty =  [[AVAudioSession sharedInstance] category];
+    dispatch_async(audioConfigurationQueueIOS(), ^{
+        JAMI_DBG("iOS CoreLayer - Start Stream");
+        auto currentCategoty =  [[AVAudioSession sharedInstance] category];
+
+        bool updateStream = currentCategoty == AVAudioSessionCategoryPlayback && (stream == AudioDeviceType::CAPTURE || stream == AudioDeviceType::ALL);
+        if (status_ == Status::Started) {
+            if (updateStream)
+                destroyAudioLayer();
+            else
+                return;
+        }
+        status_ = Status::Started;
 
-    bool updateStream = currentCategoty == AVAudioSessionCategoryPlayback && (stream == AudioDeviceType::CAPTURE || stream == AudioDeviceType::ALL);
-    if (status_ == Status::Started) {
-        if (updateStream)
+        dcblocker_.reset();
+        if (!initAudioLayerIO(stream) || AudioUnitInitialize(ioUnit_) || AudioOutputUnitStart(ioUnit_)) {
             destroyAudioLayer();
-        else
-            return;
-    }
-    status_ = Status::Started;
-
-    dcblocker_.reset();
-    if (initAudioLayerIO(stream)) {
-        auto inputRes = AudioUnitInitialize(ioUnit_);
-        auto outputRes = AudioOutputUnitStart(ioUnit_);
-        if (!inputRes && !outputRes) {
-            return;
+            status_ = Status::Idle;
         }
-    }
-    destroyAudioLayer();
-    status_ = Status::Idle;
+    });
 }
 
 void
@@ -354,15 +358,13 @@ CoreLayer::destroyAudioLayer()
 void
 CoreLayer::stopStream(AudioDeviceType stream)
 {
-    JAMI_DBG("iOS CoreLayer - Stop Stream");
-    {
-        std::lock_guard<std::mutex> lock(mutex_);
+    dispatch_async(audioConfigurationQueueIOS(), ^{
+        JAMI_DBG("iOS CoreLayer - Stop Stream");
         if (status_ != Status::Started)
             return;
         status_ = Status::Idle;
         destroyAudioLayer();
-    }
-
+    });
     /* Flush the ring buffers */
     flushUrgent();
     flushMain();
diff --git a/src/media/audio/coreaudio/osx/corelayer.h b/src/media/audio/coreaudio/osx/corelayer.h
index 8409a49f1d61622bf9da860858be2ee50301ea48..14284475249994f6838cdcfef53d0a459239490b 100644
--- a/src/media/audio/coreaudio/osx/corelayer.h
+++ b/src/media/audio/coreaudio/osx/corelayer.h
@@ -22,10 +22,7 @@
 #define CORE_LAYER_H_
 
 #include "audio/audiolayer.h"
-#include "noncopyable.h"
-#include <CoreFoundation/CoreFoundation.h>
 #include <AudioToolbox/AudioToolbox.h>
-#include <CoreAudio/AudioHardware.h>
 
 #define checkErr(err) \
     if (err) { \
diff --git a/src/media/audio/coreaudio/osx/corelayer.cpp b/src/media/audio/coreaudio/osx/corelayer.mm
similarity index 95%
rename from src/media/audio/coreaudio/osx/corelayer.cpp
rename to src/media/audio/coreaudio/osx/corelayer.mm
index 823f516ec07ff59dc836fb2f4de77cc3bde00599..d6eb58a8843503f7a1e00aae7d98a599d5768540 100644
--- a/src/media/audio/coreaudio/osx/corelayer.cpp
+++ b/src/media/audio/coreaudio/osx/corelayer.mm
@@ -20,17 +20,19 @@
 
 #include "corelayer.h"
 #include "manager.h"
-#include "noncopyable.h"
-#include "audio/resampler.h"
-#include "audio/ringbufferpool.h"
-#include "audio/ringbuffer.h"
 #include "audiodevice.h"
 
-#include <cmath>
-#include <vector>
-
 namespace jami {
 
+dispatch_queue_t audioConfigurationQueueMacOS() {
+    static dispatch_once_t queueCreationGuard;
+    static dispatch_queue_t queue;
+    dispatch_once(&queueCreationGuard, ^{
+        queue = dispatch_queue_create("audioConfigurationQueueMacOS", DISPATCH_QUEUE_SERIAL);
+    });
+    return queue;
+}
+
 // AudioLayer implementation.
 CoreLayer::CoreLayer(const AudioPreference& pref)
     : AudioLayer(pref)
@@ -42,7 +44,13 @@ CoreLayer::CoreLayer(const AudioPreference& pref)
 
 CoreLayer::~CoreLayer()
 {
-    stopStream();
+    dispatch_sync(audioConfigurationQueueMacOS(), ^{
+        if (status_ != Status::Started)
+            return;
+        destroyAudioLayer();
+        flushUrgent();
+        flushMain();
+    });
 }
 
 std::vector<std::string>
@@ -294,10 +302,9 @@ CoreLayer::initAudioLayerIO(AudioDeviceType stream)
 void
 CoreLayer::startStream(AudioDeviceType stream)
 {
-    JAMI_DBG("START STREAM");
+    dispatch_async(audioConfigurationQueueMacOS(), ^{
+        JAMI_DBG("START STREAM");
 
-    {
-        std::lock_guard<std::mutex> lock(mutex_);
         if (status_ != Status::Idle)
             return;
         status_ = Status::Started;
@@ -306,13 +313,13 @@ CoreLayer::startStream(AudioDeviceType stream)
 
         initAudioLayerIO(stream);
 
-        auto inputRes = AudioUnitInitialize(ioUnit_);
-        auto outputRes = AudioOutputUnitStart(ioUnit_);
-        if (!inputRes && !outputRes) {
-            return;
+        auto inputError = AudioUnitInitialize(ioUnit_);
+        auto outputError = AudioOutputUnitStart(ioUnit_);
+        if (inputError || outputError) {
+            status_ = Status::Idle;
+            destroyAudioLayer();
         }
-    }
-    stopStream();
+    });
 }
 
 void
@@ -326,15 +333,13 @@ CoreLayer::destroyAudioLayer()
 void
 CoreLayer::stopStream(AudioDeviceType stream)
 {
-    JAMI_DBG("STOP STREAM");
-    {
-        std::lock_guard<std::mutex> lock(mutex_);
+    dispatch_async(audioConfigurationQueueMacOS(), ^{
+        JAMI_DBG("STOP STREAM");
         if (status_ != Status::Started)
             return;
         status_ = Status::Idle;
         destroyAudioLayer();
-    }
-
+    });
     /* Flush the ring buffers */
     flushUrgent();
     flushMain();