WWDC2001 Session 208

Transcript

Kind: captions
Language: en
good afternoon and welcome to the audio
services in Mac OS 10 session I'm Craig
Keithley on the USB and firewire
technology manager and worldwide
developer relations a lot of audio
devices these days are moving to
firewire and USB and we have a great
fondness of them we're especially
interested in seeing great firewire
audio devices using the M LAN standard
in the future we are working very
diligently to add that support and next
and an upcoming OS release I can't tell
you when or where the the thing that I
want to stress is I as I get ready to
introduce the the engineering team is
that Steve said in his keynote that one
of the developer feedback items we got
was audio support and I've been working
with the audio team and going through
their presentations and I think you'll
be very excited by what we've got so
with that I'd like to bring up Bill
Stewart the manager of audio software
engineering Thanks ok so I'd like to
just give you some overview of the audio
and many services that we have shipping
in Mac OS 10 today it came out with the
first version of Mac OS 10 and give you
some idea of the sessions that we have
at the conference this is the first
session and we're going to be mainly
focusing on the lowest levels of the
audio system how hardware is presented
to applications how applications can
talk to audio hardware and there's two
sessions tomorrow starting at 3:30 on
MIDI and MIDI services that are provided
in Mac OS 10 as well as the later
session of 5:00 o'clock is talking about
some high-level services such as
software synthesizers audio units and
audio unit graphs and in the MIDI
session tomorrow we'll actually go
through some detail about some of the
performance and latency characteristics
of rs.10 there's been some good and bad
usually misinformed information about
that and we'd like to sort of present to
you some information that we've got
based on some of the tests we've done
and
so the keynote on Mondays so there's
there's some information would like to
give to that and that'll be mainly in
tomorrow's session so before I bring up
Jeff Moore who will talk about the the
bottom layers of the system I thought I
should give you some overview of what is
on ten some of the things that we had in
mind when we were designing this system
and some of the concerns that we sought
to address by re architecting the system
so I think flexible audio format what
does that mean well we've seen audio
come a long way since two channels was
the king of the day and we've now got
multi-channel fairly commonly placed in
a lot of different areas not just in the
pro audio world but in consumer devices
in games and so forth we also realized
that there's a need to address the PCM
format which is a standard sort of audio
format where you've got the Royal sample
data there and there's also a lot of
devices coming out now that deal with
non PCM formats like devices that will
take encoded format in say a c3 as a DVD
player or something so we needed to take
that into consideration we also wanted
to preserve as much of information as we
could if we're going to be doing signal
processing a lot of the devices are not
just 16-bit devices anymore you you'll
have resolutions on the devices up to 24
bits and when we were discussing this we
thought that the best way to do this not
only from a DSP point of view but also
in terms of representing the hardware is
to present that in a format that is
capable of being preserving the
integrity and the the resolution that
you require and also as many of you
aware sample rates have gone up quite a
long way since 44.1 K was the standard
and so we needed to address that issue
another thing that we wanted to do in
the professional world you typically see
a very strong focus of audio being
generated and controlled by one
application
and in an operating system-level that is
not going to fly or it's not going to be
particularly useful for applications
that may want to generate audio and they
may not be the focus application or they
want to cease beep and in the background
all kinds of things like that so if
you're going to have multiple
applications talking to the audio system
you you then also got to understand well
what might be an appropriate latency for
one application is not an appropriate at
latency for another application so we
wanted to design a system that took care
of those issues and that applications
operate at a level of detail that they
were comfortable with another weakness
that we saw with the existing sound
manager stack on Mac OS classic systems
was we sometimes had no idea what time
it was if you look at the samples that
are coming in or samples that are going
out you can sort of guess at some of the
time information that should be around
those samples but you may not exactly
know what time it is and that has a lot
of ramifications for how you deal with
synchronization with other media with
hardware that may be doing both video
and audio so we wanted to address that
and if some of you know my history I
have a particular fondness for Java so I
felt we should present these services
not just to C programmers but also
present an API for the Java platform
that would be comfortable for people
that are working in that space this is a
diagram of the architecture that we have
the white line in the diagram is the the
difference between the kernel space and
then above it is the different user
spaces as you all know Mac OS tends a
memory protective system each client has
its users base as its own memory address
mapping so below the white line you've
got the kernel and the i/o in Mac OS 10
is handled by i/o kit io kit is a set of
classes to deal with different types of
buses and different types of hardware
like PCI etc if I
USB and the above-the-line the first
layer that you see for audio is called
the audio hal hal stands for hardware
abstraction layer and the main services
that you would expect at that point is
that the audio hell is going to cross
the boundaries women needs to in order
to talk to hardware and each user client
of the system is going to see different
versions of the hell but then there must
be some global state if you've got two
apps talking to the same device for
instance and so we'll be going through
in today's talk about some of the stuff
that goes on there and then on top of
that in the client process you have
services that in on the left hand side
or now your right hand side you've got
classic and classic talks to the audio
hell in order to talk to hardware in the
second process you may have the carbon
sound manager and that talks to the hell
to talk to hardware and then audio units
are some processing units it's part of
the audio toolbox stuff that we'll be
going into a tomorrow session at 5
o'clock so the core do framework we have
frameworks on 10 and that's how
libraries and their header files are
presented to users the cordilla
framework has the audio hell that's
where you find that there's an audio
hardware dot H file in there that is
where you find the api's and typedefs
and so forth for interfacing to the
audio hell it has basically the audio
device is the primary object we'll be
going through this in some detail today
the audio toolbox and audio unit
frameworks the high-level frameworks
I'll be covered in detail tomorrow Audio
toolbox the aim there is to provide a
set of tools that you can use in your
application to do audio tasks like
sequencing a MIDI file dealing with
different types of events that might
translate to some changes in audio
behavior like generating notes on a
software synthesizer or
panning a sound from one channel to
another over time and if you've got a
sequence of events you need some object
to apply it that's what the music player
does
Audio Units I suppose the best way to
think about this is is like a plug-in
it's a way of taking audio of making a
component that will take audio in do
something to it and spit audio out but
some audio units may just generate audio
they may not have any audio input a good
example that would be the software
synthesizer and somehow Audio Units may
just sort of end there you don't see
anything come out of them at least from
the application point of view you might
get audio into them and see nothing out
and later on in this talk we'll be
talking about a unit we call a default
output unit and I'll leave the details
of that until later this afternoon just
to talk a little bit about sound manager
that's in carbon carbon sound manager
it's nearly equivalent API between
what's on tenem what's in the classic
there's some deprecated API is that we
removed one that was very unpopular but
we've been telling you for a long time
we're going to remove it anyway so we
thought we would which is sample a
double buffer there is some sample code
up on the website if you want to see how
you can provide that capability yourself
I think an important thing to understand
about the two the two platforms is the
different roles the sound manager
performs on both of those platforms on a
classic system the sound manager is a
global state you can really see the
whole state of sound manager from all
the different applications and stuff by
looking at the sound manager and in a 9
it also provides the hardware model we
have esterday of components we have
input drivers input components and
things like that that really do
interface directly to the hardware and
for better or worse this was the way
that if you wanted sound manager and
clients of sound manager like QuickTime
to talk to your audio hardware you had
to write components for the sound
manager our Mac OS 10 the sound manager
is quite different it's a client of the
audio system and the audio system we
have on 10 is really called core audio
which is what these talks are about on
Mac OS 10 the sound manager is per
process you don't have
any idea what's going on in another
process through sound manager calls it's
only what's happening in that particular
process it also does not provide the
hardware model the lower levels of the
sound manager on 10 talked to the hell
and the hardware model for audio devices
are provided by IO kit specifically by
the IO audio family classes and support
capabilities so that's an important
distinction to understand and another
important distinction I think is the
sound manager has a native format of
16-bit integers it doesn't deal very
well with formats beyond that doesn't
deal very well with stereo with anything
beyond stereo and these are all
limitations of we hope we've completely
gone beyond with cordilla where you can
have n channels of data where you can
deal with floating-point 32-bit as your
primary generic format we also on Mac OS
10 provide many services this is a
complete representation and complete
publication of capabilities of MIDI
devices it's really an evolution rather
not of the MIDI manager that you see
that Apple did quite a while ago but
more in the spirit of OMS or free MIDI
as it was on Mac OS 9 the difference
being that this is actually provided as
a system service by Apple and is
supported by Apple as a a MIDI
architecture we also provide services in
the MIDI architecture for inter
application communication you can create
what are called endpoints that allow
your application to register to the rest
of the system as it to the rest of the
applications on the system as a virtual
destination or a virtual source of MIDI
data we also share the same time
stamping structures between the MIDI and
the audio system so it becomes very easy
to understand the timing of events in
the MIDI system or the timing of buffers
etc and the audio systems and how you
might need to do translations between
those two things as a common set of
services for that and we'll be going
through this in the middie specifically
in the middie section tomorrow at 3:30
devices what devices well Apple
currently supports the USB audio plus
driver as I was a moderate USB audio and
many i've got two slides for this so we
support obviously built-in hardware most
of apple's built-in hardware is 16-bit
44k stereo USB provides a completely
different thing and we'll show you some
of the extended work that we're doing to
make sure we do support USB audio as we
should on the platform later in this
session
firewire audio as Craig mentioned
earlier very we consider this at Apple
to be very important technology going
forward for audio particularly for the
pro audio space for for the high
performance and the kind of stringent
demands of pro audio wants firewire
audio is really comprised of two things
as 618 83 - 6 transport layer it took me
months to remember that number and I can
get it now and the M LAN connection
management the transport layer is just
how do you put audio and MIDI data
across firewire bus air main connection
manager is intelligent information that
the devices can publish about their
capabilities to other firewire devices
and allows for configuration of a
network of audio or MIDI devices we are
at Apple a signatory of the Emlyn
connection management stuff and we will
certainly be doing I think some very
interesting work in this sphere going
forward and it's a very similar story
for MIDI we actually do provide a USB
MIDI class driver we also in as
developers example code provide a sample
code for vendor specific USB drivers so
it's very easy if you're publishing a
vendor specific USB MIDI device to just
sort of take that code as a basis and
then provide a driver which many people
in this room will probably would like to
use yesterday
and we also have firewire
plans for MIDI as part of the emulating
connection management so you've had
enough of me I'm going to bring up Jeff
more now Jeff's engineer been working on
the audio hardware abstraction layer and
please make him welcome thank you my job
here is to kind of delve into what the
audio hardware abstraction layer is all
about so as bill said it provides the
lowest user level user level access to
audio devices on the system its role is
to efficiently move data to and from the
device it also allows you to manipulate
device attributes like the volume the
sample rate mute whatever and it also
provides very strong synchronization
primitives to allow you to make sure
didn't know what's going on in any given
time the hardware the design goals that
we had for the Hal primarily the first
foremost to clean low overhead signal
paths we don't want to introduce any
distortion into your art into your
signal at all and further we want to get
out of your way we want to make sure
you're it's getting out to the hardware
as fast as it can
another big big-ticket item is multiple
multiple simultaneous client access to
single audio devices that's been a
hallmark feature the Macintosh for ever
it would we needed to carry that forward
and then it's to break through some of
the bottlenecks we add on OS 9 you know
more channels higher bit depths higher
sample rates and then again you know
synchronization it's like I can't say it
enough I mean it's like one of the most
important things that we do now with
audio on 10 and then finally we came up
with a pretty small API but it's fairly
complete we think that it should cover
the majority of the needs that people
will have to do when trying to get
manipulated to do their hard audio
hardware the API itself is object
oriented C code that's not Objective C
code but it has a Java interface as well
and since its object oriented it has two
major objects it has
a device object which basically
encapsulates all the information need to
know about and access to the the actual
device and then there's a kind of a more
nebulous object which is a global
context which allows you to access to
information about the system such as you
know the device list and whatnot so
every object in the system has
properties and would and properties
manipulate the different aspects of the
object things like the name the buffer
size volume a channel - whatever oh you
can pretty much describe anything about
a device in terms of properties the
actual property itself is a unique
identifier it's a 32 bit int and they
can have an arbitrary amount of data and
there is no self description mechanism
like you get from an apple event the
data types you get are agreed on and
they're documented in the header files
and it's also important to know that
some of the properties are only
read-only you need to make sure you're
checking with the device before you try
to set a property some devices may allow
you to change the sample rate some may
not and then finally another big
important thing about properties is that
you can sign up for notifications for
when things change so if someone changes
the system volume you can find out about
it so the global heart the global
properties are all referenced using the
routines in the API that use the prefix
audio Hardware the constants and
everything will pretty much that pertain
to the global context you'll see the
words audio hardware and their names
somewhere the important properties when
you're looking at the global space are
the device list which is and the default
input and output device and then there's
a kind of a fourth property which is
whether or not you want the the machine
to idle sleep while you're playing sound
by default that's disabled so that idle
sleeping won't happen while you're
playing sound much like it happens on OS
9 so here's a code example of how you
would go about getting the device list
the first step is to call audio hardware
get propertyinfo because the device list
is documented to be a variable length
array so you need to find out how much
memory it's going to take up so one of
the parameters you get back from audio
hardware get property info is the actual
size of the data and you can see and
then to get the number of actual devices
you divide the size you get back which
is in bytes by the size of an audio
device ID then you allocate the memory
to hold the list and then you call audio
Hardware get property and you pass that
memory you just allocated in and the how
will go then and fill out all the device
IDs for all the devices on the system
and then you can peruse and get
information about those devices and use
which devices you want that best fit
your needs so and then once you have a
device you know all the little routines
again we use audio device to refer to
the things that maple 8 devices as
you'll see devices are addressed with a
very specific protocol you need to make
sure you're telling your asking about an
input or an output property and exactly
what channel you are talking about the
how is simple but it's also very
particular about doing things like that
the important properties that you'll see
with with a device are of course the
buffer size of the device for doing the
i/o transfers an important thing to
realize about that is the buffer size is
not just settable by the application its
settable for each application
individually so one application can have
can be communicating with a device at a
buffer size of say 64 frames and another
another process could be communicating
with the same device with a buffer size
of 2048 frames it gets its what Bill is
talking about when you were talking
about controllable latency on a per
process basis we think this is one of
the big new features of audio on 10 and
then you'll also want to know things
about how the layout of the device and
you can
is the stream configuration property to
find that out and then things like the
volume and mute and what data source
you're talking to and they're all
individual properties for the device so
here's a code example of how you would
go about setting the volume of channel 2
on a device so first thing you need to
find out if you actually can set the
volume of channel 2 and again you use
audio device get property info and you
can see how I'm being very particular
about specifying channel 2 and I'm also
making sure I'm finding out ahead of
time whether or not I actually can set
the property and then when I figure it
out then you just turn out and call
audio to my set property and in this
case the volume scaler is a floating
point number from 0 to 1 and this
example we're setting the volume to
full-on so now you kind of know your way
around the API a little bit so now it's
time to talk a little bit about how you
actually get audio data to the hardware
we rethought how i/o was going to be how
audio i/o was done to take advantage of
what OS 10 really does well in
particular OS 10 is really good at
handling shared memory and and threading
and things that OS 9 really wasn't as
good at it's a little less what good at
things like hardware that has higher
degrees of high rates of interrupts
being fired so we had to work around to
all these different constraints and come
up with a system that could deliver the
performance we were looking for with how
kind of having to re-architect the
entire kernel from the inside out so the
way the model we came up with is
basically with the hardware and the
house share they have a ring buffer that
is a pretty large ring buffer it's about
three-quarters of the second size for
most for most drivers and that one ring
buffer is shared all across the system
so and the hardware tracks its progress
through the ring buffer by time stamping
that the point at which it wraps back
around so
the DMA engines cycling through the
buffer and when it jumps back around it
will it'll generate some timing
information and that is also
coincidentally the only time when you'll
see a hardware interrupt so the hardware
rate the interrupts rate of the system
is gone way down compared to OS 9 and
this is much less taxing on the system
you get better throughput the rest of
the system is a lot happier and as
people are finding audio is becoming
more and more integrated in what you're
doing in other parts of the system so
it's really important to be well-behaved
so once it's so to move data in and out
of the ring buffer the help provides and
what's called an i/o thread and each
device has a single i/o thread in each
process in order to call your function
that will provide or consume data this
thread is a mock real-time thread the
reason why we do that is that mock
real-time threads have certain
guarantees about the level of the level
of accuracy they will get for latency in
scheduling so when the House says this
thread needs to wake up at such-and-such
a time because it's a mock real-time
thread we're pretty we're pretty
guaranteed to that it's going to wake up
pretty close to when we asked it to and
then the how also use another lower
priority thread in order to handle all
the property notifications and um the
the client can actually have some can do
barrier control over the priority and
timing characteristics of that thread
using the audio hardware property run
loop to tell the how about your own CF
run loop that you want then your
notifications fired in so I'm gonna walk
you through kind of the algorithm of the
i/o thread so you kind of have an idea
of what's going on kind of behind the
scenes so the first thing that happens
is when you when the how first enters
the loop of the work loop of the i/o
thread is it goes to sleep the reason
why is that it needs to prepare for
input data needs so presumably the
hardware has just started up and now it
needs to wait for the first full buffer
is worth of input
data so the very first thing it does is
figure out when that's going to be and
then it puts the thread to sleep until
then so then when it when it comes back
and wakes up presumably all the input
data and if it's there is available now
so it calculates what the actual
timestamp is of that of that input data
and then it calls down into the kernel
to actually fill up all the buffers out
of the ring buffer the the driver itself
has complete control over the transfer
out of the ring buffer and into the
clients buffer and then the same is true
for output but in this case we're about
to call out to ask the client for output
so we have to figure out when we want
the client when that what time it is
that we're asking the client for audio
and then we set up their buffer their
audio buffers by clearing them out the
one thing that you should take is that
the hell does is that it tries to
isolate you as much as possible from
other clients on the system so you don't
have to worry about necessarily
accumulating to a buffer or worrying
that someone else is going to have
already written data there and then once
we have the input and output data
marshaled we then call out to all the
client IO procs and I'll talk a little
bit more about writing i/o procs in a
minute so once the i/o procs have all
assembled presumably they've consumed
the input data and they provided the
requested output data the how will then
have to call down back down into the
driver to mix the provided data into the
system's mix bus this is all part of the
shared device management we have and
it's also the main reason why we use
float32 as our lingua franca as far as
sample formats go we want to maintain
the the the Headroom of the mix as close
to as far down and as close to the
hardware as possible to minimize the
amount of distortion added to this to
the signal then once we've handled the
mixing the hell will also then handle
any reentrant actions that might have
occurred in by calling out to the client
i/o procs for instance you might want to
adjust the buffer size on the
- you know to adjust your own
performance you know or whatever and
that couldn't happen like right in the
middle of the handling everyone else's
IO proc so the Hal has a mechanism for
catching those circumstances and
handling it
after that complete IO so guys as
completed so this diagram right here
kind of illustrates the the flow of
control we're really the kind of the
timing of things of when the when the IO
thread is executing so you can see the
the red arrow kind of indicates where
the hardware actually is in terms of
consuming output data and the blue arrow
shows where the IO thread wakes up in
order to allow the clients to render
buffer for what's being pointed at by
the green arrow the overall performance
envelope through this mechanism is
equivalent to the performance you would
get from a double buffered scheme the
house almost will always be asking you a
buffer ahead of when of a buffer ahead
in time of the for the data that you're
actually gonna very rendering so next up
you're going to need to have an IO proc
for the IO thread to call so you
register your I Oh proc with the device
and then you have to start and stop them
you do individual transactions on
starting and stopping based on the IO
proc not on the entire device and the
reason why is that these guys are shared
across the whole system when you saw in
when you register your IO proc the
hardware may already be in use by
someone else in a different process so
we manage the state relative to the IO
proc so so when you start your IO proc
the device will only start if this is
the actual first i/o proc on the entire
system that is starting up on that
device and con then the converse is true
with
stopping the device so when your i/o
proc is called you're gonna receive all
the input data and you're going to be
asked and you're going to be provided
with a buffer in which to write all the
output data for that time slice and
there are always there they're going to
be timestamps that tell you exactly
what's going on where those buffers are
belong in the timeline the input data
will tell you when the input timestamp
will tell you when the first frame of
the input data was acquired and the
output timestamp will tell you when the
first frame is going to be written to
the written out to the hardware and the
the final timestamp is is also the
current time so it kind of is which as
you'll see it from the previous diagram
it kind of Falls it kind of in between
that kind of gives you kind of some dead
reckoning on what's going on in the
system you might use that to sync other
subsystems to what's going on in the
hardware so when your i/o practice
called we pass everything in the data is
passed into your i/o proc using an audio
buffer list data structure an audio
buffer list is a collection of
individual audio buffers and you'll get
a buffer for each stream that the audio
device has and you can think of the
stream in this case as being a single
interleaved container for the data so a
device might have two streams that have
two channels in each stream and the
audio buffer list will reflect that that
your that you'll receive so it what
we're really trying to do is kind of
mimic what the hardware is presenting to
the to us to you and you can find out
ahead of time what that's actually going
to look like by using the stream
configuration property so that if you
want to set up do you want to know
what's going on so you can set up your
bloops or whatever it's it's the
informations there so this is kind of a
is a code example of an actual i/o proc
you can see this this slide has the
prototype of an eye
you see the you get the device ID you
get all the time stamps you get the
individual audio buffer list and you
also get a client data pointer you know
aka a refcon from OS 9 and you can use
the client data pointer for anything you
want in this case this I up Rock I'm
using the client data pointer as a
pointer to my C++ object that has my
audio engine in it so basically you have
to make sure you're in the IO proc you
make sure you're checking for No the
device can change format on you between
calls to your i/o proc it could change
format on you between your call to the
getting the format of the device and
your i/o proc the only way to be sure
you know what's going on is to sign up
for notifications on the format
properties but in the i/o proc you
should always make sure you're doing
your sanity checks or you will crash and
die horribly so in this case we're
basically doing all that it passed the
input buffers and the input timestamps
to my engine in this slide we see the
how you actually register and unregister
an i/o proc it's pretty straightforward
a diaphragm of i/o proc and you can see
how I'm passing in the pointer to my
engine object in this case as well and
then starting and stopping is very much
similar there's individual calls to
start and stop and next up I'm going to
bring up Doug Wyatt and he's gonna use
another engineer for core audio and he's
going to talk a little bit about the
default output unit which is gonna allow
you to ignore everything I just told you
about
thanks Jeff
you won't have to ignore everything
about it because there's some parts of
the default output unit that dulled on
top of the Hal data structures as we'll
see I also wanted to just correct
something bill said earlier the two
sessions tomorrow the earlier one at
3:30 is the one on the audio toolbox and
audio units and the later one at 5:00 is
on on MIDI you have the x reversed ok so
the default output unit is a component
that provides you with a slightly
simpler API to the how you don't have to
worry about receiving quite as many
notifications and it builds in a sample
rate converter for you so if you want to
render data at 22 K you don't have to
care whether the hardware is at 44 K or
48 K you can just render your 22 K data
say I want to sample rate converter in
there and it'll do the conversion for
you so I'd like to just walk through a
simple example of using the default
output unit it doesn't take a whole lot
to write a program to generate sound
this way there's a call open default
output unit to open the component audio
unit initialize to initialize it and
here we're going to manipulate the Hal
device so first we want to find out what
it is and we make the call to audio you
name get property passing the the
property constant K audio output unit
property current device we passed the
global scope I'm not sure that's
necessary but it's the best choice and
we'll get back the audio device ID of
the current device and here in this
example we're going to set our clients
buffer size to 64 frames which is only 1
and 1/2 milliseconds we're going to
render some audio in a very responsive
manner
so we're calculating the buffer size in
bytes 64 frames times the number of
channels which was probably 2 but could
be more depending on how you know we
would have interrogated the stream
format of the device to find out for
sure in case it's 64 times the number of
channels times the size of a float and
then we're making a call to the how
audio device set property to change the
buffer size at which this client will
get called or rather the interval at
which this client will get called to
render data having done that the next
thing we'll do is set up a sample rate
conversion in this example I want to
render data at 22050 Hertz I don't care
what the hardware sample rate is so
there's a property on the audio unit the
default output unit called K audio unit
property sample rate now here the scope
is important because this audio unit if
you ask it for its sample rate in the
global scope it will give you back the
hardware sample rate whereas if you want
to manipulate or interrogate the input
sample rate as you would you know in
this example you're saying I want to
render at 22 K so we're telling the
audio unit yes my input is at 22 K and
so we're passing a G sample rate
and the next step is to provide a
callback function to the audio unit to
tell it here's a function in which I
want to do my rendering and this is kind
of a simpler version of the house i/o
proc as we'll see in a moment we fill
out an audio unit input callback
structure with a pointer to a function
the refcon here is is null but it can be
any piece of data that you want access
in your renderer then we make another
call to audio unit set property with the
constant K audio unit property set input
callback also in the global scope and so
that's telling the audio unit whenever
you want to render data call me back at
this function and here's an example of
what a rendering function looks like
like I said a moment ago it's pretty
similar to the Hal rendering function
the first parameter you get back as your
ref con you get some flags whose well we
don't need to go into those they're
usually not used you get the the
timestamp for output you're getting a
bus number which is relevant when there
are multiple streams of audio and you're
getting an audio buffer which is one of
the buffers that the Hal provided in its
callback so you can look at that io data
parameter which is an audio buffer and
find out how many channels are in it
what the buffer sizes and bytes and from
that we can compute the number of frames
we can set up a local pointer sample
pointer is a float 32 and treat that as
an array into which we can fill our
sample data and that's pretty much all
there is to rendering to the default
output unit after having gotten all that
prepared we can just make a call to
audio get output units start the hell
will get fired up it'll start running
our rendering proc will start getting
called back we can synthesize sine waves
or horrible noises or whatever
we want and when we're done we can call
audio units stop audio output units stop
rather and when we're completely done we
can call clothes component to get rid of
it so that's the default output unit and
it's a pretty simple and high-level
interface to the help so the stem oh I
believe is Jeff's I'll turn it back over
to you thinks so so we're gonna do to do
now is the very first time I think we
had demonstrated on an Apple operating
system built-in system services for
multi-channel outputs and multi-channel
sound output so I'm just gonna go ahead
and play it and tell you a little bit
more afterwards
this is a test this is a test the
emergency broadcast system this is only
a test
[Music]
this is only a test so first thing I
want to do is kind of show you what what
we're using here this is a stock Wall
Street powder power book running OS 10
with a USB PC card attached to it this
is the e magic mi-26 thank you a magic
that's and this is so this is on sale
today and it's using our stock built-in
USB audio class driver this is all built
into the system it's it's it's great a
couple other things I want to show you
about this little test app here this
little test app is in the slash
developer examples core audio directory
it was written by one of our other
engineers Bob Aaron to kind of extra
kind of demonstrate what what's going on
in the how and kind of where
everything's at you it kind of gives you
a Friday user interface for all the
different little properties you'll see
in the header files in particular see it
shows the buffer size in bytes and in
frames it shows you all the format
information that you might have for the
for the device it allows you to change
the format and then it gives you
individual controls over the hardware
for for as long as the hardware has it
implemented yeah you can you notice in
this case that the that this device only
has a master output volume and a master
mute so you can see it now I'll switch
to the built-in
Audio the built-in output device and you
can see it has two left/right control
individual channel controls and no
master but it does still have a master
mute the hell does not abstract this
away from you if you're looking for a
master control it may not be there you
need to be prepared for that the house
not going to hide what's going on in the
hardware from you too much it's good
obviously it's gonna abstract a little
bit of stuff away from you obviously the
sample format being one of them but you
can see that you know there's a whole
lot in here and I encourage you to go
and build this code example yourself and
play with it and those you bring it up
hardware this is a great test tool to
figure out if you're doing everything
right so I think I'll play that again
and kind of give you that's a the the
the the track I'm playing here is a 5.1
mix that's it's a 6 channel AIFF file
that I authored last week so I'm think
I'm just gonna go ahead and play it
again
turn the volume down
it's too quiet I'm gonna turn up again
[Music]
[Applause]
don't really have too much else to say
about about this app I probably should
tell you what it's called this is the
app is called Daisy and then you have
the source code it's already installed
in your system if it's if you install
the developer tools and I think that's
pretty much it can we go back to the
slides please and next bills gonna come
up and tell you more about Java so we'll
be doing some Q&A and stuff in a minute
so don't all rush off unless you want to
get to the beer bust but we're going to
keep you too much longer I hate to keep
a man from his beer so I don't actually
have any examples today that I want to
show you about the cordilla Java stuff I
do have some stuff tomorrow that I'll go
through the audio hardware and the audio
device stuff is in the cordilla Java
it's in actually a common apple audio
dot hardware package you'll see the same
kinds of api's that Jeff was talked
about start-stop you've got audio device
IO proc as a Java interface that's you
implement that interface and then you
instantiate that interfaces your
callback in order to render data for the
audio device IO proc the
while output audio unit is there as well
one thing I'd like to add to those
comments is that that will the the
reason the default output unit is there
is two-track choices that the user might
make in the system control panel when
the system control panel will let you
make choices which it currently doesn't
so you might imagine that you you could
have a user that might have two or three
different audio devices on their system
and I would like to say well maybe you
know default output device will be the
USB guy it will be built-in audio and
the default output unit will listen for
those things and it will switch
automatically for you so your
application if you're just doing basic
audio stuff this becomes a very useful
service at the bottom and it's the same
kind of service of the sound manager
itself sits on top of the default output
unit is is actually an extension of
something we call a howl output unit so
if you if you're writing audio units or
you're using audio units to do your
application you can use a hell output
unit just to talk to a particular device
or you can use this guy if you want to
track any changes the user might make to
their system and as Doug said he showed
you you're setting the sample rate you
can also not have it to the sample rate
conversion if you want to take care of
that detail yourself it's not a
requirement that it does that for you
with the cordilla Java stuff there's
Java doc that's available and that I'll
give you some URLs at the end of this
talk for that sinus stuff regardless of
the language that you use we we're
really not sort of language centric in
the choreo group because I'm there I
suppose more than anything else
otherwise it obviously plus plus but so
we really kind of stress that you should
understand the architecture whether
you're going to approach the dealing
with the API through C or C++ or through
Java you really need to understand the
architecture of how the system is
working what are the underpinnings of
the system and these are really not
language constructs their architectural
constructs that you should do so when we
talk about an API and for the Java
platform we're not talking about any
additional capability we haven't
rewritten this whole thing
in Java it's not going to be portable
because it's based on a native audio
engine but we're just providing an
access to it from Java so some of the
stuff that you see today if you go home
on your Mac OS 10 system now and you run
dayz you'll see it looks a little bit
different than the version that we're
running the we've done additional work
since Mac OS 10 was released in order to
support the USB stuff that we were
showing today and we are very interested
in doing technology see obviously we're
going to release this stuff to the
broader community as soon as we can I
just don't want you to sort of get a
false expectation of going home and
trying it doesn't work and then you're
going to abuse me so you can contact us
I'll give you an email at the end of the
talk today about contacting us if you're
interested in getting technology
stealing from us and of course you know
we were close to releasing this to the
general public as well so another thing
that we're sort of announcing today is
we have a mailing list up Apple sponsors
a website called list opal calm these
are not really apples Apple run lists or
anything they're really a service to
Apple developers and the Apple community
that's basically there you can get it
from Apple but these aren't sort of like
Bozo in some way official Apple mailing
lists but they're not official Apple -
they're your mailing lists they're not
censored or monitored by people at Apple
they're really it's your resource that
you can use you can support each other
with it we obviously like to be involved
in these things and we do now have a
core audio mailing list and I'm pleased
about it and you can get there at least
opal calm and you'll see the choreo list
and we'll field any questions there on
Java core do stuff on the MIDI stuff on
the things that we'll cover tomorrow in
the talks and also today we have a
website up that actually talks about Mac
OS 10 audio for the first time and it's
developer.apple.com slash audio
we're also this close to documentation
we realize it's be a very very
frustrating experience
for us and probably for you about well
this stuff is there but how do you know
about it because we're not telling
anybody about it it's sort of a best
kept secret but up on the audio website
there will be a PDF it's a draft only of
the Claudio api's but and we're doing
more work and we'll update that in the
future if that's not available by
tomorrow then it will be available early
next week and it's a pretty good sort of
first pass and we're also on the mailing
list so if you know you get the
documentation you've got SDK examples
and you were more than happy to answer
questions and help you with problems or
you know listen to your feedback so we
really welcome your input okay there's a
sound and networking for games session
tomorrow and then there the two times of
the sessions and they're the right times
not the wrong times I'll come back to
this slide probably okay so if you've
got any questions on firewire or USB as
Craig said earlier this is you know
stuff that we've fairly involved in with
the audio community so you can contact
Craig at that address and develop the
seating which I talked about earlier you
can send us an email and we will
certainly consider your request
you