Re: Creating Aggregate Devices programmatically
Re: Creating Aggregate Devices programmatically
- Subject: Re: Creating Aggregate Devices programmatically
- From: Jeff Moore <email@hidden>
- Date: Mon, 1 Aug 2005 12:06:59 -0700
Wow that's a lot! I'll try to deal with it in place.
On Aug 1, 2005, at 7:44 AM, Dave Addey wrote:
Hi Jeff,
Thanks for the suggestions. I did a bit more experimentation, and I
narrowed
down the problem, as well as coming up with a few more questions.
Any help
once again much appreciated, and sorry for the long email -
hopefully the
testing will prove useful.
BTW, unfortunately I don't easily have any simple test code to
post. But I
would be very happy to send you a debug version of our compiled app
including this code, with debugging on, if that would help.
Can't hurt, but I'd really rather see source code. Helps narrow
things down. I guess I can code something up quickly to see what's
going on. However, AMS uses the same mechanisms you are using, except
that it's aggregates are, of course, all public.
First off, I found out what was causing the main problem. Seems
that if I
create the Aggregate Device as a public device, then it works okay.
However, if I add a value of 1 for
kAudioAggregateDeviceIsPrivateKey to my
dictionary, then things go all wrong. ("Go wrong", at least, when
working
with QuickTime AudioContexts). Although I *could* work with public
aggregate devices, I'd really rather not, as I'm creating them
behind the
scenes to output two movie tracks to two different devices, so they
serve no
wider purpose outside of my application.
In the private case, the aggregate device is correctly made as
private, and
still has the right composition and number of channels. However,
when I try
and play a prerolled movie through an audiocontext to this device,
no sound
comes out through any physical device in the aggregate device. If
I stop
and then play again (not pre-rolled this time, just playing from
the same
point), then the movie's audio is played, but through the default
output
device only, regardless of which devices are in the aggregate device.
Sounds like there could be a bug in the HAL somewhere, but it's
really hard to say given all the variables involved (your code, QT,
AUHAL, etc). Theoretically, the only difference between a public
aggregate and a private aggregate is that the HAL doesn't publish the
device to other processes.
Secondly, if I then dispose of the movie, it seems that the private
aggregate device is also disposed of for me. I don't really want
this to
happen! Sounds most likely that I'm doing something wrong here,
but I'm not
sure what. Do I need to be doing anything special or careful with the
CFDictionary that I pass in to the plugin for aggregate device
creation once
the device is created?
Disposing of a movie does nothing to the HAL. How do you know the
device has been disposed?
One thing I did as a test was to view the contents of the
CFDictionary for
an aggregate device created by Audio MIDI Setup.app, using
kAudioAggregateDevicePropertyComposition, to compare against my own
aggregate devices. From this, it looks as if I am passing in a valid
Dictionary, especially since the public device is working.
Like I said, AMS uses the same APIs and constructs you do.
My own devices have exactly the same composition as an AMS device when
queried via kAudioAggregateDevicePropertyComposition, but when
viewing my
public devices in AMS, they still don't have any audio input or audio
output, and show up with no devices enabled in "Configure Device".
Their
name also defaults to "Aggregate Device" in AMS, even though it has
been set
to something else by my application. This doesn't stop them working
- it
just might be indicative of something awry. Also, if I quit my
application
and then run it again, I am unable to use the device I have just
created,
and I also find that its name is defaulted to "Aggregate Device". (By
"unable to use" I mean that I am unable to set the current device of a
HALOuputAudioUnit to be the public device I previously created.)
What does HALLab say? Also, what system are you on? There were some
very important aggregate device fixes in 10.4.2.
Another (and perhaps most important) problem I have encountered is
that when
I play a QuickTime movie (with two tracks, in this case) through the
(working, public) aggregate device, there is a 1 to 2 sec delay
before the
movie starts playing, during which time nothing happens.
Prerolling the
movie removes this delay, but still takes 1 - 2 sec to do the
prerolling.
(This is on a Dual 2Ghz G5, 3.5Gb memory, OS 10.4.2).
Unfortunately, this
makes responsive starting of movies very tricky when responding to
user
interaction for triggering playback. Is this just the nature of
aggregate
devices, or is there anything I can do to reduce this time?
This is expected and can't be avoided. Due to their nature, aggregate
devices need to ensure that the clocks on the sub-devices have
settled out and are reasonably accurate. This takes a few time stamps
from each sub-device, which can be a second or two depending on the
devices in use. There is nothing you can do to change this.
Finally, my public aggregate devices don't seem to be being destroyed
correctly. Although I am calling
kAudioPluginDestroyAggregateDevice with no
error, the device still exists in Audio MIDI Setup afterwards.
Again, sounds like a bug. Please file it.
In all of these tests, I am using QT7.0.1, Mac OS 10.4.2, on a
PowerMac G5
Dual 2Ghz 3.5Mb RAM. I am using a MovieController to play a movie
through
an audiocontext to the aggregate device. The movie is opened via
NewMovieFromProperties, and one of the properties is an
audiocontext for
kQTContextPropertyID_AudioContext. Once the movie is opened, its
one stereo
soundtrack is cloned, and the two soundtracks are then separately
mapped via
AudioChannelLayouts to different channel pairs on the device.
Have you done any experiments that don't involve QuickTime? It's
possible QT has issues still to resolve with the unique nature of
aggregate devices.
Some asides on the subject of Aggregate Devices:
The CFDictionary obtained via kAudioAggregateDevicePropertyComposition
contains a number of extra key-value pairs which aren't mentioned in
AudioHardware.h, such as:
* a "name" for each SubDevice
* "channels-in" and "channels-out" for each SubDevice
...and other subdevice keys.
These seem to be being pre-filled for my own aggregate devices too,
even
though I don't supply values for them in my CFDictionary. Are
these extra
properties that I can set or should set? Or are they just set for me?
Certainly when I did try and pass in values for these, they seemed
to be
overwritten by CoreAudio when viewed using
kAudioAggregateDevicePropertyComposition.
Those are filled out and maintained by the HAL. They are for
informational purposes only and sometimes can be a bit inaccurate.
They're there so that applications have some knowledge about a given
sub-device, even if it is currently unplugged. You can fill them out
if you like. They didn't make the last deadlines to be included in
the headers for Tiger.
Another question: I noticed that the AMS-created aggregate devices
don't
contain a value for kAudioAggregateDeviceMasterSubDeviceKey, even
though one
of the devices is automatically selected as being the master clock
in AMS.
Do I need to specify a value for this in my CFDictionary? If so,
which of
the available devices is the 'best' candidate, or rather, what
criteria
should I use to select one?
If that key isn't present, then the HAL will use the first device in
the list.
The choice of the master clock depends on a lot of factors. We could
devote hours to talking about the ins and outs of proper synch setup.
Probably the best rule of thumb is to configure the aggregate to
reflect the reality of the hardware. The master sub-device should be
the same device that sources any hardware synch for other devices to
follow. In the absence of hardware synch.
It sounds like you may have stumbled into a few bugs in AMS or the
HAL or other places. Please make sure that you file these issues so
that we can be sure to remember to take a look at them and fix them
where appropriate.
--
Jeff Moore
Core Audio
Apple
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden