CoreAudio: cleanup

This commit is contained in:
Andrew Kelley 2015-08-04 09:52:48 -07:00
parent f87961275d
commit d00fe4db58

View file

@ -41,14 +41,10 @@ static void destroy_ca(struct SoundIoPrivate *si) {
kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster kAudioObjectPropertyElementMaster
}; };
err = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop_address, AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop_address, on_devices_changed, si);
on_devices_changed, si);
assert(!err);
prop_address.mSelector = kAudioHardwarePropertyServiceRestarted; prop_address.mSelector = kAudioHardwarePropertyServiceRestarted;
err = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop_address, AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop_address, on_service_restarted, si);
on_service_restarted, si);
assert(!err);
if (sica->thread) { if (sica->thread) {
sica->abort_flag.clear(); sica->abort_flag.clear();
@ -71,12 +67,6 @@ static void destroy_ca(struct SoundIoPrivate *si) {
soundio_destroy_devices_info(sica->ready_devices_info); soundio_destroy_devices_info(sica->ready_devices_info);
} }
/* TODO
static CFStringRef to_cf_string(const char *str) {
return CFStringCreateWithCString(kCFAllocatorDefault, str, kCFStringEncodingUTF8);
}
*/
// Possible errors: // Possible errors:
// * SoundIoErrorNoMem // * SoundIoErrorNoMem
// * SoundIoErrorEncodingString // * SoundIoErrorEncodingString
@ -215,6 +205,8 @@ static SoundIoChannelId from_channel_descr(const AudioChannelDescription *descr)
// See https://developer.apple.com/library/mac/documentation/MusicAudio/Reference/CoreAudioDataTypesRef/#//apple_ref/doc/constant_group/Audio_Channel_Layout_Tags // See https://developer.apple.com/library/mac/documentation/MusicAudio/Reference/CoreAudioDataTypesRef/#//apple_ref/doc/constant_group/Audio_Channel_Layout_Tags
// Possible Errors: // Possible Errors:
// * SoundIoErrorIncompatibleDevice // * SoundIoErrorIncompatibleDevice
// This does not handle all the possible layout enum values and it does not
// handle channel bitmaps.
static int from_coreaudio_layout(const AudioChannelLayout *ca_layout, SoundIoChannelLayout *layout) { static int from_coreaudio_layout(const AudioChannelLayout *ca_layout, SoundIoChannelLayout *layout) {
switch (ca_layout->mChannelLayoutTag) { switch (ca_layout->mChannelLayoutTag) {
case kAudioChannelLayoutTag_UseChannelDescriptions: case kAudioChannelLayoutTag_UseChannelDescriptions:
@ -226,7 +218,6 @@ static int from_coreaudio_layout(const AudioChannelLayout *ca_layout, SoundIoCha
break; break;
} }
case kAudioChannelLayoutTag_UseChannelBitmap: case kAudioChannelLayoutTag_UseChannelBitmap:
soundio_panic("TODO how the f to parse this");
return SoundIoErrorIncompatibleDevice; return SoundIoErrorIncompatibleDevice;
case kAudioChannelLayoutTag_Mono: case kAudioChannelLayoutTag_Mono:
layout->channel_count = 1; layout->channel_count = 1;
@ -303,7 +294,6 @@ static int from_coreaudio_layout(const AudioChannelLayout *ca_layout, SoundIoCha
layout->channels[6] = SoundIoChannelIdTopBackLeft; layout->channels[6] = SoundIoChannelIdTopBackLeft;
layout->channels[7] = SoundIoChannelIdTopBackRight; layout->channels[7] = SoundIoChannelIdTopBackRight;
break; break;
// TODO more hardcoded channel layouts
default: default:
return SoundIoErrorIncompatibleDevice; return SoundIoErrorIncompatibleDevice;
} }
@ -347,7 +337,6 @@ static void deinit_refresh_devices(RefreshDevices *rd) {
free(rd->avr_array); free(rd->avr_array);
} }
// TODO get the device UID which persists between unplug/plug
static int refresh_devices(struct SoundIoPrivate *si) { static int refresh_devices(struct SoundIoPrivate *si) {
SoundIo *soundio = &si->pub; SoundIo *soundio = &si->pub;
SoundIoCoreAudio *sica = &si->backend_data.coreaudio; SoundIoCoreAudio *sica = &si->backend_data.coreaudio;
@ -752,8 +741,10 @@ static void device_thread_run(void *arg) {
static void outstream_destroy_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { static void outstream_destroy_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio;
if (osca->output_instance) if (osca->output_instance) {
AudioOutputUnitStop(osca->output_instance)
AudioComponentInstanceDispose(osca->output_instance); AudioComponentInstanceDispose(osca->output_instance);
}
} }
static OSStatus write_callback_ca(void *userdata, AudioUnitRenderActionFlags *io_action_flags, static OSStatus write_callback_ca(void *userdata, AudioUnitRenderActionFlags *io_action_flags,
@ -788,16 +779,19 @@ static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamP
AudioComponent output_comp = AudioComponentFindNext(nullptr, &desc); AudioComponent output_comp = AudioComponentFindNext(nullptr, &desc);
if (!output_comp) { if (!output_comp) {
soundio_panic("find next comp"); outstream_destroy_ca(si, os);
return SoundIoErrorOpeningDevice;
} }
OSStatus os_err; OSStatus os_err;
if ((os_err = AudioComponentInstanceNew(output_comp, &osca->output_instance))) { if ((os_err = AudioComponentInstanceNew(output_comp, &osca->output_instance))) {
soundio_panic("AudioComponentInstanceNew"); outstream_destroy_ca(si, os);
return SoundIoErrorOpeningDevice;
} }
if ((os_err = AudioUnitInitialize(osca->output_instance))) { if ((os_err = AudioUnitInitialize(osca->output_instance))) {
soundio_panic("AudioUnitInitialize"); outstream_destroy_ca(si, os);
return SoundIoErrorOpeningDevice;
} }
AudioStreamBasicDescription format = {0}; AudioStreamBasicDescription format = {0};
@ -813,33 +807,30 @@ static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamP
if ((os_err = AudioUnitSetProperty(osca->output_instance, kAudioOutputUnitProperty_CurrentDevice, if ((os_err = AudioUnitSetProperty(osca->output_instance, kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Input, 0, &dca->device_id, sizeof(AudioDeviceID)))) kAudioUnitScope_Input, 0, &dca->device_id, sizeof(AudioDeviceID))))
{ {
soundio_panic("set device"); outstream_destroy_ca(si, os);
return SoundIoErrorOpeningDevice;
} }
if ((os_err = AudioUnitSetProperty(osca->output_instance, kAudioUnitProperty_StreamFormat, if ((os_err = AudioUnitSetProperty(osca->output_instance, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, 0, &format, sizeof(AudioStreamBasicDescription)))) kAudioUnitScope_Input, 0, &format, sizeof(AudioStreamBasicDescription))))
{ {
soundio_panic("AudioUnitSetProperty format %d", os_err); outstream_destroy_ca(si, os);
return SoundIoErrorOpeningDevice;
} }
AURenderCallbackStruct render_callback = {write_callback_ca, os}; AURenderCallbackStruct render_callback = {write_callback_ca, os};
if ((os_err = AudioUnitSetProperty(osca->output_instance, kAudioUnitProperty_SetRenderCallback, if ((os_err = AudioUnitSetProperty(osca->output_instance, kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input, 0, &render_callback, sizeof(AURenderCallbackStruct)))) kAudioUnitScope_Input, 0, &render_callback, sizeof(AURenderCallbackStruct))))
{ {
soundio_panic("AudioUnitSetProperty callback"); outstream_destroy_ca(si, os);
return SoundIoErrorOpeningDevice;
} }
return 0; return 0;
} }
static int outstream_start_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { static int outstream_start_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; return outstream_pause_ca(si, os, false);
OSStatus os_err;
if ((os_err = AudioOutputUnitStart(osca->output_instance))) {
soundio_panic("audio outut unit start");
}
return 0;
} }
static int outstream_begin_write_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, static int outstream_begin_write_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os,
@ -872,13 +863,24 @@ static int outstream_end_write_ca(struct SoundIoPrivate *si, struct SoundIoOutSt
} }
static int outstream_clear_buffer_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { static int outstream_clear_buffer_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
soundio_panic("TODO clear buffer"); return 0;
} }
static int outstream_pause_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) { static int outstream_pause_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
soundio_panic("TODO pause"); SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio;
} OSStatus os_err;
if (pause) {
if ((os_err = AudioOutputUnitStop(osca->output_instance))) {
return SoundIoErrorStreaming;
}
} else {
if ((os_err = AudioOutputUnitStart(osca->output_instance))) {
return SoundIoErrorStreaming;
}
}
return 0;
}
static int instream_open_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { static int instream_open_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) {
@ -951,14 +953,16 @@ int soundio_coreaudio_init(SoundIoPrivate *si) {
if ((err = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop_address, if ((err = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop_address,
on_devices_changed, si))) on_devices_changed, si)))
{ {
soundio_panic("add prop listener"); destroy_ca(si);
return SoundIoErrorSystemResources;
} }
prop_address.mSelector = kAudioHardwarePropertyServiceRestarted; prop_address.mSelector = kAudioHardwarePropertyServiceRestarted;
if ((err = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop_address, if ((err = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop_address,
on_service_restarted, si))) on_service_restarted, si)))
{ {
soundio_panic("add prop listener 2"); destroy_ca(si);
return SoundIoErrorSystemResources;
} }
if ((err = soundio_os_thread_create(device_thread_run, si, false, &sica->thread))) { if ((err = soundio_os_thread_create(device_thread_run, si, false, &sica->thread))) {