mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-23 06:15:38 +00:00
CoreAudio: cleanup
This commit is contained in:
parent
f87961275d
commit
d00fe4db58
|
@ -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))) {
|
||||||
|
|
Loading…
Reference in a new issue