Re: HALOutputUnit (Pt 2)
Re: HALOutputUnit (Pt 2)
- Subject: Re: HALOutputUnit (Pt 2)
- From: William Stewart <email@hidden>
- Date: Fri, 9 Jan 2004 16:05:57 -0800
Part 2
Channel Maps
A client can tell the AUHAL units which channels of the device it wants
to deal with (for eg. the client is dealing with stereo data, but has a
six-channel device). It does this by using the
kAudioOutputUnitProperty_ChannelMap property
This property should be used as follows:
For Output:
Create an array of SInt32 that is the size of the number of channels of
the device (Get the Format of the AUHAL's output Element == 0)
Set each of the array's values to -1 (-1 indicates that that channel is
NOT to be presented in the conversion)
Having initialized this array, now set the channels from the device
that you wish to see presented in your app's output.
For eg. We have a 6 channel output device, we have stereo source we
want to provide to the device, and we want that stereo source to go to
the 3rd and 4th channels of the device. The channel map will look like
this:
{ -1, -1, 0, 1, -1, -1 }
Where the formats are:
Input Element == 0: 2 channels (- client format - settable)
Output Element == 0: 6 channels (- device format - NOT settable)
(ie. Channel 2 of the device channels format should take the first
channel, channel 3 the second). (This would translate to the 3rd and
4th plugs of the 4 output plugs of the device of course!)
For Input:
Create an array of SInt32 that is the size of the number of channels of
the format you require for input (Get (or Set in this case as needed)
the AUHAL's output Element == 1)
Set each element of this array to the device's channel from which you
want to get the data.
For eg. We have a 6 channel input device, and we wish to receive stereo
input from the 3rd and 4th channels. The channel map will look like
this:
{ 2, 3 }
Where the formats are:
Input Element == 0: 2 channels (- device format - NOT settable)
Output Element == 0: 6 channels (- client format - settable)
Stream Usage
One important consideration to understand about how the AUHAL unit does
its work is the following. The HAL provides the ability to enable or
disable streams of a device that are/aren't in use in any particular
time. Many devices will publish multiple streams, (some devices may
just present all mono streams, some devices present streams that
associate to say its analog inputs (as one set of streams) and its
digital inputs as another.
Through understanding some of the topology of the device, and using the
channel map property as described above, it becomes possible for the
AUHAL units to disable streams which the client is not using. This can
lead to a considerable CPU saving as much unnecessary work can be *not*
done.
Audio Channel Layouts
- Default Stereo Channels
- Default Surround Configuration
This is best thought of as a feature that was fully supported in the OS
with Panther. AudioMIDISetup provides that ability for a user to
specify two default speaker/format configurations for a particular
piece of hardware:
(1) Default Stereo Channels
- ie. on a mulitchannel device, which two channels are currently being
used for the Left and Right Stereo speakers.
(2) Default Surround/Multi-channel config
- ie. which channels and which speaker format are being used
The AUHAL will automatically use the default stereo channels of a
device for any stereo formats. This enables applications like iTunes,
DVD Player, QuickTime to play stereo sound on the preferred stereo
speakers of the user. Thus, any user of the AUHAL unit will inherit
this automatic behaviour as described to the system by the user.
For surround, AUHAL will assume that a 4 channel stream is of the
channel ordering described by the AudioUnit channel layout for Quad
(kAudioChannelLayoutTag_AudioUnit_4 in <CoreAudio/CoreAudioTypes.h>)
For 5 channels, it will assume a channel layout of 5.0
(kAudioChannelLayoutTag_AudioUnit_5_0 in <CoreAudio/CoreAudioTypes.h>).
This is to preserve compatibility with existing pre-panther clients of
the AUHAL.
An application can overide this default behaviour through setting an
AudioChannelLayout on Input Element == 0
(kAudioUnitProperty_AudioChannelLayout property) to describe any order
(and for reliability it is advised that clients always set this
property.
Using the user's established speaker configuration as described above,
the AUHAL units will establish channel maps to map a client's audio
data to the device's output when this property is set.
Thus, if the client is providing a surround/multi-channel configuration
with a known/specifiable channel ordering, AUHAL will do its best to
map that channel ordering to the user's particular speaker
configuration. This should vastly simplify any UI an application has to
provide for surround output, as the user can specify this as a system
wide configuration.
AUHAL will *not* at this time do any mixing - thus there is no
down-mixing or other translations from say a surround format to stereo.
Thus, if the client is providing a 5.0 mix to AUHAL, but the user only
has stereo, then the user will only hear the first two channels of that
5.0 mix on their stereo speakers. The system provides other API
services for doing either proscribed downmixes between mis-matched
formats (or an app can of course do their own down-mixing as
appropriate).
AUHAL and Devices
The AUHAL units sit on top of the AudioDevice objects as defined in
<CoreAudio/AudioHardware.h>
A client can send property calls directly to the AudioDevice the AUHAL
unit is currently connected too by making the call on the AUHAL unit as
either AudioUnitGetProperty or AudioUnitSetProperty. (Underneath, the
AUHAL unit can detect that the property ID is actually a property of
the AudioDeviceID, and it will turn around and call the
AudioDeviceGet/Set Property calls for you).
An AUHAL unit only talks to a single AudioDeviceID entity at a given
time.
Except for the overhead of the AudioConverter that can be in place
between a client's buffer from the AUHAL unit and the device, there is
*NO* additional overhead to using the AUHAL unit. That is, there is no
incurred latency. The conversion overhead can be roughly estimated by
looking at the difference between the formats on either side of either
the device output (element 0) or device input (element 1). If a sample
rate conversion is established the quality of that conversion (and thus
the CPU load that is taken) can be adjusted using the
kAudioUnitProperty_RenderQuality property.
Bill
--
mailto:email@hidden
tel: +1 408 974 4056
________________________________________________________________________
__
"Much human ingenuity has gone into finding the ultimate Before.
The current state of knowledge can be summarized thus:
In the beginning, there was nothing, which exploded" - Terry Pratchett
________________________________________________________________________
__
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.