modules/coreaudio: replace deprecated functions

All API calls are now consolidated in AudioObject* calls, the old model
has been deprecated in 10.6. Follow that change.
This commit is contained in:
Daniel Mack 2010-03-19 17:32:21 +01:00 committed by Colin Guthrie
parent 678f12d056
commit 3df6845101
2 changed files with 135 additions and 57 deletions

View file

@ -1,7 +1,7 @@
/*** /***
This file is part of PulseAudio. This file is part of PulseAudio.
Copyright 2009 Daniel Mack <daniel@caiaq.de> Copyright 2009,2010 Daniel Mack <daniel@caiaq.de>
PulseAudio is free software; you can redistribute it and/or modify PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published it under the terms of the GNU Lesser General Public License as published
@ -46,7 +46,7 @@ PA_MODULE_USAGE("");
typedef struct ca_device ca_device; typedef struct ca_device ca_device;
struct ca_device { struct ca_device {
AudioDeviceID id; AudioObjectID id;
unsigned int module_index; unsigned int module_index;
PA_LLIST_FIELDS(ca_device); PA_LLIST_FIELDS(ca_device);
}; };
@ -58,15 +58,31 @@ struct userdata {
PA_LLIST_HEAD(ca_device, devices); PA_LLIST_HEAD(ca_device, devices);
}; };
static int ca_device_added(struct pa_module *m, AudioDeviceID id) { static int ca_device_added(struct pa_module *m, AudioObjectID id) {
AudioObjectPropertyAddress property_address;
OSStatus err;
pa_module *mod; pa_module *mod;
struct userdata *u = m->userdata; struct userdata *u = m->userdata;
struct ca_device *dev; struct ca_device *dev;
char *args; char *args, tmp[64];
UInt32 size;
pa_assert(u); pa_assert(u);
args = pa_sprintf_malloc("device_id=%d", (int) id); /* To prevent generating a black hole that will suck us in,
don't create sources/sinks for PulseAudio virtual devices */
property_address.mSelector = kAudioDevicePropertyDeviceManufacturer;
property_address.mScope = kAudioObjectPropertyScopeGlobal;
property_address.mElement = kAudioObjectPropertyElementMaster;
size = sizeof(tmp);
err = AudioObjectGetPropertyData(id, &property_address, 0, NULL, &size, tmp);
if (!err && strcmp(tmp, "pulseaudio.org") == 0)
return 0;
args = pa_sprintf_malloc("object_id=%d", (int) id);
pa_log_debug("Loading %s with arguments '%s'", DEVICE_MODULE_NAME, args); pa_log_debug("Loading %s with arguments '%s'", DEVICE_MODULE_NAME, args);
mod = pa_module_load(m->core, DEVICE_MODULE_NAME, args); mod = pa_module_load(m->core, DEVICE_MODULE_NAME, args);
pa_xfree(args); pa_xfree(args);
@ -87,26 +103,30 @@ static int ca_device_added(struct pa_module *m, AudioDeviceID id) {
} }
static int ca_update_device_list(struct pa_module *m) { static int ca_update_device_list(struct pa_module *m) {
AudioObjectPropertyAddress property_address;
OSStatus err; OSStatus err;
UInt32 i, size, num_devices; UInt32 i, size, num_devices;
Boolean writable;
AudioDeviceID *device_id; AudioDeviceID *device_id;
struct ca_device *dev; struct ca_device *dev;
struct userdata *u = m->userdata; struct userdata *u = m->userdata;
pa_assert(u); pa_assert(u);
property_address.mSelector = kAudioHardwarePropertyDevices;
property_address.mScope = kAudioObjectPropertyScopeGlobal;
property_address.mElement = kAudioObjectPropertyElementMaster;
/* get the number of currently available audio devices */ /* get the number of currently available audio devices */
err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &writable); err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &property_address, 0, NULL, &size);
if (err) { if (err) {
pa_log("Unable to get info for kAudioHardwarePropertyDevices."); pa_log("Unable to get data size for kAudioHardwarePropertyDevices.");
return -1; return -1;
} }
num_devices = size / sizeof(AudioDeviceID); num_devices = size / sizeof(AudioDeviceID);
device_id = pa_xnew(AudioDeviceID, num_devices); device_id = pa_xnew(AudioDeviceID, num_devices);
err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, device_id); err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property_address, 0, NULL, &size, device_id);
if (err) { if (err) {
pa_log("Unable to get kAudioHardwarePropertyDevices."); pa_log("Unable to get kAudioHardwarePropertyDevices.");
pa_xfree(device_id); pa_xfree(device_id);
@ -140,7 +160,7 @@ scan_removed:
} }
if (!found) { if (!found) {
pa_log_debug("device id %d has been removed (module index %d) %p", (unsigned int) dev->id, dev->module_index, dev); pa_log_debug("object id %d has been removed (module index %d) %p", (unsigned int) dev->id, dev->module_index, dev);
pa_module_unload_request_by_index(m->core, dev->module_index, TRUE); pa_module_unload_request_by_index(m->core, dev->module_index, TRUE);
PA_LLIST_REMOVE(ca_device, u->devices, dev); PA_LLIST_REMOVE(ca_device, u->devices, dev);
pa_xfree(dev); pa_xfree(dev);
@ -153,15 +173,17 @@ scan_removed:
return 0; return 0;
} }
static OSStatus property_listener_proc(AudioHardwarePropertyID property, void *data) { static OSStatus property_listener_proc(AudioObjectID objectID, UInt32 numberAddresses,
struct userdata *u = data; const AudioObjectPropertyAddress inAddresses[],
void *clientData)
{
struct userdata *u = clientData;
char dummy = 1; char dummy = 1;
pa_assert(u); pa_assert(u);
/* dispatch module load/unload operations in main thread */ /* dispatch module load/unload operations in main thread */
if (property == kAudioHardwarePropertyDevices) write(u->detect_fds[1], &dummy, 1);
write(u->detect_fds[1], &dummy, 1);
return 0; return 0;
} }
@ -178,11 +200,16 @@ static void detect_handle(pa_mainloop_api *a, pa_io_event *e, int fd, pa_io_even
int pa__init(pa_module *m) { int pa__init(pa_module *m) {
struct userdata *u = pa_xnew0(struct userdata, 1); struct userdata *u = pa_xnew0(struct userdata, 1);
AudioObjectPropertyAddress property_address;
m->userdata = u; m->userdata = u;
if (AudioHardwareAddPropertyListener(kAudioHardwarePropertyDevices, property_listener_proc, u)) { property_address.mSelector = kAudioHardwarePropertyDevices;
pa_log("AudioHardwareAddPropertyListener() failed."); property_address.mScope = kAudioObjectPropertyScopeGlobal;
property_address.mElement = kAudioObjectPropertyElementMaster;
if (AudioObjectAddPropertyListener(kAudioObjectSystemObject, &property_address, property_listener_proc, u)) {
pa_log("AudioObjectAddPropertyListener() failed.");
goto fail; goto fail;
} }
@ -202,10 +229,15 @@ fail:
void pa__done(pa_module *m) { void pa__done(pa_module *m) {
struct userdata *u = m->userdata; struct userdata *u = m->userdata;
struct ca_device *dev = u->devices; struct ca_device *dev = u->devices;
AudioObjectPropertyAddress property_address;
pa_assert(u); pa_assert(u);
AudioHardwareRemovePropertyListener(kAudioHardwarePropertyDevices, property_listener_proc); property_address.mSelector = kAudioHardwarePropertyDevices;
property_address.mScope = kAudioObjectPropertyScopeGlobal;
property_address.mElement = kAudioObjectPropertyElementMaster;
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &property_address, property_listener_proc, u);
while (dev) { while (dev) {
struct ca_device *next = dev->next; struct ca_device *next = dev->next;

View file

@ -1,7 +1,7 @@
/*** /***
This file is part of PulseAudio. This file is part of PulseAudio.
Copyright 2009 Daniel Mack <daniel@caiaq.de> Copyright 2009,2010 Daniel Mack <daniel@caiaq.de>
PulseAudio is free software; you can redistribute it and/or modify PulseAudio is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published it under the terms of the GNU Lesser General Public License as published
@ -58,11 +58,11 @@ PA_MODULE_AUTHOR("Daniel Mack");
PA_MODULE_DESCRIPTION("CoreAudio device"); PA_MODULE_DESCRIPTION("CoreAudio device");
PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_LOAD_ONCE(FALSE); PA_MODULE_LOAD_ONCE(FALSE);
PA_MODULE_USAGE("device_id=<the CoreAudio device id> " PA_MODULE_USAGE("object_id=<the CoreAudio device id> "
"ioproc_frames=<audio frames per IOProc call> "); "ioproc_frames=<audio frames per IOProc call> ");
static const char* const valid_modargs[] = { static const char* const valid_modargs[] = {
"device_id", "object_id",
"ioproc_frames", "ioproc_frames",
NULL NULL
}; };
@ -75,7 +75,7 @@ typedef struct coreaudio_sink coreaudio_sink;
typedef struct coreaudio_source coreaudio_source; typedef struct coreaudio_source coreaudio_source;
struct userdata { struct userdata {
AudioDeviceID device_id; AudioObjectID object_id;
AudioDeviceIOProcID proc_id; AudioDeviceIOProcID proc_id;
pa_thread_mq thread_mq; pa_thread_mq thread_mq;
@ -138,7 +138,7 @@ static OSStatus io_render_proc (AudioDeviceID device,
struct userdata *u = clientData; struct userdata *u = clientData;
pa_assert(u); pa_assert(u);
pa_assert(device == u->device_id); pa_assert(device == u->object_id);
u->render_input_data = inputData; u->render_input_data = inputData;
u->render_output_data = outputData; u->render_output_data = outputData;
@ -154,13 +154,13 @@ static OSStatus io_render_proc (AudioDeviceID device,
return 0; return 0;
} }
static OSStatus ca_stream_format_changed(AudioDeviceID inDevice, static OSStatus ca_stream_format_changed(AudioObjectID objectID,
UInt32 inChannel, UInt32 numberAddresses,
Boolean isInput, const AudioObjectPropertyAddress addresses[],
AudioDevicePropertyID inPropertyID, void *clientData)
void *inClientData)
{ {
struct userdata *u = inClientData; struct userdata *u = clientData;
UInt32 i;
pa_assert(u); pa_assert(u);
@ -169,8 +169,10 @@ static OSStatus ca_stream_format_changed(AudioDeviceID inDevice,
* The device settings will appear to be 'locked' for any application as long as the PA daemon is running. * The device settings will appear to be 'locked' for any application as long as the PA daemon is running.
* Once we're able to propagate such events up in the core, this needs to be changed. */ * Once we're able to propagate such events up in the core, this needs to be changed. */
return AudioDeviceSetProperty(inDevice, NULL, inChannel, isInput, for (i = 0; i < numberAddresses; i++)
kAudioDevicePropertyStreamFormat, sizeof(u->stream_description), &u->stream_description); AudioObjectSetPropertyData(objectID, addresses + i, 0, NULL, sizeof(u->stream_description), &u->stream_description);
return 0;
} }
static pa_usec_t get_latency_us(pa_object *o) { static pa_usec_t get_latency_us(pa_object *o) {
@ -179,6 +181,8 @@ static pa_usec_t get_latency_us(pa_object *o) {
bool is_source; bool is_source;
UInt32 v, total = 0; UInt32 v, total = 0;
UInt32 err, size = sizeof(v); UInt32 err, size = sizeof(v);
AudioObjectPropertyAddress property_address;
AudioObjectID stream_id;
if (pa_sink_isinstance(o)) { if (pa_sink_isinstance(o)) {
coreaudio_sink *sink = PA_SINK(o)->userdata; coreaudio_sink *sink = PA_SINK(o)->userdata;
@ -197,26 +201,39 @@ static pa_usec_t get_latency_us(pa_object *o) {
pa_assert(u); pa_assert(u);
property_address.mScope = kAudioObjectPropertyScopeGlobal;
property_address.mElement = kAudioObjectPropertyElementMaster;
/* get the device latency */ /* get the device latency */
property_address.mSelector = kAudioDevicePropertyLatency;
size = sizeof(total); size = sizeof(total);
AudioDeviceGetProperty(u->device_id, 0, is_source, kAudioDevicePropertyLatency, &size, &v); AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, &total);
total += v; total += v;
/* the the IOProc buffer size */ /* the the IOProc buffer size */
property_address.mSelector = kAudioDevicePropertyBufferFrameSize;
size = sizeof(v); size = sizeof(v);
AudioDeviceGetProperty(u->device_id, 0, is_source, kAudioDevicePropertyBufferFrameSize, &size, &v); AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, &v);
total += v; total += v;
/* IOProc safety offset - this value is the same for both directions, hence we divide it by 2 */ /* IOProc safety offset - this value is the same for both directions, hence we divide it by 2 */
property_address.mSelector = kAudioDevicePropertySafetyOffset;
size = sizeof(v); size = sizeof(v);
AudioDeviceGetProperty(u->device_id, 0, is_source, kAudioDevicePropertySafetyOffset, &size, &v); AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, &v);
total += v / 2; total += v / 2;
/* get the stream latency. /* get the stream latency.
* FIXME: this assumes the stream latency is the same for all streams */ * FIXME: this assumes the stream latency is the same for all streams */
err = AudioStreamGetProperty(0, is_source, kAudioStreamPropertyLatency, &size, &v); property_address.mSelector = kAudioDevicePropertyStreams;
if (!err) size = sizeof(stream_id);
total += v; err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, &stream_id);
if (!err) {
property_address.mSelector = kAudioStreamPropertyLatency;
size = sizeof(v);
err = AudioObjectGetPropertyData(stream_id, &property_address, 0, NULL, &size, &v);
if (!err)
total += v;
}
return pa_bytes_to_usec(total * pa_frame_size(ss), ss); return pa_bytes_to_usec(total * pa_frame_size(ss), ss);
} }
@ -237,9 +254,9 @@ static void ca_device_check_device_state(struct userdata *u) {
active = TRUE; active = TRUE;
if (active && !u->running) if (active && !u->running)
AudioDeviceStart(u->device_id, u->proc_id); AudioDeviceStart(u->object_id, u->proc_id);
else if (!active && u->running) else if (!active && u->running)
AudioDeviceStop(u->device_id, u->proc_id); AudioDeviceStop(u->object_id, u->proc_id);
u->running = active; u->running = active;
} }
@ -374,6 +391,7 @@ static int ca_device_create_sink(pa_module *m, AudioBuffer *buf, int channel_idx
unsigned int i; unsigned int i;
char tmp[255]; char tmp[255];
pa_strbuf *strbuf; pa_strbuf *strbuf;
AudioObjectPropertyAddress property_address;
ca_sink = pa_xnew0(coreaudio_sink, 1); ca_sink = pa_xnew0(coreaudio_sink, 1);
ca_sink->map.channels = buf->mNumberChannels; ca_sink->map.channels = buf->mNumberChannels;
@ -384,10 +402,13 @@ static int ca_device_create_sink(pa_module *m, AudioBuffer *buf, int channel_idx
strbuf = pa_strbuf_new(); strbuf = pa_strbuf_new();
for (i = 0; i < buf->mNumberChannels; i++) { for (i = 0; i < buf->mNumberChannels; i++) {
property_address.mSelector = kAudioObjectPropertyElementName;
property_address.mScope = kAudioDevicePropertyScopeOutput;
property_address.mElement = channel_idx + i + 1;
size = sizeof(tmp); size = sizeof(tmp);
err = AudioDeviceGetProperty(u->device_id, channel_idx + i + 1, 0, kAudioObjectPropertyElementName, &size, tmp); err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, tmp);
if (err || !strlen(tmp)) if (err || !strlen(tmp))
snprintf(tmp, sizeof(tmp), "Channel %d", channel_idx + i + 1); snprintf(tmp, sizeof(tmp), "Channel %d", property_address.mElement);
if (i > 0) if (i > 0)
pa_strbuf_puts(strbuf, ", "); pa_strbuf_puts(strbuf, ", ");
@ -463,6 +484,7 @@ static int ca_device_create_source(pa_module *m, AudioBuffer *buf, int channel_i
unsigned int i; unsigned int i;
char tmp[255]; char tmp[255];
pa_strbuf *strbuf; pa_strbuf *strbuf;
AudioObjectPropertyAddress property_address;
ca_source = pa_xnew0(coreaudio_source, 1); ca_source = pa_xnew0(coreaudio_source, 1);
ca_source->map.channels = buf->mNumberChannels; ca_source->map.channels = buf->mNumberChannels;
@ -473,10 +495,13 @@ static int ca_device_create_source(pa_module *m, AudioBuffer *buf, int channel_i
strbuf = pa_strbuf_new(); strbuf = pa_strbuf_new();
for (i = 0; i < buf->mNumberChannels; i++) { for (i = 0; i < buf->mNumberChannels; i++) {
property_address.mSelector = kAudioObjectPropertyElementName;
property_address.mScope = kAudioDevicePropertyScopeInput;
property_address.mElement = channel_idx + i + 1;
size = sizeof(tmp); size = sizeof(tmp);
err = AudioDeviceGetProperty(u->device_id, channel_idx + i + 1, 0, kAudioObjectPropertyElementName, &size, tmp); err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, tmp);
if (err || !strlen(tmp)) if (err || !strlen(tmp))
snprintf(tmp, sizeof(tmp), "Channel %d", channel_idx + i + 1); snprintf(tmp, sizeof(tmp), "Channel %d", property_address.mElement);
if (i > 0) if (i > 0)
pa_strbuf_puts(strbuf, ", "); pa_strbuf_puts(strbuf, ", ");
@ -545,12 +570,16 @@ static int ca_device_create_streams(pa_module *m, bool direction_in) {
OSStatus err; OSStatus err;
UInt32 size, i, channel_idx; UInt32 size, i, channel_idx;
struct userdata *u = m->userdata; struct userdata *u = m->userdata;
int section = direction_in ? 1 : 0;
AudioBufferList *buffer_list; AudioBufferList *buffer_list;
AudioObjectPropertyAddress property_address;
property_address.mScope = direction_in ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
property_address.mElement = kAudioObjectPropertyElementMaster;
/* get current stream format */ /* get current stream format */
size = sizeof(AudioStreamBasicDescription); size = sizeof(AudioStreamBasicDescription);
err = AudioDeviceGetProperty(u->device_id, 0, section, kAudioDevicePropertyStreamFormat, &size, &u->stream_description); property_address.mSelector = kAudioDevicePropertyStreamFormat;
err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, &u->stream_description);
if (err) { if (err) {
/* no appropriate streams found - silently bail. */ /* no appropriate streams found - silently bail. */
return -1; return -1;
@ -567,7 +596,8 @@ static int ca_device_create_streams(pa_module *m, bool direction_in) {
/* get stream configuration */ /* get stream configuration */
size = 0; size = 0;
err = AudioDeviceGetPropertyInfo(u->device_id, 0, section, kAudioDevicePropertyStreamConfiguration, &size, NULL); property_address.mSelector = kAudioDevicePropertyStreamConfiguration;
err = AudioObjectGetPropertyDataSize(u->object_id, &property_address, 0, NULL, &size);
if (err) { if (err) {
pa_log("Failed to get kAudioDevicePropertyStreamConfiguration (%s).", direction_in ? "input" : "output"); pa_log("Failed to get kAudioDevicePropertyStreamConfiguration (%s).", direction_in ? "input" : "output");
return -1; return -1;
@ -577,7 +607,7 @@ static int ca_device_create_streams(pa_module *m, bool direction_in) {
return 0; return 0;
buffer_list = (AudioBufferList *) pa_xmalloc(size); buffer_list = (AudioBufferList *) pa_xmalloc(size);
err = AudioDeviceGetProperty(u->device_id, 0, section, kAudioDevicePropertyStreamConfiguration, &size, buffer_list); err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, buffer_list);
if (!err) { if (!err) {
pa_log_debug("Sample rate: %f", u->stream_description.mSampleRate); pa_log_debug("Sample rate: %f", u->stream_description.mSampleRate);
@ -648,6 +678,7 @@ int pa__init(pa_module *m) {
pa_card_new_data card_new_data; pa_card_new_data card_new_data;
coreaudio_sink *ca_sink; coreaudio_sink *ca_sink;
coreaudio_source *ca_source; coreaudio_source *ca_source;
AudioObjectPropertyAddress property_address;
pa_assert(m); pa_assert(m);
@ -660,14 +691,18 @@ int pa__init(pa_module *m) {
u->module = m; u->module = m;
m->userdata = u; m->userdata = u;
if (pa_modargs_get_value_u32(ma, "device_id", (unsigned int *) &u->device_id) != 0) { if (pa_modargs_get_value_u32(ma, "object_id", (unsigned int *) &u->object_id) != 0) {
pa_log("Failed to parse device_id argument."); pa_log("Failed to parse object_id argument.");
goto fail; goto fail;
} }
property_address.mScope = kAudioObjectPropertyScopeGlobal;
property_address.mElement = kAudioObjectPropertyElementMaster;
/* get device product name */ /* get device product name */
property_address.mSelector = kAudioDevicePropertyDeviceName;
size = sizeof(tmp); size = sizeof(tmp);
err = AudioDeviceGetProperty(u->device_id, 0, 0, kAudioDevicePropertyDeviceName, &size, &tmp); err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, tmp);
if (err) { if (err) {
pa_log("Failed to get kAudioDevicePropertyDeviceName (err = %08x).", (int) err); pa_log("Failed to get kAudioDevicePropertyDeviceName (err = %08x).", (int) err);
goto fail; goto fail;
@ -679,11 +714,12 @@ int pa__init(pa_module *m) {
pa_proplist_sets(card_new_data.proplist, PA_PROP_DEVICE_STRING, tmp); pa_proplist_sets(card_new_data.proplist, PA_PROP_DEVICE_STRING, tmp);
card_new_data.driver = __FILE__; card_new_data.driver = __FILE__;
pa_card_new_data_set_name(&card_new_data, tmp); pa_card_new_data_set_name(&card_new_data, tmp);
pa_log_info("Initializing module for CoreAudio device '%s' (id %d)", tmp, (unsigned int) u->device_id); pa_log_info("Initializing module for CoreAudio device '%s' (id %d)", tmp, (unsigned int) u->object_id);
/* get device vendor name (may fail) */ /* get device vendor name (may fail) */
property_address.mSelector = kAudioDevicePropertyDeviceManufacturer;
size = sizeof(tmp); size = sizeof(tmp);
err = AudioDeviceGetProperty(u->device_id, 0, 0, kAudioDevicePropertyDeviceManufacturer, &size, &tmp); err = AudioObjectGetPropertyData(u->object_id, &property_address, 0, NULL, &size, tmp);
if (!err) if (!err)
u->vendor_name = pa_xstrdup(tmp); u->vendor_name = pa_xstrdup(tmp);
@ -717,17 +753,22 @@ int pa__init(pa_module *m) {
} }
/* register notification callback for stream format changes */ /* register notification callback for stream format changes */
AudioDeviceAddPropertyListener(u->device_id, 0, 0, kAudioDevicePropertyStreamFormat, ca_stream_format_changed, u); property_address.mSelector = kAudioDevicePropertyStreamFormat;
property_address.mScope = kAudioObjectPropertyScopeGlobal;
property_address.mElement = kAudioObjectPropertyElementMaster;
AudioObjectAddPropertyListener(u->object_id, &property_address, ca_stream_format_changed, u);
/* set number of frames in IOProc */ /* set number of frames in IOProc */
frames = DEFAULT_FRAMES_PER_IOPROC; frames = DEFAULT_FRAMES_PER_IOPROC;
pa_modargs_get_value_u32(ma, "ioproc_frames", (unsigned int *) &frames); pa_modargs_get_value_u32(ma, "ioproc_frames", (unsigned int *) &frames);
AudioDeviceSetProperty(u->device_id, NULL, 0, 0, kAudioDevicePropertyBufferFrameSize, sizeof(frames), &frames); property_address.mSelector = kAudioDevicePropertyBufferFrameSize;
AudioObjectSetPropertyData(u->object_id, &property_address, 0, NULL, sizeof(frames), &frames);
pa_log_debug("%u frames per IOProc\n", (unsigned int) frames); pa_log_debug("%u frames per IOProc\n", (unsigned int) frames);
/* create one ioproc for both directions */ /* create one ioproc for both directions */
err = AudioDeviceCreateIOProcID(u->device_id, io_render_proc, u, &u->proc_id); err = AudioDeviceCreateIOProcID(u->object_id, io_render_proc, u, &u->proc_id);
if (err) { if (err) {
pa_log("AudioDeviceCreateIOProcID() failed (err = %08x\n).", (int) err); pa_log("AudioDeviceCreateIOProcID() failed (err = %08x\n).", (int) err);
goto fail; goto fail;
@ -757,6 +798,7 @@ void pa__done(pa_module *m) {
struct userdata *u; struct userdata *u;
coreaudio_sink *ca_sink; coreaudio_sink *ca_sink;
coreaudio_source *ca_source; coreaudio_source *ca_source;
AudioObjectPropertyAddress property_address;
pa_assert(m); pa_assert(m);
@ -805,11 +847,15 @@ void pa__done(pa_module *m) {
} }
if (u->proc_id) { if (u->proc_id) {
AudioDeviceStop(u->device_id, u->proc_id); AudioDeviceStop(u->object_id, u->proc_id);
AudioDeviceDestroyIOProcID(u->device_id, u->proc_id); AudioDeviceDestroyIOProcID(u->object_id, u->proc_id);
} }
AudioDeviceRemovePropertyListener(u->device_id, 0, 0, kAudioDevicePropertyStreamFormat, ca_stream_format_changed); property_address.mSelector = kAudioDevicePropertyStreamFormat;
property_address.mScope = kAudioObjectPropertyScopeGlobal;
property_address.mElement = kAudioObjectPropertyElementMaster;
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &property_address, ca_stream_format_changed, u);
pa_xfree(u->device_name); pa_xfree(u->device_name);
pa_xfree(u->vendor_name); pa_xfree(u->vendor_name);