ecore_audio: drop support for CoreAudio on macOS
authorJean Guyomarc'h <jean@guyomarch.bzh>
Sat, 29 Oct 2016 20:32:19 +0000 (22:32 +0200)
committerJean Guyomarc'h <jean@guyomarch.bzh>
Sat, 29 Oct 2016 21:01:38 +0000 (23:01 +0200)
CoreAudio support was initially introduced by commit
62e29b39f4df40fd3c0a6b17f7a16f0f8fc1d0c9 as an experimental feature.

It played basic sounds, but suffered from drawbacks: it was controlling
the master channel, and therefore any sound played by ecore_audio would
shut down a previous sound (e.g. background music) for the time of the
sound being played. So that wasn't exactly great... Also, after some
time, some hangs have been reported when playing a sound on input. Most
of the time, it translated as a pause in the main loop (see T3797).
More recently (several months ago), ecore_audio with CoreAudio stopped
working during 1.19 development...

So... CoreAudio support on macOS has never been great. And now it's fully
broken. Instead of trying to revive the thing, let just use PulseAudio.
PulseAudio can be installed without any trouble on macOS thanks to
package managers such as Homebrew. Actually, the efl package provided by
Homebrew already provides PulseAudio as a dependency. And it actually
just works very fine. Dropping CoreAudio seems therefore a nice option:
removes unmaintained code, fixes bugs, and add features.

configure.ac
src/Makefile_Ecore_Audio.am
src/lib/ecore_audio/Ecore_Audio.h
src/lib/ecore_audio/ecore_audio_core_audio.c [deleted file]
src/lib/ecore_audio/ecore_audio_obj_out_core_audio.c [deleted file]
src/lib/ecore_audio/ecore_audio_obj_out_core_audio.h [deleted file]
src/lib/ecore_audio/ecore_audio_out_core_audio.eo [deleted file]
src/lib/ecore_audio/ecore_audio_private.h

index 4f68b1e..d67f353 100644 (file)
@@ -3904,55 +3904,6 @@ AC_ARG_ENABLE([pulseaudio],
    ],
    [want_pulseaudio="yes"])
 
-if test "x${have_darwin}" = "xyes"; then
-   want_pulseaudio="no"
-   want_alsa="no"
-   want_coreaudio="yes"
-else
-   want_coreaudio="no"
-fi
-
-
-# CoreAudio flags
-if test "x${want_coreaudio}" = "xyes"; then
-   coreaudio_ldflags=""
-   have_coreaudio="no"
-   LIBS_save="$LIBS"
-   LIBS="$LIBS -framework CoreAudio"
-   AC_LINK_IFELSE(
-      [AC_LANG_PROGRAM(
-        [[
-#include <CoreAudio/CoreAudio.h>
-        ]],
-        [[
-UInt32 size;
-AudioDeviceID dev_id;
-AudioObjectPropertyAddress prop = {
-   kAudioHardwarePropertyDefaultOutputDevice,
-   kAudioObjectPropertyScopeGlobal,
-   kAudioObjectPropertyElementMaster
-};
-size = sizeof(AudioDeviceID);
-AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop, 0, NULL,
-                          &size, &dev_id);
-        ]])],
-        [
-         have_coreaudio="yes"
-         coreaudio_ldflags="-framework CoreAudio"
-        ],
-        [have_coreaudio="no"])
-      LIBS="$LIBS_save"
-      AC_MSG_CHECKING([whether Apple CoreAudio framework is supported])
-      AC_MSG_RESULT([${have_coreaudio}])
-fi
-AC_SUBST(coreaudio_ldflags)
-if test "x${have_coreaudio}" = "xyes"; then
-   AC_DEFINE([HAVE_COREAUDIO], [1], [CoreAudio support enabled])
-else
-   AC_DEFINE([HAVE_COREAUDIO], [0], [CoreAudio support disabled])
-fi
-
-
 ### Default values
 
 ### Checks for programs
