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