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