coreaudio: Implemented audio capture for iOS.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
diff --git a/src/audio/coreaudio/SDL_coreaudio.c b/src/audio/coreaudio/SDL_coreaudio.c
index 2385995..d70196b 100644
--- a/src/audio/coreaudio/SDL_coreaudio.c
+++ b/src/audio/coreaudio/SDL_coreaudio.c
@@ -268,6 +268,27 @@ device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectP
}
#endif
+
+static int open_playback_devices = 0;
+static int open_capture_devices = 0;
+
+static void update_audio_session()
+{
+#if !MACOSX_COREAUDIO
+ /* !!! FIXME: move this to AVAudioSession. This is deprecated, and the new version is available as of (ancient!) iOS 3.0 */
+ UInt32 category;
+ if (open_playback_devices && open_capture_devices) {
+ category = kAudioSessionCategory_PlayAndRecord;
+ } else if (open_capture_devices) {
+ category = kAudioSessionCategory_RecordAudio;
+ } else { /* nothing open, or just playing audio. */
+ category = kAudioSessionCategory_AmbientSound;
+ }
+ AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof (UInt32), &category);
+#endif
+}
+
+
/* The CoreAudio callback */
static OSStatus
outputCallback(void *inRefCon,
@@ -416,6 +437,7 @@ static void
COREAUDIO_CloseDevice(_THIS)
{
if (this->hidden != NULL) {
+ const int iscapture = this->iscapture;
if (this->hidden->audioUnitOpened) {
#if MACOSX_COREAUDIO
/* Unregister our disconnect callback. */
@@ -425,7 +447,6 @@ COREAUDIO_CloseDevice(_THIS)
AURenderCallbackStruct callback;
const AudioUnitElement output_bus = 0;
const AudioUnitElement input_bus = 1;
- const int iscapture = this->iscapture;
const AudioUnitElement bus =
((iscapture) ? input_bus : output_bus);
@@ -440,13 +461,19 @@ COREAUDIO_CloseDevice(_THIS)
AudioComponentInstanceDispose(this->hidden->audioUnit);
this->hidden->audioUnitOpened = 0;
- #if MACOSX_COREAUDIO
SDL_free(this->hidden->captureBufferList.mBuffers[0].mData);
- #endif
+
}
SDL_free(this->hidden->buffer);
SDL_free(this->hidden);
this->hidden = NULL;
+
+ if (iscapture) {
+ open_capture_devices--;
+ } else {
+ open_playback_devices--;
+ }
+ update_audio_session();
}
}
@@ -544,7 +571,6 @@ prepare_audiounit(_THIS, void *handle, int iscapture,
this->hidden->audioUnitOpened = 1;
-#if MACOSX_COREAUDIO
if (iscapture) { /* have to do EnableIO only for capture devices. */
UInt32 enable = 1;
result = AudioUnitSetProperty(this->hidden->audioUnit,
@@ -563,6 +589,7 @@ prepare_audiounit(_THIS, void *handle, int iscapture,
("AudioUnitSetProperty (kAudioOutputUnitProperty_EnableIO output bus)");
}
+#if MACOSX_COREAUDIO
/* this is always on the output_bus, even for capture devices. */
result = AudioUnitSetProperty(this->hidden->audioUnit,
kAudioOutputUnitProperty_CurrentDevice,
@@ -581,14 +608,13 @@ prepare_audiounit(_THIS, void *handle, int iscapture,
strdesc, sizeof (*strdesc));
CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)");
-#if MACOSX_COREAUDIO
if (iscapture) { /* only need to do this for capture devices. */
void *ptr;
UInt32 framesize = 0;
UInt32 propsize = sizeof (UInt32);
result = AudioUnitGetProperty(this->hidden->audioUnit,
- kAudioDevicePropertyBufferFrameSize,
+ kAudioUnitProperty_MaximumFramesPerSlice,
kAudioUnitScope_Global, output_bus,
&framesize, &propsize);
CHECK_RESULT
@@ -601,13 +627,11 @@ prepare_audiounit(_THIS, void *handle, int iscapture,
SDL_OutOfMemory();
return 0;
}
-
this->hidden->captureBufferList.mNumberBuffers = 1;
this->hidden->captureBufferList.mBuffers[0].mNumberChannels = this->spec.channels;
this->hidden->captureBufferList.mBuffers[0].mDataByteSize = framesize;
this->hidden->captureBufferList.mBuffers[0].mData = ptr;
}
-#endif
/* Set the audio callback */
SDL_zero(callback);
@@ -616,7 +640,9 @@ prepare_audiounit(_THIS, void *handle, int iscapture,
result = AudioUnitSetProperty(this->hidden->audioUnit,
iscapture ? kAudioOutputUnitProperty_SetInputCallback : kAudioUnitProperty_SetRenderCallback,
- kAudioUnitScope_Global, output_bus, &callback, sizeof(callback));
+ kAudioUnitScope_Global,
+ iscapture ? input_bus : output_bus,
+ &callback, sizeof (callback));
CHECK_RESULT
("AudioUnitSetProperty (kAudioUnitProperty_SetRenderCallback)");
@@ -668,6 +694,13 @@ COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
}
SDL_zerop(this->hidden);
+ if (iscapture) {
+ open_capture_devices++;
+ } else {
+ open_playback_devices++;
+ }
+ update_audio_session();
+
/* Setup a AudioStreamBasicDescription with the requested format */
SDL_zero(strdesc);
strdesc.mFormatID = kAudioFormatLinearPCM;
@@ -742,20 +775,22 @@ COREAUDIO_Init(SDL_AudioDriverImpl * impl)
#if MACOSX_COREAUDIO
impl->DetectDevices = COREAUDIO_DetectDevices;
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
- impl->HasCaptureSupport = 1;
#else
impl->OnlyHasDefaultOutputDevice = 1;
+ impl->OnlyHasDefaultInputDevice = 1;
/* Set category to ambient sound so that other music continues playing.
You can change this at runtime in your own code if you need different
behavior. If this is common, we can add an SDL hint for this.
*/
+ /* !!! FIXME: move this to AVAudioSession. This is deprecated, and the new version is available as of (ancient!) iOS 3.0 */
AudioSessionInitialize(NULL, NULL, NULL, nil);
UInt32 category = kAudioSessionCategory_AmbientSound;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(UInt32), &category);
#endif
impl->ProvidesOwnCallbackThread = 1;
+ impl->HasCaptureSupport = 1;
return 1; /* this audio target is available. */
}
diff --git a/src/audio/coreaudio/SDL_coreaudio.h b/src/audio/coreaudio/SDL_coreaudio.h
index 95e1215..3290732 100644
--- a/src/audio/coreaudio/SDL_coreaudio.h
+++ b/src/audio/coreaudio/SDL_coreaudio.h
@@ -48,9 +48,9 @@ struct SDL_PrivateAudioData
void *buffer;
UInt32 bufferOffset;
UInt32 bufferSize;
+ AudioBufferList captureBufferList;
#if MACOSX_COREAUDIO
AudioDeviceID deviceID;
- AudioBufferList captureBufferList;
#endif
};