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();