21 #include "../../SDL_internal.h"
23 #if SDL_AUDIO_DRIVER_COREAUDIO
29 #include "../SDL_audio_c.h"
30 #include "../SDL_sysaudio.h"
32 #include "../../thread/SDL_systhread.h"
34 #define DEBUG_COREAUDIO 0
37 #define CHECK_RESULT(msg) \
38 if (result != noErr) { \
39 printf("COREAUDIO: Got error %d from '%s'!\n", (int) result, msg); \
40 SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \
44 #define CHECK_RESULT(msg) \
45 if (result != noErr) { \
46 SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \
53 static const AudioObjectPropertyAddress devlist_address = {
54 kAudioHardwarePropertyDevices,
55 kAudioObjectPropertyScopeGlobal,
56 kAudioObjectPropertyElementMaster
59 typedef void (*addDevFn)(
const char *
name,
const int iscapture, AudioDeviceID devId,
void *
data);
61 typedef struct AudioDeviceList
65 struct AudioDeviceList *next;
68 static AudioDeviceList *output_devs =
NULL;
69 static AudioDeviceList *capture_devs =
NULL;
72 add_to_internal_dev_list(
const int iscapture, AudioDeviceID devId)
74 AudioDeviceList *item = (AudioDeviceList *)
SDL_malloc(
sizeof (AudioDeviceList));
80 item->next = iscapture ? capture_devs : output_devs;
91 addToDevList(
const char *
name,
const int iscapture, AudioDeviceID devId,
void *
data)
93 if (add_to_internal_dev_list(iscapture, devId)) {
99 build_device_list(
int iscapture, addDevFn addfn,
void *addfndata)
103 AudioDeviceID *devs =
NULL;
107 result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
109 if (
result != kAudioHardwareNoError)
112 devs = (AudioDeviceID *) alloca(
size);
116 result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
117 &devlist_address, 0,
NULL, &
size, devs);
118 if (
result != kAudioHardwareNoError)
121 max =
size /
sizeof (AudioDeviceID);
122 for (
i = 0;
i < max;
i++) {
123 CFStringRef cfstr =
NULL;
125 AudioDeviceID dev = devs[i];
126 AudioBufferList *buflist =
NULL;
129 const AudioObjectPropertyAddress
addr = {
130 kAudioDevicePropertyStreamConfiguration,
131 iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
132 kAudioObjectPropertyElementMaster
135 const AudioObjectPropertyAddress nameaddr = {
136 kAudioObjectPropertyName,
137 iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
138 kAudioObjectPropertyElementMaster
154 for (
j = 0;
j < buflist->mNumberBuffers;
j++) {
155 if (buflist->mBuffers[
j].mNumberChannels > 0) {
168 size =
sizeof (CFStringRef);
169 result = AudioObjectGetPropertyData(dev, &nameaddr, 0,
NULL, &
size, &cfstr);
170 if (
result != kAudioHardwareNoError)
173 len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
174 kCFStringEncodingUTF8);
179 (cfstr,
ptr,
len + 1, kCFStringEncodingUTF8)));
186 while ((
len > 0) && (
ptr[
len - 1] ==
' ')) {
196 printf(
"COREAUDIO: Found %s device #%d: '%s' (devid %d)\n",
197 ((iscapture) ?
"capture" :
"output"),
198 (
int)
i,
ptr, (
int) dev);
200 addfn(
ptr, iscapture, dev, addfndata);
207 free_audio_device_list(AudioDeviceList **list)
209 AudioDeviceList *item = *list;
211 AudioDeviceList *next = item->next;
219 COREAUDIO_DetectDevices(
void)
226 build_device_change_list(
const char *
name,
const int iscapture, AudioDeviceID devId,
void *
data)
228 AudioDeviceList **list = (AudioDeviceList **)
data;
229 AudioDeviceList *item;
230 for (item = *list; item !=
NULL; item = item->next) {
231 if (item->devid == devId) {
237 add_to_internal_dev_list(iscapture, devId);
242 reprocess_device_list(
const int iscapture, AudioDeviceList **list)
244 AudioDeviceList *item;
245 AudioDeviceList *prev =
NULL;
246 for (item = *list; item !=
NULL; item = item->next) {
250 build_device_list(iscapture, build_device_change_list, list);
254 while (item !=
NULL) {
255 AudioDeviceList *next = item->next;
261 prev->next = item->next;
273 device_list_changed(AudioObjectID systemObj, UInt32 num_addr,
const AudioObjectPropertyAddress *addrs,
void *
data)
275 reprocess_device_list(
SDL_TRUE, &capture_devs);
276 reprocess_device_list(
SDL_FALSE, &output_devs);
282 static int open_playback_devices;
283 static int open_capture_devices;
284 static int num_open_devices;
287 #if !MACOSX_COREAUDIO
289 static BOOL session_active = NO;
291 static void pause_audio_devices()
299 for (
i = 0;
i < num_open_devices; ++
i) {
301 if (
device->hidden->audioQueue && !
device->hidden->interrupted) {
302 AudioQueuePause(device->hidden->audioQueue);
307 static void resume_audio_devices()
315 for (
i = 0;
i < num_open_devices; ++
i) {
317 if (
device->hidden->audioQueue && !
device->hidden->interrupted) {
318 AudioQueueStart(device->hidden->audioQueue, NULL);
323 static void interruption_begin(
_THIS)
325 if (
this !=
NULL && this->hidden->audioQueue !=
NULL) {
326 this->hidden->interrupted =
SDL_TRUE;
327 AudioQueuePause(this->hidden->audioQueue);
331 static void interruption_end(
_THIS)
333 if (
this !=
NULL && this->hidden !=
NULL && this->hidden->audioQueue !=
NULL
334 && this->hidden->interrupted
335 && AudioQueueStart(this->hidden->audioQueue,
NULL) == AVAudioSessionErrorCodeNone) {
340 @interface SDLInterruptionListener : NSObject
346 @implementation SDLInterruptionListener
348 - (
void)audioSessionInterruption:(NSNotification *)note
350 @
synchronized (
self) {
351 NSNumber *
type = note.userInfo[AVAudioSessionInterruptionTypeKey];
352 if (
type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan) {
353 interruption_begin(
self.
device);
355 interruption_end(
self.
device);
360 - (
void)applicationBecameActive:(NSNotification *)note
362 @
synchronized (
self) {
363 interruption_end(
self.
device);
372 AVAudioSession *session = [AVAudioSession sharedInstance];
373 NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
375 NSString *category = AVAudioSessionCategoryPlayback;
376 NSString *
mode = AVAudioSessionModeDefault;
377 NSUInteger options = AVAudioSessionCategoryOptionMixWithOthers;
384 category = AVAudioSessionCategoryAmbient;
385 }
else if (
SDL_strcasecmp(hint,
"AVAudioSessionCategorySoloAmbient") == 0) {
386 category = AVAudioSessionCategorySoloAmbient;
387 options &= ~AVAudioSessionCategoryOptionMixWithOthers;
388 }
else if (
SDL_strcasecmp(hint,
"AVAudioSessionCategoryPlayback") == 0 ||
390 category = AVAudioSessionCategoryPlayback;
391 options &= ~AVAudioSessionCategoryOptionMixWithOthers;
392 }
else if (
SDL_strcasecmp(hint,
"AVAudioSessionCategoryPlayAndRecord") == 0 ||
394 if (allow_playandrecord) {
395 category = AVAudioSessionCategoryPlayAndRecord;
398 }
else if (open_playback_devices && open_capture_devices) {
399 category = AVAudioSessionCategoryPlayAndRecord;
400 }
else if (open_capture_devices) {
401 category = AVAudioSessionCategoryRecord;
405 if (category == AVAudioSessionCategoryPlayAndRecord) {
406 options |= AVAudioSessionCategoryOptionDefaultToSpeaker;
409 if (category == AVAudioSessionCategoryRecord ||
410 category == AVAudioSessionCategoryPlayAndRecord) {
416 if (category == AVAudioSessionCategoryPlayAndRecord) {
417 options |= AVAudioSessionCategoryOptionAllowBluetoothA2DP |
418 AVAudioSessionCategoryOptionAllowAirPlay;
420 if (category == AVAudioSessionCategoryPlayback ||
421 category == AVAudioSessionCategoryPlayAndRecord) {
422 options |= AVAudioSessionCategoryOptionDuckOthers;
425 if ([session respondsToSelector:
@selector(setCategory:
mode:options:error:)]) {
426 if (![session.category isEqualToString:category] || session.categoryOptions != options) {
428 pause_audio_devices();
429 [session setActive:NO error:nil];
432 if (![session setCategory:category
mode:
mode options:options error:&err]) {
433 NSString *desc = err.description;
434 SDL_SetError(
"Could not set Audio Session category: %s", desc.UTF8String);
439 if (![session.category isEqualToString:category]) {
441 pause_audio_devices();
442 [session setActive:NO error:nil];
445 if (![session setCategory:category error:&err]) {
446 NSString *desc = err.description;
447 SDL_SetError(
"Could not set Audio Session category: %s", desc.UTF8String);
453 if ((open_playback_devices || open_capture_devices) && !session_active) {
454 if (![session setActive:YES error:&err]) {
455 if ([err code] == AVAudioSessionErrorCodeResourceNotAvailable &&
456 category == AVAudioSessionCategoryPlayAndRecord) {
457 return update_audio_session(
this, open,
SDL_FALSE);
460 NSString *desc = err.description;
461 SDL_SetError(
"Could not activate Audio Session: %s", desc.UTF8String);
464 session_active = YES;
465 resume_audio_devices();
466 }
else if (!open_playback_devices && !open_capture_devices && session_active) {
467 pause_audio_devices();
468 [session setActive:NO error:nil];
473 SDLInterruptionListener *listener = [SDLInterruptionListener new];
474 listener.device =
this;
476 [center addObserver:listener
477 selector:@selector(audioSessionInterruption:)
478 name:AVAudioSessionInterruptionNotification
485 [center addObserver:listener
486 selector:@selector(applicationBecameActive:)
487 name:UIApplicationDidBecomeActiveNotification
490 [center addObserver:listener
491 selector:@selector(applicationBecameActive:)
492 name:UIApplicationWillEnterForegroundNotification
495 this->hidden->interruption_listener = CFBridgingRetain(listener);
497 SDLInterruptionListener *listener = nil;
498 listener = (SDLInterruptionListener *) CFBridgingRelease(this->hidden->interruption_listener);
499 [center removeObserver:listener];
500 @
synchronized (listener) {
501 listener.device =
NULL;
513 outputCallback(
void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
522 SDL_memset(inBuffer->mAudioData, this->spec.silence, inBuffer->mAudioDataBytesCapacity);
523 }
else if (this->
stream) {
524 UInt32 remaining = inBuffer->mAudioDataBytesCapacity;
527 while (remaining > 0) {
531 (*this->callbackspec.callback)(this->callbackspec.userdata,
532 this->hidden->buffer, this->hidden->bufferSize);
534 this->hidden->bufferOffset = 0;
552 UInt32 remaining = inBuffer->mAudioDataBytesCapacity;
555 while (remaining > 0) {
557 if (this->hidden->bufferOffset >= this->hidden->bufferSize) {
560 (*this->callbackspec.callback)(this->callbackspec.userdata,
561 this->hidden->buffer, this->hidden->bufferSize);
563 this->hidden->bufferOffset = 0;
566 len = this->hidden->bufferSize - this->hidden->bufferOffset;
567 if (
len > remaining) {
571 this->hidden->bufferOffset,
len);
574 this->hidden->bufferOffset +=
len;
578 AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0,
NULL);
580 inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity;
584 inputCallback(
void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer,
585 const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions,
586 const AudioStreamPacketDescription *inPacketDescs)
597 UInt32 remaining = inBuffer->mAudioDataByteSize;
598 while (remaining > 0) {
599 UInt32
len = this->hidden->bufferSize - this->hidden->bufferOffset;
600 if (
len > remaining) {
604 SDL_memcpy((
char *)this->hidden->buffer + this->hidden->bufferOffset,
ptr,
len);
607 this->hidden->bufferOffset +=
len;
609 if (this->hidden->bufferOffset >= this->hidden->bufferSize) {
611 (*this->callbackspec.callback)(this->callbackspec.userdata, this->hidden->buffer, this->hidden->bufferSize);
613 this->hidden->bufferOffset = 0;
618 AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0,
NULL);
623 static const AudioObjectPropertyAddress alive_address =
625 kAudioDevicePropertyDeviceIsAlive,
626 kAudioObjectPropertyScopeGlobal,
627 kAudioObjectPropertyElementMaster
631 device_unplugged(AudioObjectID devid, UInt32 num_addr,
const AudioObjectPropertyAddress *addrs,
void *
data)
636 UInt32
size =
sizeof (isAlive);
643 error = AudioObjectGetPropertyData(this->hidden->deviceID, &alive_address,
646 if (error == kAudioHardwareBadDeviceError) {
648 }
else if ((error == kAudioHardwareNoError) && (!isAlive)) {
661 default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses,
const AudioObjectPropertyAddress *inAddresses,
void *inUserData)
665 printf(
"COREAUDIO: default device changed for SDL audio device %p!\n",
this);
673 COREAUDIO_CloseDevice(
_THIS)
675 const SDL_bool iscapture = this->iscapture;
682 AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged,
this);
687 open_capture_devices--;
689 open_playback_devices--;
692 #if !MACOSX_COREAUDIO
696 for (
i = 0;
i < num_open_devices; ++
i) {
699 if (
i < num_open_devices) {
705 if (num_open_devices == 0) {
713 if (this->hidden->audioQueue) {
714 AudioQueueDispose(this->hidden->audioQueue, 1);
717 if (this->hidden->thread) {
722 if (this->hidden->ready_semaphore) {
727 SDL_free(this->hidden->audioBuffer);
728 SDL_free(this->hidden->thread_error);
737 AudioDeviceID devid = (AudioDeviceID) ((
size_t)
handle);
743 AudioObjectPropertyAddress
addr = {
745 kAudioObjectPropertyScopeGlobal,
746 kAudioObjectPropertyElementMaster
750 size =
sizeof (AudioDeviceID);
752 ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice :
753 kAudioHardwarePropertyDefaultOutputDevice);
754 result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &
addr,
756 CHECK_RESULT(
"AudioHardwareGetProperty (default device)");
759 addr.mSelector = kAudioDevicePropertyDeviceIsAlive;
760 addr.mScope = iscapture ? kAudioDevicePropertyScopeInput :
761 kAudioDevicePropertyScopeOutput;
766 (
"AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
769 SDL_SetError(
"CoreAudio: requested device exists, but isn't alive.");
773 addr.mSelector = kAudioDevicePropertyHogMode;
778 if ((
result == noErr) && (pid != -1)) {
779 SDL_SetError(
"CoreAudio: requested device is being hogged.");
783 this->hidden->deviceID = devid;
788 assign_device_to_audioqueue(
_THIS)
790 const AudioObjectPropertyAddress prop = {
791 kAudioDevicePropertyDeviceUID,
792 this->iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
793 kAudioObjectPropertyElementMaster
798 UInt32 devuidsize =
sizeof (devuid);
799 result = AudioObjectGetPropertyData(this->hidden->deviceID, &prop, 0,
NULL, &devuidsize, &devuid);
800 CHECK_RESULT(
"AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID)");
801 result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize);
802 CHECK_RESULT(
"AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)");
809 prepare_audioqueue(
_THIS)
811 const AudioStreamBasicDescription *strdesc = &this->hidden->strdesc;
812 const int iscapture = this->iscapture;
819 result = AudioQueueNewInput(strdesc, inputCallback,
this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &this->hidden->audioQueue);
820 CHECK_RESULT(
"AudioQueueNewInput");
822 result = AudioQueueNewOutput(strdesc, outputCallback,
this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &this->hidden->audioQueue);
823 CHECK_RESULT(
"AudioQueueNewOutput");
827 if (!assign_device_to_audioqueue(
this)) {
833 if (this->handle !=
NULL) {
838 AudioObjectAddPropertyListener(this->hidden->deviceID, &alive_address, device_unplugged,
this);
846 AudioChannelLayout layout;
850 layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
853 layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
856 layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_4;
859 layout.mChannelLayoutTag = kAudioChannelLayoutTag_Quadraphonic;
862 layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_0_A;
865 layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_1_A;
869 layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_6_1_A;
872 layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_7_1_A;
875 if (layout.mChannelLayoutTag != 0) {
876 result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_ChannelLayout, &layout,
sizeof(layout));
877 CHECK_RESULT(
"AudioQueueSetProperty(kAudioQueueProperty_ChannelLayout)");
881 this->hidden->bufferSize = this->
spec.
size;
882 this->hidden->bufferOffset = iscapture ? 0 : this->hidden->bufferSize;
884 this->hidden->buffer =
SDL_malloc(this->hidden->bufferSize);
885 if (this->hidden->buffer ==
NULL) {
891 double MINIMUM_AUDIO_BUFFER_TIME_MS = 15.0;
892 #if defined(__IPHONEOS__)
893 if (
floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
895 MINIMUM_AUDIO_BUFFER_TIME_MS = 40.0;
899 int numAudioBuffers = 2;
900 if (msecs < MINIMUM_AUDIO_BUFFER_TIME_MS) {
901 numAudioBuffers = ((
int)
SDL_ceil(MINIMUM_AUDIO_BUFFER_TIME_MS / msecs) * 2);
904 this->hidden->numAudioBuffers = numAudioBuffers;
905 this->hidden->audioBuffer =
SDL_calloc(1,
sizeof (AudioQueueBufferRef) * numAudioBuffers);
906 if (this->hidden->audioBuffer ==
NULL) {
912 printf(
"COREAUDIO: numAudioBuffers == %d\n", numAudioBuffers);
915 for (
i = 0;
i < numAudioBuffers;
i++) {
916 result = AudioQueueAllocateBuffer(this->hidden->audioQueue, this->spec.size, &this->hidden->audioBuffer[
i]);
917 CHECK_RESULT(
"AudioQueueAllocateBuffer");
918 SDL_memset(this->hidden->audioBuffer[
i]->mAudioData, this->spec.silence, this->hidden->audioBuffer[
i]->mAudioDataBytesCapacity);
919 this->hidden->audioBuffer[i]->mAudioDataByteSize = this->hidden->audioBuffer[i]->mAudioDataBytesCapacity;
921 result = AudioQueueEnqueueBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[
i], 0,
NULL);
922 CHECK_RESULT(
"AudioQueueEnqueueBuffer");
925 result = AudioQueueStart(this->hidden->audioQueue,
NULL);
926 CHECK_RESULT(
"AudioQueueStart");
933 audioqueue_thread(
void *arg)
938 const AudioObjectPropertyAddress default_device_address = {
939 this->iscapture ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice,
940 kAudioObjectPropertyScopeGlobal,
941 kAudioObjectPropertyElementMaster
944 if (this->handle ==
NULL) {
946 AudioObjectAddPropertyListener(kAudioObjectSystemObject, &default_device_address, default_device_changed,
this);
950 const int rc = prepare_audioqueue(
this);
963 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1);
966 if ((this->handle ==
NULL) &&
SDL_AtomicGet(&this->hidden->device_change_flag)) {
970 printf(
"COREAUDIO: audioqueue_thread is trying to switch to new default device!\n");
976 const AudioDeviceID prev_devid = this->hidden->deviceID;
977 if (prepare_device(
this, this->handle, this->iscapture) && (prev_devid != this->hidden->deviceID)) {
978 AudioQueueStop(this->hidden->audioQueue, 1);
979 if (assign_device_to_audioqueue(
this)) {
981 for (
i = 0;
i < this->hidden->numAudioBuffers;
i++) {
982 SDL_memset(this->hidden->audioBuffer[
i]->mAudioData, this->spec.silence, this->hidden->audioBuffer[
i]->mAudioDataBytesCapacity);
984 AudioQueueEnqueueBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[
i], 0,
NULL);
986 AudioQueueStart(this->hidden->audioQueue,
NULL);
993 if (!this->iscapture) {
995 CFRunLoopRunInMode(kCFRunLoopDefaultMode, secs, 0);
999 if (this->handle ==
NULL) {
1001 AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_device_address, default_device_changed,
this);
1009 COREAUDIO_OpenDevice(
_THIS,
void *
handle,
const char *devname,
int iscapture)
1011 AudioStreamBasicDescription *strdesc;
1013 int valid_datatype = 0;
1019 if (this->hidden ==
NULL) {
1024 strdesc = &this->hidden->strdesc;
1027 open_capture_devices++;
1029 open_playback_devices++;
1033 if (new_open_devices) {
1038 #if !MACOSX_COREAUDIO
1045 AVAudioSession* session = [AVAudioSession sharedInstance];
1046 [session setPreferredSampleRate:this->spec.freq error:nil];
1050 [session setPreferredInputNumberOfChannels:this->spec.channels error:nil];
1051 this->
spec.
channels = session.preferredInputNumberOfChannels;
1053 [session setPreferredOutputNumberOfChannels:this->spec.channels error:nil];
1054 this->
spec.
channels = session.preferredOutputNumberOfChannels;
1064 strdesc->mFormatID = kAudioFormatLinearPCM;
1065 strdesc->mFormatFlags = kLinearPCMFormatFlagIsPacked;
1067 strdesc->mSampleRate = this->
spec.
freq;
1068 strdesc->mFramesPerPacket = 1;
1070 while ((!valid_datatype) && (test_format)) {
1073 switch (test_format) {
1085 strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
1088 strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
1090 strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
1099 if (!valid_datatype) {
1106 #if MACOSX_COREAUDIO
1115 if (!this->hidden->ready_semaphore) {
1120 if (!this->hidden->thread) {
1126 this->hidden->ready_semaphore =
NULL;
1128 if ((this->hidden->thread !=
NULL) && (this->hidden->thread_error !=
NULL)) {
1133 return (this->hidden->thread !=
NULL) ? 0 : -1;
1137 COREAUDIO_Deinitialize(
void)
1139 #if MACOSX_COREAUDIO
1140 AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed,
NULL);
1141 free_audio_device_list(&capture_devs);
1142 free_audio_device_list(&output_devs);
1154 #if MACOSX_COREAUDIO
1156 AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed,
NULL);
1169 "coreaudio",
"CoreAudio", COREAUDIO_Init, 0
#define SDL_assert(condition)
void SDL_RemoveAudioDevice(const int iscapture, void *handle)
void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
static SDL_AudioDevice * open_devices[16]
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
SDL_AudioFormat SDL_NextAudioFormat(void)
#define SDL_AUDIO_ISBIGENDIAN(x)
Uint16 SDL_AudioFormat
Audio format flags.
#define SDL_AUDIO_ISSIGNED(x)
#define SDL_AUDIO_ISFLOAT(x)
#define SDL_AUDIO_BITSIZE(x)
#define SDL_AudioStreamGet
#define SDL_SetThreadPriority
#define SDL_AudioStreamAvailable
#define SDL_DestroySemaphore
#define SDL_CreateSemaphore
#define SDL_AudioStreamPut
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
#define SDL_OutOfMemory()
#define SDL_HINT_AUDIO_CATEGORY
A variable controlling the audio category on iOS and Mac OS X.
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLuint GLuint GLsizei GLenum type
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint const GLchar * name
AudioBootStrap COREAUDIO_bootstrap
SDL_Thread * SDL_CreateThreadInternal(int(*fn)(void *), const char *name, const size_t stacksize, void *data)
@ SDL_THREAD_PRIORITY_HIGH
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
EGLImageKHR EGLint EGLint * handle
static SDL_AudioDeviceID device
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
void(* CloseDevice)(_THIS)
int OnlyHasDefaultCaptureDevice
void(* DetectDevices)(void)
int OnlyHasDefaultOutputDevice
void(* Deinitialize)(void)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
int ProvidesOwnCallbackThread
AudioStreamBasicDescription strdesc
typedef int(__stdcall *FARPROC)()