@@ -3992,7 +3943,6 @@ EFL_EVAL_PKGS([ECORE_AUDIO])
 EFL_ADD_FEATURE([ECORE_AUDIO], [alsa])
 EFL_ADD_FEATURE([ECORE_AUDIO], [pulseaudio])
 EFL_ADD_FEATURE([ECORE_AUDIO], [sndfile])
-EFL_ADD_FEATURE([ECORE_AUDIO], [coreaudio])
 
 ### Checks for header files
 
@@ -4009,7 +3959,6 @@ EFL_ADD_FEATURE([ECORE_AUDIO], [coreaudio])
 EFL_LIB_END_OPTIONAL([Ecore_Audio])
 AM_CONDITIONAL([HAVE_ECORE_AUDIO_PULSE], [test "x${want_pulseaudio}" = "xyes"])
 AM_CONDITIONAL([HAVE_ECORE_AUDIO_SNDFILE], [test "x${want_sndfile}" = "xyes"])
-AM_CONDITIONAL([HAVE_ECORE_AUDIO_CORE_AUDIO], [test "x${want_coreaudio}" = "xyes"])
 
 #### End of Ecore_Audio
 
@@ -4913,7 +4862,7 @@ AC_ARG_ENABLE([multisense],
     fi
    ],
    [
-    if test "x${want_pulseaudio}" = "xyes" -o "x${want_coreaudio}" = "xyes"; then
+    if test "x${want_pulseaudio}" = "xyes"; then
        want_multisense="yes"
     else
        want_multisense="no"
@@ -6242,7 +6191,7 @@ if test -n "$CFOPT_WARNING"; then
     echo "Reconsider disabling audio."
     echo "_____________________________________________________________________"
   fi
-  if test "x${have_darwin}" = "xno" -a "x${want_pulseaudio}" = "xno"; then
+  if test "x${want_pulseaudio}" = "xno"; then
     echo "_____________________________________________________________________"
     echo "The only audio output method supported by Ecore right now on your"
     echo "system is via Pulseaudio. You have disabled that and likely have"
index 0291bd8..f57595f 100644 (file)
@@ -9,7 +9,6 @@ ecore_audio_eolian_files = \
        lib/ecore_audio/ecore_audio_in_sndfile.eo \
        lib/ecore_audio/ecore_audio_out_sndfile.eo \
        lib/ecore_audio/ecore_audio_out_pulse.eo \
-       lib/ecore_audio/ecore_audio_out_core_audio.eo \
        lib/ecore_audio/ecore_audio_in_tone.eo
 
 
@@ -72,14 +71,6 @@ lib/ecore_audio/ecore_audio_obj_out_sndfile.c \
 lib/ecore_audio/ecore_audio_sndfile_vio.c
 endif
 
-if HAVE_ECORE_AUDIO_CORE_AUDIO
-dist_installed_ecoreaudiomainheaders_DATA += \
-lib/ecore_audio/ecore_audio_obj_out_core_audio.h
-lib_ecore_audio_libecore_audio_la_SOURCES += \
-lib/ecore_audio/ecore_audio_obj_out_core_audio.c
-lib_ecore_audio_libecore_audio_la_LDFLAGS += @coreaudio_ldflags@
-
-endif
 
 if HAVE_ELUA
 
index 50e4b83..78dc346 100644 (file)
@@ -44,7 +44,7 @@ enum _Ecore_Audio_Type {
     ECORE_AUDIO_TYPE_ALSA,    /**< Use ALSA module*/
     ECORE_AUDIO_TYPE_SNDFILE, /**< Use libsndfile module */
     ECORE_AUDIO_TYPE_TONE,    /**< Use tone module */
-    ECORE_AUDIO_TYPE_CORE_AUDIO, /**< Use Core Audio module (Apple) */
+    ECORE_AUDIO_TYPE_CORE_AUDIO EINA_DEPRECATED, /**< Use Core Audio module (Apple) - DEPRECATED */
     ECORE_AUDIO_TYPE_CUSTOM,  /**< Use custom module */
     ECORE_AUDIO_MODULE_LAST,  /**< Sentinel */
 };
@@ -193,10 +193,6 @@ EAPI int                 ecore_audio_shutdown(void);
 
 #include <ecore_audio_obj_in_tone.h>
 
-#if HAVE_COREAUDIO
-# include <ecore_audio_obj_out_core_audio.h>
-#endif
-
 #if HAVE_PULSE
 # include <ecore_audio_obj_out_pulse.h>
 #endif
diff --git a/src/lib/ecore_audio/ecore_audio_core_audio.c b/src/lib/ecore_audio/ecore_audio_core_audio.c
deleted file mode 100644 (file)
index 2141d9d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_COREAUDIO
-#include "Ecore.h"
-#include "ecore_private.h"
-#include "Ecore_Audio.h"
-#include "ecore_audio_private.h"
-
-static Ecore_Audio_Module *_module = NULL;
-
-EAPI Ecore_Audio_Module *
-ecore_audio_core_audio_init(void)
-{
-   /* Don't call this twice */
-   if (_module != NULL) return _module;
-
-   _module = calloc(1, sizeof(Ecore_Audio_Module));
-   if (EINA_UNLIKELY(_module == NULL))
-     {
-        CRI("Failed to allocate Ecore_Audio_Module");
-        goto ret_null;
-     }
-
-   ECORE_MAGIC_SET(_module, ECORE_MAGIC_AUDIO_MODULE);
-   _module->type = ECORE_AUDIO_TYPE_CORE_AUDIO;
-   _module->name = "CoreAudio";
-
-   return _module;
-
-ret_null:
-   return NULL;
-}
-
-EAPI void
-ecore_audio_nssound_shutdown(void)
-{
-   free(_module);
-   _module = NULL;
-}
-
-#endif /* HAVE_COREAUDIO */
-
diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_core_audio.c b/src/lib/ecore_audio/ecore_audio_obj_out_core_audio.c
deleted file mode 100644 (file)
index 21c21c1..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <Eo.h>
-#include "ecore_audio_private.h"
-
-#include <CoreAudio/CoreAudio.h>
-
-/* Notes:
- *
- * A lot of source code on the internet dealing with CoreAudio is deprecated.
- * sndfile-play (bundled with libsndfile) is no exception and uses an almost
- * 10 years old API. Nethertheless, sndfile-play has been heavily used to
- * create the CoreAudio module.
- *
- * Documentation is almost non-existant, but here is the technical note from
- * Apple explaining how CoreAudio objects should be manipulated:
- * https://developer.apple.com/library/mac/technotes/tn2223/_index.html
- */
-
-#include "ecore_audio_obj_out_core_audio.h"
-
-typedef struct
-{
-   Eo                                  *input;
-   Eo                                  *output;
-   AudioDeviceIOProcID                  proc_id;
-   AudioStreamBasicDescription          format;
-   AudioObjectID                        obj_id;
-   UInt32                               buf_size;
-
-   Eina_Bool                            is_playing;
-   Eina_Bool                            fake_stereo;
-} Core_Audio_Helper;
-
-
-/* Apple's error codes are tricky: they are stored as 32 bits integers.
- * However, they are supposed to be represented as 4-bytes strings.
- * There is no equivalent of strerror() (of what I know).
- *
- * Ref: http://vgable.com/blog/2008/04/23/printing-a-fourcharcode/
- *
- * In case of error, take a look at CoreAudio/AudioHardwareBase.h where
- * the error codes are explained.
- */
-#define APPLE_ERROR(err_) \
-   (char[5]){((err_) >> 24) & 0xff, ((err_) >> 16) & 0xff, ((err_) >> 8) & 0xff, (err_) & 0xff, 0}
-
-#define MY_CLASS ECORE_AUDIO_OUT_CORE_AUDIO_CLASS
-#define MY_CLASS_NAME "Ecore_Audio_Out_Core_Audio"
-
-/*============================================================================*
- *                                 Helper API                                 *
- *============================================================================*/
-
-static Core_Audio_Helper *
-_core_audio_helper_new(void)
-{
-   return calloc(1, sizeof(Core_Audio_Helper));
-}
-
-static void
-_core_audio_helper_stop(Core_Audio_Helper *helper)
-{
-   EINA_SAFETY_ON_NULL_RETURN(helper);
-
-   OSStatus err;
-
-   if (!helper->is_playing) return;
-
-   /* Stop audio device */
-   err = AudioDeviceStop(helper->obj_id, helper->proc_id);
-   if (EINA_UNLIKELY(err != noErr))
-     ERR("Failed to stop audio device %i for proc id %p: '%s'",
-         helper->obj_id, helper->proc_id, APPLE_ERROR(err));
-
-   /* Remove proc ID */
-   err = AudioDeviceDestroyIOProcID(helper->obj_id, helper->proc_id);
-   if (EINA_UNLIKELY(err != noErr))
-     ERR("Failed to stop audio device %i for proc id %p: '%s'",
-         helper->obj_id, helper->proc_id, APPLE_ERROR(err));
-
-   helper->is_playing = EINA_FALSE;
-}
-
-static void
-_core_audio_helper_free(Core_Audio_Helper *helper)
-{
-   EINA_SAFETY_ON_NULL_RETURN(helper);
-
-   if (helper->is_playing)
-     _core_audio_helper_stop(helper);
-   free(helper);
-}
-
-
-/*============================================================================*
- *                           Audio Object Properties                          *
- *============================================================================*/
-
-static OSStatus
-_audio_object_id_get(AudioObjectID *obj_id)
-{
-   OSStatus err;
-   UInt32 size;
-   AudioObjectPropertyAddress prop = {
-      kAudioHardwarePropertyDefaultOutputDevice,
-      kAudioObjectPropertyScopePlayThrough,
-      kAudioObjectPropertyElementMaster
-   };
-
-   /* Default output device */
-   size = sizeof(AudioObjectID);
-   err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop, 0, NULL,
-                                    &size, obj_id);
-   return err;
-}
-
-static OSStatus
-_audio_device_stream_format_get(AudioObjectID                obj_id,
-                                AudioStreamBasicDescription *format)
-{
-   OSStatus err;
-   UInt32 size;
-   AudioObjectPropertyAddress prop = {
-      kAudioDevicePropertyStreamFormat,
-      kAudioObjectPropertyScopePlayThrough,
-      kAudioObjectPropertyElementMaster /* Channel number */
-   };
-
-   size = sizeof(AudioStreamBasicDescription);
-   err = AudioObjectGetPropertyData(obj_id, &prop, 0, NULL, &size, format);
-   return err;
-}
-
-static OSStatus
-_audio_device_stream_format_set(AudioObjectID                obj_id,
-                                AudioStreamBasicDescription *format)
-{
-   OSStatus err;
-   UInt32 size;
-   AudioObjectPropertyAddress prop = {
-      kAudioDevicePropertyStreamFormat,
-      kAudioObjectPropertyScopePlayThrough,
-      kAudioObjectPropertyElementMaster /* Channel number */
-   };
-
-   size = sizeof(AudioStreamBasicDescription);
-   err = AudioObjectSetPropertyData(obj_id, &prop, 0, NULL, size, format);
-   return err;
-}
-
-
-/*============================================================================*
- *                               Audio Callback                               *
- *============================================================================*/
-
-static OSStatus
-_audio_io_proc_cb(AudioObjectID          obj_id         EINA_UNUSED,
-                  const AudioTimeStamp  *in_now         EINA_UNUSED,
-                  const AudioBufferList *input_data     EINA_UNUSED,
-                  const AudioTimeStamp  *input_time     EINA_UNUSED,
-                  AudioBufferList       *output_data,
-                  const AudioTimeStamp  *in_output_time EINA_UNUSED,
-                  void                  *data)
-{
-   Core_Audio_Helper *helper = data;
-   float *buf;
-   int size, bread, sample_count, k;
-
-   size = output_data->mBuffers[0].mDataByteSize;
-   buf = output_data->mBuffers[0].mData;
-   sample_count = size / sizeof(float);
-
-   if (helper->fake_stereo)
-     {
-        bread = ecore_audio_obj_in_read(helper->input, buf, size * 2);
-
-        for (k = bread - 1; k >= 0; --k)
-          {
-             buf[2 * k + 0] = buf[k];
-             buf[2 * k + 1] = buf[k];
-          }
-        bread /= 2;
-     }
-   else
-     {
-        bread = ecore_audio_obj_in_read(helper->input, buf, size * 4);
-        bread /= 4;
-     }
-
-   /* Done playing */
-   if (bread < sample_count)
-     {
-        INF("Done playing: %i < %i", bread, sample_count);
-        /* Auto-detached. Don't need to do more. */
-     }
-
-   return noErr;
-}
-
-
-/*============================================================================*
- *                                   Eo API                                   *
- *============================================================================*/
-
-EOLIAN static void
-_ecore_audio_out_core_audio_ecore_audio_volume_set(Eo *obj, void *sd EINA_UNUSED, double volume)
-{
-   // TODO Change volume of playing inputs
-   ecore_audio_obj_volume_set(efl_super(obj, MY_CLASS), volume);
-}
-
-EOLIAN static Eina_Bool
-_ecore_audio_out_core_audio_ecore_audio_out_input_attach(Eo *obj, void *sd EINA_UNUSED, Eo *input)
-{
-   Core_Audio_Helper *helper;
-   UInt32 channels;
-   OSStatus err;
-   Eina_Bool chk;
-
-   chk = ecore_audio_obj_out_input_attach(efl_super(obj, MY_CLASS), input);
-   if (EINA_UNLIKELY(!chk))
-     {
-        ERR("Failed to attach input (eo_do_super)");
-        goto return_failure;
-     }
-
-   helper = _core_audio_helper_new();
-   if (EINA_UNLIKELY(helper == NULL))
-     {
-        CRI("Failed to allocate memory");
-        goto detach;
-     }
-
-   /* Keep track of input source and output object */
-   helper->input = input;
-   helper->output = obj;
-
-   /* Default output device */
-   err = _audio_object_id_get(&(helper->obj_id));
-   if (EINA_UNLIKELY(err != noErr))
-     {
-        ERR("Failed to get object property: default output device: '%s'",
-            APPLE_ERROR(err));
-        goto free_helper;
-     }
-
-   /* Get data format description */
-   err = _audio_device_stream_format_get(helper->obj_id, &(helper->format));
-   if (EINA_UNLIKELY(err != noErr))
-     {
-        ERR("Failed to get property: stream format: '%s'", APPLE_ERROR(err));
-        goto free_helper;
-     }
-
-   /* Forward samplerate to CoreAudio */
-   helper->format.mSampleRate = ecore_audio_obj_in_samplerate_get(input);
-
-   /* Set channels. If only 1 channel, emulate stereo */
-   channels = ecore_audio_obj_in_channels_get(input);
-   if (channels == 1)
-     {
-        DBG("Fake stereo enabled for input %p", input);
-        helper->fake_stereo = EINA_TRUE;
-        channels = 2;
-     }
-   helper->format.mChannelsPerFrame = channels;
-
-   /* Set new format description */
-   err = _audio_device_stream_format_set(helper->obj_id, &(helper->format));
-   if (EINA_UNLIKELY(err != noErr))
-     {
-        ERR("Failed to set property: stream format: '%s'", APPLE_ERROR(err));
-        goto free_helper;
-     }
-
-   /* We want linear PCM */
-   if (helper->format.mFormatID != kAudioFormatLinearPCM)
-     {
-        ERR("Invalid format ID. Expected linear PCM: '%s'", APPLE_ERROR(err));
-        goto free_helper;
-     }
-
-   /* Create IO proc ID */
-   err = AudioDeviceCreateIOProcID(helper->obj_id, _audio_io_proc_cb,
-                                   helper, &(helper->proc_id));
-   if (err != noErr)
-     {
-        ERR("Failed to create IO proc ID. Error: '%s'", APPLE_ERROR(err));
-        goto free_helper;
-     }
-
-   /* Keep track of data for deallocation */
-   efl_key_data_set(input, "coreaudio_data", helper);
-
-   /* Start playing */
-   helper->is_playing = EINA_TRUE;
-   err = AudioDeviceStart(helper->obj_id, helper->proc_id);
-   if (err != noErr)
-     {
-        ERR("Failed to start proc ID %p for device id %i: '%s'",
-            helper->proc_id, helper->obj_id, APPLE_ERROR(err));
-        goto free_proc_id;
-     }
-
-   return EINA_TRUE;
-
-free_proc_id:
-   AudioDeviceDestroyIOProcID(helper->obj_id, helper->proc_id);
-free_helper:
-   free(helper);
-detach:
-   ecore_audio_obj_out_input_detach(efl_super(obj, MY_CLASS), input);
-return_failure:
-   return EINA_FALSE;
-}
-
-EOLIAN static Eina_Bool
-_ecore_audio_out_core_audio_ecore_audio_out_input_detach(Eo *obj, void *sd EINA_UNUSED, Eo *input)
-{
-   Core_Audio_Helper *data;
-   Eina_Bool ret;
-
-   DBG("Detach");
-   /* Free helper */
-   data = efl_key_data_get(input, "coreaudio_data");
-   _core_audio_helper_free(data);
-
-   ret = ecore_audio_obj_out_input_detach(efl_super(obj, MY_CLASS), input);
-
-   return ret;
-}
-
-#include "ecore_audio_out_core_audio.eo.c"
diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_core_audio.h b/src/lib/ecore_audio/ecore_audio_obj_out_core_audio.h
deleted file mode 100644 (file)
index 9b8eb7d..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _ECORE_AUDIO_OBJ_OUT_CORE_AUDIO_H_
-#define _ECORE_AUDIO_OBJ_OUT_CORE_AUDIO_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "ecore_audio_out_core_audio.eo.h"
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ! _ECORE_AUDIO_OBJ_OUT_CORE_AUDIO_H_ */
-
diff --git a/src/lib/ecore_audio/ecore_audio_out_core_audio.eo b/src/lib/ecore_audio/ecore_audio_out_core_audio.eo
deleted file mode 100644 (file)
index f417a8b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-class Ecore.Audio.Out.Core_Audio (Ecore.Audio.Out)
-{
-   [[Ecore audio output for Mac OSX Core Aduio.]]
-   data: null;
-   eo_prefix: ecore_audio_obj_out_core_audio;
-   implements {
-      Ecore.Audio.volume.set;
-      Ecore.Audio.Out.input_attach;
-      Ecore.Audio.Out.input_detach;
-   }
-}
index 0bccb0e..03947b1 100644 (file)
@@ -231,13 +231,6 @@ void      ecore_audio_sndfile_lib_unload(void);
 #endif /* HAVE_SNDFILE */
 
 //////////////////////////////////////////////////////////////////////////
-#ifdef HAVE_COREAUDIO
-/* ecore_audio_core_audio */
-Ecore_Audio_Module *ecore_audio_core_audio_init(void);
-void                ecore_audio_core_audio_shutdown(void);
-#endif /* HAVE_COREAUDIO */
-
-//////////////////////////////////////////////////////////////////////////
 Ecore_Audio_Module *ecore_audio_custom_init(void);
 void                ecore_audio_custom_shutdown(void);