• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Creating Aggregate Devices programmatically
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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
  • Follow-Ups:
    • Re: Creating Aggregate Devices programmatically
      • From: "B.J. Buchalter" <email@hidden>
References: 
 >Re: Creating Aggregate Devices programmatically (From: Dave Addey <email@hidden>)

  • Prev by Date: Re: SPDIF audio in DVD Player
  • Next by Date: Re: SPDIF audio in DVD Player
  • Previous by thread: Re: Creating Aggregate Devices programmatically
  • Next by thread: Re: Creating Aggregate Devices programmatically
  • Index(es):
    • Date
    • Thread