mirror of https://github.com/encounter/SDL.git
coreaudio: Implemented audio capture for iOS.
This commit is contained in:
parent
f758483a28
commit
a9ef240cef
|
@ -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. */
|
||||
}
|
||||
|
|
|
@ -48,9 +48,9 @@ struct SDL_PrivateAudioData
|
|||
void *buffer;
|
||||
UInt32 bufferOffset;
|
||||
UInt32 bufferSize;
|
||||
AudioBufferList captureBufferList;
|
||||
#if MACOSX_COREAUDIO
|
||||
AudioDeviceID deviceID;
|
||||
AudioBufferList captureBufferList;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue