diff --git a/Makefile.common b/Makefile.common
index 80ee18ed55..f403fd2c85 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -510,9 +510,19 @@ endif
# Audio
+
ifeq ($(HAVE_COREAUDIO), 1)
OBJ += audio/drivers/coreaudio.o
- LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit
+ HAVE_COREAUDIO_LIBS = 1
+endif
+
+ifeq ($(HAVE_COREAUDIO3), 1)
+ OBJ += audio/drivers/coreaudio3.o
+ HAVE_COREAUDIO_LIBS = 1
+endif
+
+ifeq ($(HAVE_COREAUDIO_LIBS), 1)
+ LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit
endif
ifeq ($(HAVE_CORETEXT), 1)
diff --git a/audio/audio_driver.c b/audio/audio_driver.c
index b9b13b03ea..6633d8147b 100644
--- a/audio/audio_driver.c
+++ b/audio/audio_driver.c
@@ -89,6 +89,9 @@ static const audio_driver_t *audio_drivers[] = {
#ifdef HAVE_COREAUDIO
&audio_coreaudio,
#endif
+#ifdef HAVE_COREAUDIO3
+ &audio_coreaudio3,
+#endif
#ifdef HAVE_AL
&audio_openal,
#endif
diff --git a/audio/audio_driver.h b/audio/audio_driver.h
index 8f2ba905f0..cc882af3b4 100644
--- a/audio/audio_driver.h
+++ b/audio/audio_driver.h
@@ -304,6 +304,7 @@ extern audio_driver_t audio_pulse;
extern audio_driver_t audio_dsound;
extern audio_driver_t audio_wasapi;
extern audio_driver_t audio_coreaudio;
+extern audio_driver_t audio_coreaudio3;
extern audio_driver_t audio_xenon360;
extern audio_driver_t audio_ps3;
extern audio_driver_t audio_gx;
diff --git a/audio/drivers/coreaudio3.m b/audio/drivers/coreaudio3.m
new file mode 100644
index 0000000000..279a4f2612
--- /dev/null
+++ b/audio/drivers/coreaudio3.m
@@ -0,0 +1,382 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2019 - Stuart Carnie
+ *
+ * RetroArch is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RetroArch.
+ * If not, see .
+ */
+
+#import
+#import
+#import
+
+#include
+#include
+#include
+#include
+
+#include "../audio_driver.h"
+
+#pragma mark - ringbuffer
+
+typedef struct ringbuffer
+{
+ float *buffer;
+ size_t cap;
+ atomic_int len;
+ size_t writePtr;
+ size_t readPtr;
+} ringbuffer_t;
+
+typedef ringbuffer_t * ringbuffer_h;
+
+static inline size_t rb_len(ringbuffer_h r)
+{
+ return atomic_load_explicit(&r->len, memory_order_relaxed);
+}
+
+static inline size_t rb_cap(ringbuffer_h r)
+{
+ return (r->readPtr + r->cap - r->writePtr) % r->cap;
+}
+
+static inline size_t rb_avail(ringbuffer_h r)
+{
+ return r->cap - rb_len(r);
+}
+
+static inline void rb_advance_write(ringbuffer_h r)
+{
+ r->writePtr = (r->writePtr + 1) % r->cap;
+}
+
+static inline void rb_advance_write_n(ringbuffer_h r, size_t n)
+{
+ r->writePtr = (r->writePtr + n) % r->cap;
+}
+
+static inline void rb_advance_read(ringbuffer_h r)
+{
+ r->readPtr = (r->readPtr + 1) % r->cap;
+}
+
+static inline void rb_len_add(ringbuffer_h r, int n)
+{
+ atomic_fetch_add(&r->len, n);
+}
+
+static inline void rb_len_sub(ringbuffer_h r, int n)
+{
+ atomic_fetch_sub(&r->len, n);
+}
+
+static void rb_init(ringbuffer_h r, size_t cap)
+{
+ r->buffer = malloc(cap * sizeof(float));
+ r->cap = cap;
+ atomic_init(&r->len, 0);
+ r->writePtr = 0;
+ r->readPtr = 0;
+}
+
+static void rb_free(ringbuffer_h r)
+{
+ free(r->buffer);
+ bzero(r, sizeof(*r));
+}
+
+#define UNLIKELY(x) __builtin_expect((x), 0)
+#define LIKELY(x) __builtin_expect((x), 1)
+
+static void rb_write_data(ringbuffer_h r, const float *data, size_t len)
+{
+ size_t avail = rb_avail(r);
+ size_t n = MIN(len, avail);
+ size_t first_write = n;
+ size_t rest_write = 0;
+
+ if (r->writePtr + n > r->cap)
+ {
+ first_write = r->cap - r->writePtr;
+ rest_write = n - first_write;
+ }
+
+ memcpy(r->buffer + r->writePtr, data, first_write*sizeof(float));
+ memcpy(r->buffer, data + first_write, rest_write*sizeof(float));
+
+ rb_advance_write_n(r, n);
+ rb_len_add(r, (int)n);
+}
+
+static void rb_read_data(ringbuffer_h r, float *d0, float *d1, size_t len)
+{
+ size_t need = len*2;
+
+ do {
+ size_t have = rb_len(r);
+ size_t n = MIN(have, need);
+ int i = 0;
+ for (; i < n/2; i++)
+ {
+ d0[i] = r->buffer[r->readPtr];
+ rb_advance_read(r);
+ d1[i] = r->buffer[r->readPtr];
+ rb_advance_read(r);
+ }
+
+ need -= n;
+ rb_len_sub(r, (int)n);
+
+ if (UNLIKELY(need > 0))
+ {
+ /* we got more data */
+ if (rb_len(r) > 0)
+ continue;
+
+ // underflow
+ const float quiet = 0.0f;
+ size_t fill = (need/2)*sizeof(float);
+ memset_pattern4(&d0[i], &quiet, fill);
+ memset_pattern4(&d1[i], &quiet, fill);
+ }
+ } while (0);
+}
+
+#pragma mark - CoreAudio3
+
+static bool g_interrupted;
+
+@interface CoreAudio3 : NSObject {
+ ringbuffer_t _rb;
+ dispatch_semaphore_t _sema;
+ AUAudioUnit *_au;
+ size_t _bufferSize;
+ BOOL _nonBlock;
+}
+
+@property (nonatomic, readwrite) BOOL nonBlock;
+@property (nonatomic, readonly) BOOL paused;
+@property (nonatomic, readonly) size_t writeAvailableInBytes;
+@property (nonatomic, readonly) size_t bufferSizeInBytes;
+
+- (instancetype)initWithRate:(NSUInteger)rate
+ latency:(NSUInteger)latency;
+- (ssize_t)writeFloat:(const float *)data samples:(size_t)samples;
+- (void)start;
+- (void)stop;
+
+@end
+
+@implementation CoreAudio3
+
+- (instancetype)initWithRate:(NSUInteger)rate
+ latency:(NSUInteger)latency {
+ if (self = [super init])
+ {
+ _sema = dispatch_semaphore_create(0);
+
+ _bufferSize = (latency * rate) / 1000;
+ _bufferSize *= 2; // stereo
+ rb_init(&_rb, _bufferSize);
+
+ AudioComponentDescription desc = {
+ .componentType = kAudioUnitType_Output,
+ .componentSubType = kAudioUnitSubType_DefaultOutput,
+ .componentManufacturer = kAudioUnitManufacturer_Apple,
+ };
+
+ NSError *err;
+ AUAudioUnit *au = [[AUAudioUnit alloc] initWithComponentDescription:desc error:&err];
+ if (err != nil)
+ return nil;
+
+ AVAudioFormat *format = au.outputBusses[0].format;
+ if (format.channelCount != 2)
+ return nil;
+
+ AVAudioFormat *renderFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:rate channels:2];
+ [au.inputBusses[0] setFormat:renderFormat error:&err];
+ if (err != nil)
+ return nil;
+
+ ringbuffer_h rb = &_rb;
+ __block dispatch_semaphore_t sema = _sema;
+ au.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags * actionFlags, const AudioTimeStamp * timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList * inputData) {
+ rb_read_data(rb, inputData->mBuffers[0].mData, inputData->mBuffers[1].mData, frameCount);
+ dispatch_semaphore_signal(sema);
+ return 0;
+ };
+
+ [au allocateRenderResourcesAndReturnError:&err];
+ if (err != nil)
+ return nil;
+
+ _au = au;
+
+ RARCH_LOG("[CoreAudio3]: Using buffer size of %u bytes: (latency = %u ms)\n", (unsigned)self.bufferSizeInBytes, latency);
+
+ [self start];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ rb_free(&_rb);
+}
+
+- (BOOL)paused {
+ return !_au.running;
+}
+
+- (size_t)bufferSizeInBytes {
+ return _bufferSize * sizeof(float);
+}
+
+- (size_t)writeAvailableInBytes {
+ return rb_avail(&_rb) * sizeof(float);
+}
+
+- (void)start {
+ NSError *err;
+ [_au startHardwareAndReturnError:&err];
+}
+
+- (void)stop {
+ [_au stopHardware];
+}
+
+- (ssize_t)writeFloat:(const float *)data samples:(size_t)samples {
+ size_t written = 0;
+ while (!g_interrupted && samples > 0)
+ {
+ size_t write_avail = rb_avail(&_rb);
+ if (write_avail > samples)
+ write_avail = samples;
+
+ rb_write_data(&_rb, data, write_avail);
+ data += write_avail;
+ written += write_avail;
+ samples -= write_avail;
+
+ if (_nonBlock)
+ break;
+
+ if (write_avail == 0)
+ dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER);
+ }
+
+ return written;
+}
+
+@end
+
+static void coreaudio3_free(void *data)
+{
+ CoreAudio3 *dev = (__bridge_transfer CoreAudio3 *)data;
+ if (dev == nil)
+ return;
+
+ [dev stop];
+ dev = nil;
+}
+
+static void *coreaudio3_init(const char *device,
+ unsigned rate, unsigned latency,
+ unsigned block_frames,
+ unsigned *new_rate)
+{
+ CoreAudio3 *dev = [[CoreAudio3 alloc] initWithRate:rate
+ latency:latency];
+
+ *new_rate = rate;
+
+ return (__bridge_retained void *)dev;
+}
+
+static ssize_t coreaudio3_write(void *data, const void *buf_, size_t size)
+{
+ CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
+ return [dev writeFloat:(const float *)buf_ samples:size/sizeof(float)] * sizeof(float);
+}
+
+static void coreaudio3_set_nonblock_state(void *data, bool state)
+{
+ CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
+ if (dev == nil)
+ return;
+
+ dev.nonBlock = state;
+}
+
+static bool coreaudio3_alive(void *data)
+{
+ CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
+ if (dev == nil)
+ return NO;
+
+ return !dev.paused;
+}
+
+static bool coreaudio3_stop(void *data)
+{
+ CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
+ if (dev == nil)
+ return NO;
+
+ [dev stop];
+ return dev.paused;
+}
+
+static bool coreaudio3_start(void *data, bool is_shutdown)
+{
+ CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
+ if (dev == nil)
+ return NO;
+
+ [dev start];
+ return !dev.paused;
+}
+
+static bool coreaudio3_use_float(void *data)
+{
+ return YES;
+}
+
+static size_t coreaudio3_write_avail(void *data)
+{
+ CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
+ if (dev == nil)
+ return 0;
+
+ return dev.writeAvailableInBytes;
+}
+
+static size_t coreaudio3_buffer_size(void *data)
+{
+ CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
+ if (dev == nil)
+ return 0;
+
+ return dev.bufferSizeInBytes;
+}
+
+audio_driver_t audio_coreaudio3 = {
+ coreaudio3_init,
+ coreaudio3_write,
+ coreaudio3_stop,
+ coreaudio3_start,
+ coreaudio3_alive,
+ coreaudio3_set_nonblock_state,
+ coreaudio3_free,
+ coreaudio3_use_float,
+ "coreaudio3",
+ coreaudio3_write_avail,
+ coreaudio3_buffer_size,
+};
diff --git a/config.features.h b/config.features.h
index f3e0d85b50..42e2ff569e 100644
--- a/config.features.h
+++ b/config.features.h
@@ -152,6 +152,12 @@ static const bool _coreaudio_supp = true;
static const bool _coreaudio_supp = false;
#endif
+#ifdef HAVE_COREAUDIO3
+static const bool _coreaudio3_supp = true;
+#else
+static const bool _coreaudio3_supp = false;
+#endif
+
#if defined(HAVE_OSS) || defined(HAVE_OSS_BSD)
static const bool _oss_supp = true;
#else
diff --git a/configuration.c b/configuration.c
index a614444a4e..3612f28c7f 100644
--- a/configuration.c
+++ b/configuration.c
@@ -191,6 +191,7 @@ enum audio_driver_enum
AUDIO_DSOUND,
AUDIO_WASAPI,
AUDIO_COREAUDIO,
+ AUDIO_COREAUDIO3,
AUDIO_PS3,
AUDIO_XENON360,
AUDIO_WII,
@@ -394,6 +395,8 @@ static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_TINYALSA;
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_OSS;
#elif defined(HAVE_JACK)
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_JACK;
+#elif defined(HAVE_COREAUDIO3)
+static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO3;
#elif defined(HAVE_COREAUDIO)
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO;
#elif defined(HAVE_XAUDIO)
diff --git a/griffin/griffin_objc.m b/griffin/griffin_objc.m
index da5dfec212..a346ca8ec5 100644
--- a/griffin/griffin_objc.m
+++ b/griffin/griffin_objc.m
@@ -64,6 +64,10 @@
#include "../input/drivers_joypad/mfi_joypad.m"
#endif
+#ifdef HAVE_COREAUDIO3
+#include "../audio/drivers/coreaudio3.m"
+#endif
+
#if defined(HAVE_DISCORD)
#include "../deps/discord-rpc/src/discord_register_osx.m"
#endif
diff --git a/intl/msg_hash_ar.h b/intl/msg_hash_ar.h
index dac4c632ff..4261ff67ba 100644
--- a/intl/msg_hash_ar.h
+++ b/intl/msg_hash_ar.h
@@ -3756,3 +3756,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h
index c68303e6b7..c6a99ce1c7 100644
--- a/intl/msg_hash_chs.h
+++ b/intl/msg_hash_chs.h
@@ -4768,3 +4768,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h
index 68962e2594..7661b5aa54 100644
--- a/intl/msg_hash_cht.h
+++ b/intl/msg_hash_cht.h
@@ -3526,3 +3526,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h
index a87af6b448..b78379bb90 100644
--- a/intl/msg_hash_de.h
+++ b/intl/msg_hash_de.h
@@ -3655,3 +3655,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h
index c86d04999b..9fd13ec7a7 100644
--- a/intl/msg_hash_el.h
+++ b/intl/msg_hash_el.h
@@ -7752,3 +7752,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h
index 5b7a3b62e0..b67e4a6245 100644
--- a/intl/msg_hash_eo.h
+++ b/intl/msg_hash_eo.h
@@ -3414,3 +3414,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h
index cde4e970bb..8a3adf4730 100644
--- a/intl/msg_hash_es.h
+++ b/intl/msg_hash_es.h
@@ -7888,3 +7888,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h
index ac548e9444..1fe39d6a1f 100644
--- a/intl/msg_hash_fr.h
+++ b/intl/msg_hash_fr.h
@@ -3570,3 +3570,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h
index 100449e88a..6d11116c74 100644
--- a/intl/msg_hash_it.h
+++ b/intl/msg_hash_it.h
@@ -3611,3 +3611,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h
index 4a03650676..5df46be382 100644
--- a/intl/msg_hash_ja.h
+++ b/intl/msg_hash_ja.h
@@ -4060,3 +4060,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h
index 1ac0a3dd74..bfec9bae41 100644
--- a/intl/msg_hash_ko.h
+++ b/intl/msg_hash_ko.h
@@ -3521,3 +3521,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h
index def8fb25b3..b7eb9ad1c8 100644
--- a/intl/msg_hash_nl.h
+++ b/intl/msg_hash_nl.h
@@ -3400,3 +3400,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio ondersteuning"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h
index 8b26a2bee7..60868491dd 100644
--- a/intl/msg_hash_pl.h
+++ b/intl/msg_hash_pl.h
@@ -3814,3 +3814,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h
index 8700e47bce..51efefbdea 100644
--- a/intl/msg_hash_pt_br.h
+++ b/intl/msg_hash_pt_br.h
@@ -8040,3 +8040,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h
index 9f9721395d..4101c40ea8 100644
--- a/intl/msg_hash_pt_pt.h
+++ b/intl/msg_hash_pt_pt.h
@@ -3480,3 +3480,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h
index 401eae6bae..2d7cef985b 100644
--- a/intl/msg_hash_ru.h
+++ b/intl/msg_hash_ru.h
@@ -3683,3 +3683,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h
index 53809150f5..86d8a21177 100644
--- a/intl/msg_hash_us.h
+++ b/intl/msg_hash_us.h
@@ -8120,3 +8120,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h
index 8849743b03..6c802afa81 100644
--- a/intl/msg_hash_vn.h
+++ b/intl/msg_hash_vn.h
@@ -3570,3 +3570,7 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
"CoreAudio support"
)
+MSG_HASH(
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
+ "CoreAudio V3 support"
+ )
diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c
index deda0344e4..26a3c8b4cb 100644
--- a/menu/menu_displaylist.c
+++ b/menu/menu_displaylist.c
@@ -1098,6 +1098,15 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info)
menu_entries_append_enum(info->list, feat_str, "",
MENU_ENUM_LABEL_SYSTEM_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0);
+ snprintf(feat_str, sizeof(feat_str),
+ "%s: %s",
+ msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT),
+ _coreaudio3_supp ?
+ msg_hash_to_str(MENU_ENUM_LABEL_VALUE_YES) :
+ msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO));
+ menu_entries_append_enum(info->list, feat_str, "",
+ MENU_ENUM_LABEL_SYSTEM_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0);
+
snprintf(feat_str, sizeof(feat_str),
"%s: %s",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT),
diff --git a/msg_hash.h b/msg_hash.h
index adb6c1809b..ae8b339239 100644
--- a/msg_hash.h
+++ b/msg_hash.h
@@ -1836,6 +1836,7 @@ enum msg_hash_enums
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OSS_SUPPORT,
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT,
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO_SUPPORT,
+ MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENSL_SUPPORT,
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT,
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT,
diff --git a/retroarch.c b/retroarch.c
index dfcbc8780e..0406c3ecf6 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -390,6 +390,7 @@ static void retroarch_print_features(void)
_PSUPP(vg, "OpenVG", "Video context driver");
_PSUPP(coreaudio, "CoreAudio", "Audio driver");
+ _PSUPP(coreaudio3, "CoreAudioV3", "Audio driver");
_PSUPP(alsa, "ALSA", "Audio driver");
_PSUPP(oss, "OSS", "Audio driver");
_PSUPP(jack, "Jack", "Audio driver");