diff --git a/audio/coreaudio.c b/audio/coreaudio.c index f3bbaddd72..239a421218 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -22,8 +22,7 @@ #include "../boolean.h" #include -#include -#include +#include #include #include @@ -32,7 +31,7 @@ typedef struct coreaudio pthread_mutex_t lock; pthread_cond_t cond; - ComponentInstance dev; + AudioComponentInstance dev; bool dev_alive; fifo_buffer_t *buffer; @@ -49,7 +48,7 @@ static void coreaudio_free(void *data) if (dev->dev_alive) { AudioOutputUnitStop(dev->dev); - CloseComponent(dev->dev); + AudioComponentInstanceDispose(dev->dev); } if (dev->buffer) @@ -102,43 +101,32 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) if (!dev) return NULL; - CFRunLoopRef run_loop = NULL; - AudioObjectPropertyAddress addr = { - kAudioHardwarePropertyRunLoop, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; - pthread_mutex_init(&dev->lock, NULL); pthread_cond_init(&dev->cond, NULL); - AudioObjectSetPropertyData(kAudioObjectSystemObject, &addr, 0, NULL, - sizeof(CFRunLoopRef), &run_loop); - ComponentDescription desc = {0}; + // Create AudioComponent + AudioComponentDescription desc = {0}; desc.componentType = kAudioUnitType_Output; +#ifdef IOS + desc.componentSubType = kAudioUnitSubType_RemoteIO; +#else desc.componentSubType = kAudioUnitSubType_HALOutput; +#endif desc.componentManufacturer = kAudioUnitManufacturer_Apple; - AudioStreamBasicDescription stream_desc = {0}; - AudioStreamBasicDescription real_desc; - AudioChannelLayout layout = {0}; - AURenderCallbackStruct cb = {0}; - - Component comp = NULL; - OSStatus res = noErr; - UInt32 i_size = 0; - size_t fifo_size; - - comp = FindNextComponent(NULL, &desc); + AudioComponent comp = AudioComponentFindNext(NULL, &desc); if (comp == NULL) goto error; - - res = OpenAComponent(comp, &dev->dev); - if (res != noErr) + + if (AudioComponentInstanceNew(comp, &dev->dev) != noErr) goto error; dev->dev_alive = true; + // Set audio format + AudioStreamBasicDescription stream_desc = {0}; + AudioStreamBasicDescription real_desc; + stream_desc.mSampleRate = rate; stream_desc.mBitsPerChannel = sizeof(float) * CHAR_BIT; stream_desc.mChannelsPerFrame = 2; @@ -147,20 +135,16 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) stream_desc.mFramesPerPacket = 1; stream_desc.mFormatID = kAudioFormatLinearPCM; stream_desc.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | (is_little_endian() ? 0 : kAudioFormatFlagIsBigEndian); - - res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)); - if (res != noErr) + + if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)) != noErr) goto error; - - i_size = sizeof(real_desc); - res = AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &real_desc, &i_size); - if (res != noErr) + + // Check returned audio format + UInt32 i_size = sizeof(real_desc);; + if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr) goto error; - RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n", (float)real_desc.mSampleRate); - g_settings.audio.out_rate = real_desc.mSampleRate; - if (real_desc.mChannelsPerFrame != stream_desc.mChannelsPerFrame) goto error; if (real_desc.mBitsPerChannel != stream_desc.mBitsPerChannel) @@ -170,26 +154,34 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) if (real_desc.mFormatID != stream_desc.mFormatID) goto error; - layout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelBitmap; - layout.mChannelBitmap = 0x03; + RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n", (float)real_desc.mSampleRate); + g_settings.audio.out_rate = real_desc.mSampleRate; - res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_AudioChannelLayout, - kAudioUnitScope_Input, 0, &layout, sizeof(layout)); - if (res != noErr) + + // Set channel layout (fails on iOS) +#ifndef IOS + AudioChannelLayout layout = {0}; + + layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; + if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_AudioChannelLayout, + kAudioUnitScope_Input, 0, &layout, sizeof(layout)) != noErr) goto error; +#endif + // Set callbacks and finish up + AURenderCallbackStruct cb = {0}; cb.inputProc = audio_cb; cb.inputProcRefCon = dev; - res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_SetRenderCallback, - kAudioUnitScope_Input, 0, &cb, sizeof(cb)); - if (res != noErr) + if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_SetRenderCallback, + kAudioUnitScope_Input, 0, &cb, sizeof(cb)) != noErr) goto error; - res = AudioUnitInitialize(dev->dev); - if (res != noErr) + if (AudioUnitInitialize(dev->dev) != noErr) goto error; + size_t fifo_size; + fifo_size = (latency * g_settings.audio.out_rate) / 1000; fifo_size *= 2 * sizeof(float); dev->buffer_size = fifo_size; @@ -200,8 +192,7 @@ static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) RARCH_LOG("[CoreAudio]: Using buffer size of %u bytes: (latency = %u ms)\n", (unsigned)fifo_size, latency); - res = AudioOutputUnitStart(dev->dev); - if (res != noErr) + if (AudioOutputUnitStart(dev->dev) != noErr) goto error; return dev; diff --git a/ios/RetroArch.xcodeproj/project.pbxproj b/ios/RetroArch.xcodeproj/project.pbxproj index 55fbcb2f86..1db4b195b8 100644 --- a/ios/RetroArch.xcodeproj/project.pbxproj +++ b/ios/RetroArch.xcodeproj/project.pbxproj @@ -21,6 +21,9 @@ 96297A2716C82FF100E6DCE0 /* overlays in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2616C82FF100E6DCE0 /* overlays */; }; 96366C5016C9A4E100D64A22 /* resampler.c in Sources */ = {isa = PBXBuildFile; fileRef = 96366C4F16C9A4E100D64A22 /* resampler.c */; }; 96366C5216C9A4E600D64A22 /* hermite.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEC16C1DC73009DE44C /* hermite.c */; }; + 96366C5316C9A7C100D64A22 /* coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEE816C1DC73009DE44C /* coreaudio.c */; }; + 96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5416C9AC3300D64A22 /* CoreAudio.framework */; }; + 96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */; }; 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2916C1D4EA009DE44C /* UIKit.framework */; }; 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */; }; 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */; }; @@ -54,8 +57,6 @@ 96AFAEE416C1DBDB009DE44C /* config_file.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEE116C1DBDB009DE44C /* config_file.c */; }; 96AFAF0B16C1DC73009DE44C /* null.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEE16C1DC73009DE44C /* null.c */; }; 96AFAF1816C1DC73009DE44C /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEFD16C1DC73009DE44C /* utils.c */; }; - 96AFAF1F16C1DF0A009DE44C /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */; }; - 96AFAF2016C1DF3A009DE44C /* openal.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAEEF16C1DC73009DE44C /* openal.c */; }; 96AFAF2216C1DF88009DE44C /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 96AFAF2116C1DF88009DE44C /* libz.dylib */; }; 96AFAF2D16C1DFC8009DE44C /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF2416C1DFC8009DE44C /* compat.c */; }; 96AFAF2F16C1DFC8009DE44C /* rxml.c in Sources */ = {isa = PBXBuildFile; fileRef = 96AFAF2916C1DFC8009DE44C /* rxml.c */; }; @@ -100,6 +101,8 @@ 96297A2316C818FF00E6DCE0 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = RetroArch/Icon.png; sourceTree = ""; }; 96297A2616C82FF100E6DCE0 /* overlays */ = {isa = PBXFileReference; lastKnownFileType = folder; name = overlays; path = ../media/overlays; sourceTree = ""; }; 96366C4F16C9A4E100D64A22 /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = ""; }; + 96366C5416C9AC3300D64A22 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; + 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 96AFAE2516C1D4EA009DE44C /* RetroArch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RetroArch.app; sourceTree = BUILT_PRODUCTS_DIR; }; 96AFAE2916C1D4EA009DE44C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -190,7 +193,6 @@ 96AFAF0216C1DC73009DE44C /* xaudio-c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "xaudio-c.h"; sourceTree = ""; }; 96AFAF0316C1DC73009DE44C /* xaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xaudio.h; sourceTree = ""; }; 96AFAF0416C1DC73009DE44C /* xaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xaudio.c; sourceTree = ""; }; - 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; }; 96AFAF2116C1DF88009DE44C /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; 96AFAF2416C1DFC8009DE44C /* compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compat.c; sourceTree = ""; }; 96AFAF2516C1DFC8009DE44C /* getopt_rarch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = getopt_rarch.h; sourceTree = ""; }; @@ -289,8 +291,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 96366C5916C9ACF500D64A22 /* AudioToolbox.framework in Frameworks */, + 96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */, 96AFAF2216C1DF88009DE44C /* libz.dylib in Frameworks */, - 96AFAF1F16C1DF0A009DE44C /* OpenAL.framework in Frameworks */, 96AFAE2A16C1D4EA009DE44C /* UIKit.framework in Frameworks */, 96AFAE2C16C1D4EA009DE44C /* Foundation.framework in Frameworks */, 96AFAE2E16C1D4EA009DE44C /* CoreGraphics.framework in Frameworks */, @@ -311,7 +314,6 @@ 962979F416C43B9500E6DCE0 /* ic_dir.png */, 962979F516C43B9500E6DCE0 /* ic_file.png */, 96AFAF2116C1DF88009DE44C /* libz.dylib */, - 96AFAF1E16C1DF0A009DE44C /* OpenAL.framework */, 96AFAE9C16C1D976009DE44C /* core */, 96AFAE3316C1D4EA009DE44C /* RetroArch */, 96AFAE2816C1D4EA009DE44C /* Frameworks */, @@ -330,6 +332,8 @@ 96AFAE2816C1D4EA009DE44C /* Frameworks */ = { isa = PBXGroup; children = ( + 96366C5816C9ACF500D64A22 /* AudioToolbox.framework */, + 96366C5416C9AC3300D64A22 /* CoreAudio.framework */, 96AFAE2916C1D4EA009DE44C /* UIKit.framework */, 96AFAE2B16C1D4EA009DE44C /* Foundation.framework */, 96AFAE2D16C1D4EA009DE44C /* CoreGraphics.framework */, @@ -772,7 +776,6 @@ 96AFAEE416C1DBDB009DE44C /* config_file.c in Sources */, 96AFAF0B16C1DC73009DE44C /* null.c in Sources */, 96AFAF1816C1DC73009DE44C /* utils.c in Sources */, - 96AFAF2016C1DF3A009DE44C /* openal.c in Sources */, 96AFAF2D16C1DFC8009DE44C /* compat.c in Sources */, 96AFAF2F16C1DFC8009DE44C /* rxml.c in Sources */, 96AFAF8D16C1E00A009DE44C /* bitmapfont.c in Sources */, @@ -807,6 +810,7 @@ 96297A1D16C6D20900E6DCE0 /* settings_list.m in Sources */, 96366C5016C9A4E100D64A22 /* resampler.c in Sources */, 96366C5216C9A4E600D64A22 /* hermite.c in Sources */, + 96366C5316C9A7C100D64A22 /* coreaudio.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -959,7 +963,7 @@ "-D__LIBRETRO__", "-DRARCH_PERFORMANCE_MODE", "-DPACKAGE_VERSION=\\\"1.0\\\"", - "-DHAVE_AL", + "-DHAVE_COREAUDIO", "-DHAVE_DYNAMIC", "-DHAVE_OVERLAY", "-DHAVE_ZLIB", @@ -996,7 +1000,7 @@ "-D__LIBRETRO__", "-DRARCH_PERFORMANCE_MODE", "-DPACKAGE_VERSION=\\\"1.0\\\"", - "-DHAVE_AL", + "-DHAVE_COREAUDIO", "-DHAVE_DYNAMIC", "-DHAVE_OVERLAY", "-DHAVE_ZLIB",