Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2002-008
$eventId
ID of event: wwdc2002
$eventContentId
ID of session without event part: 008
$eventShortId
Shortened ID of event: wwdc02
$year
Year of session: 2002
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC02 • Session 008

DiscRecording APIs

General • 54:24

New for the next release of Mac OS X! Want to be a recording artist? Learn how to integrate disc recording capabilities and burn CDs and DVDs directly from your application, using the same APIs that iTunes uses. This session explains the overall architecture of DiscRecording and then goes in-depth on the Core Burn Engine, Content APIs, and DiscRecording UI.

Speakers: Drew Thaler, Mike Shields

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

First of all, if you thought this was the session about zero configuration, it's not, and nor is it the Sunday flea market. The last song is the theme song for the team that is going to be talking to you today, Burn Baby Burn. This is all about disc recording, burning Anyway, it's the nicest looking crew of engineers at Apple.

Clean cut, nice guys, all dressed nicely today. And they want to talk to you about the DiscRecording APIs. DiscRecording APIs are interesting to me in my role at Apple, primarily because they provide for a very consistent user experience for users, burning CDs and DVDs and whatever they're doing. It's also a really great technology and they're going to explain how you can build in disc recording capabilities in your application just like iTunes has them built into it. So I'd like to talk to you through this stuff. I'd like to introduce Drew Thaler.

Welcome. All right, so I'm here to talk to you about the DiscRecording APIs. And my name's Drew Thaler, and I'm from a group at Apple that you might not have heard of before. We're called Burning Issues. That's because we handle all the issues to do with burning. So today in the session, we're going to go over a little history of burning, what it used to be like, and what it's like today. We're going to tell you about DiscRecording, and we're going to go into the different parts of DiscRecording. We're going to have lots of demos and lots of sample code.

So let's talk about history. Way back a long time ago, like 1999 or so, I'm not that young. So burning was only handled by specialized burning applications. You had to--you know, if you had all your music in one thing, you exported it or did something special, created an image, copied things onto a 700-meg hard drive, did whatever you needed to do, and it was all handled by this specialized burning application.

All the content creators and the organizers weren't directly involved. And especially as people started doing a lot more with digital media, it kind of got to be a pain because you just had this one application. If it didn't work, then you were stuck. It was kind of painful.

And then something happened. Or, well, let's go to this slide instead. Let's talk about why burning is so hard. The basic answer is it's just really difficult. If you want to add burning into your application, it's several years of work, literally. You need a team of people working for about a year.

You need to be able to talk to a lot of different layers of the operating system. You really need all up and down the stack. You need your application layer. You need to talk, you know, in Mac OS X, we're talking to I/O Kit, we're talking to the kernel, we're talking to services that most people haven't heard of, such as disk arbitration. And then on top of all that, you have to be able to talk directly to the CD drive. And a lot of different drives, if you write applications that talk to hardware, not all hardware behaves exactly the same. You get some quirks in between different drives.

The next thing you have to do is you have to stream your data from beginning to end, because that's the way CD burning works. You start at block zero and you write all the way to the end. - And when you're doing that, if you're burning, for example, a data disk, you're burning a special cross-platform file system.

It's not HFS+. You might be burning HFS+, but you're burning-- more likely you're burning, along with HFS+, something like ISO and Joliet. These are file systems that aren't designed for random access. It's not easy to create them, and it's especially not easy to create them just on the fly. In order to do all this stuff, you have to read thousands and thousands of pages of documentation.

You know, I have a sea of acronyms up here on the slide. There's just all kinds of documentation. You have all the different color books that you have to read. You have the red book, the blue book, the white book, the orange book, the yellow book, the other blue book.

There's just all kinds of stuff that you have to go through. And then, if you really want to play nice with the system, you need to do some kind of resource arbitration. You need one application to talk nicely with the other application. So we have iTunes and the Finder, and they both do burning. And yet, the right thing happens. When you're in iTunes and you hit burn, the Finder doesn't come up and try to steal the disc away from you. These applications are talking to each other and working it out to find out who gets the disc.

So that's the way it was in 1999. Then something happened. January 9, 2001, we introduced iTunes, iDVD, and DiscBurner all at once. It was a huge show. And these applications really kind of brought burning back to the user. And so we had a What they did is they really just made burning discs a natural part of the workflow. Burning discs becomes really natural. So the finder is where you're organizing your files.

So the finder naturally gains the ability to burn data discs. iTunes is where you're organizing your music. Well, you can make mixes, you can burn MP3 CDs, and all you developers out there are pretty familiar with disc copy, which is how we distribute seed images and stuff. And you can take a CD image, you can download it using your high-speed internet connection, and create a CD from that. And it's all really natural. Each application is able to just burn exactly what it makes sense for that application to burn. to burn.

Now I know what you're saying right now. You're saying, "Well sure, but you know, those are all Apple applications that I've got up there. If I want to take my application and I want it to burn discs, I have to go back here. I have to do all this." Well that's no fun.

You know, wouldn't you rather, wouldn't you rather be back up here where your application is integrated into the workflow? Well, so I'm proud to announce DiscRecording, which is a new set of APIs for Jaguar. And these are the same APIs that iTunes and the Finder use to do their burning. Thank you.

We're making these public in Jaguar. We've really--we've been working on them really hard. Been cleaning them up. Let me give--just as a for instance, let me give you a little bit of example. We're, uh... You know, it takes, I said, many years of effort. So we had a team of people working on this for a long time.

When we went to finally put it into iTunes, it took about four to six weeks for us to cram burning support into iTunes. And we're also doing DiscBurner at the same time, and So four to six weeks, from man years of effort down to like four to six weeks, it was really pretty good, but it wasn't good enough. So we went and we made it even easier.

We made it really straightforward, as simple as we could get it, and now literally if some of you are out there, you can probably hop on the ADC seed site, grab the SDK, and you might be able to get burning added to your application by the end of this session. We really think that it's really about a day to start burning. Your basic kinds of discs, which is really just absolutely amazing.

So these are the same APIs that iTunes and the Finder are using. We've got two system-level frameworks, one which is the actual engine, which we call DiscRecording, and we have another which is a common set of user interface elements, which is what we call DiscRecording UI. And it's really sort of like printing, for example. It's, you know, you've got the UI panels for printing, but you also have the core printing. You don't have to use the UI panels. And it really--it makes CD and DVD recording really easy, and your app becomes part of the digital hub.

So disk recording, what does it do? It handles burning. It handles erasing. It'll handle file system creation. Like I said, file system creation is pretty darn hard. So we offer some APIs to help you with that. It'll handle device support. You don't have to worry about the-- you have to send an extra command to a Sony drive before you burn to it that you don't have to send on a Yamaha. You don't have to worry about any of that. We worry about that. We make it work.

It gives you resource arbitration just about for free. It's really easy. You'll be just interacting with iTunes in the Finder and the new digital hub stuff that you might have seen in Jaguar. It'll all just work correctly. And it's just really great. And we give a standard user interface and experience. We have one set of burn dialogues, one set of progress.

So you don't have to worry about implementing that. You don't have to worry about making-- how am I going to present this to the user? We've done that. The user has one set of progress. They have panels that they're familiar with. And burning becomes trivially easy for them in your application.

So you might be saying to yourself, you know, what can I get out of this? Who should be using this? And really, we don't want necessarily everybody to be using it. Just where it makes sense. Let me give you an example. You know, I know the guy that writes MP3 alarm clock. It's a great application. You know, plays MP3s at a given time. Should it be burning audio CDs? Probably not.

But there are a lot of places where it really does make sense. We have printing for digital media. If you're any sort of digital media app, your sound, movies, photos, anything like that, a lot of times it makes a lot of sense for you to just have an export step in your application and just burn a CD straight from your application.

If you have cross-platform needs, if you know that users are using your application to create data, and then taking over to another platform, well, we burn a cross-platform file system on our disks. So you can create a disk. If you know for a fact the user's going to take your output and just burn it to a disk anyway, well, we can make that process a little bit easier.

If you have large data files, if you're generating large data files and you're... You know, you're doing, for example, scientific or mathematical applications. Maybe you generate 3 gigabytes of protein folding data, and you want a way to just quickly store that off somewhere. Well, maybe it makes sense to archive it to a DVD. You can do that.

So we've got a lot of current clients, got most of them up on the slide here, and we're making it public, so we really want your application to start getting into this and start burning as well. Alright. So that's the sales pitch. Now let's talk about the architecture.

The first part that lies underneath everything is the Core Burn Engine. The Core Burn Engine is basically an engine that handles burning content to a disk. It handles device management, which is actually one of the harder things to do. It handles burning and it handles erasing. It's just burning, it doesn't know anything about content. And that lies underneath everything.

The next part we have is we have a set of Content APIs, which will help you create file systems. And, like I said, creating file systems is really pretty difficult. We have some really powerful and flexible APIs in our stuff to help you create all sorts of different file systems, very highly configurable, and they're really great.

And those are built on top of the Burn Engine. So they were, you know, they're actually using the same APIs that the Core Burn Engine uses. So if you happen to know how to build file systems yourself, well, you can build your own file system and send it to the Core Burn Engine in exactly the same way the Content APIs are doing it.

Then we have DiscRecording UI. And these are our common setup panels and progress bar. And again, those are just built on top of the Core Burn Engine. You don't have to use the UI panels, but you're gonna see just how easy it is and just how hard it is to do it the other way. So we really want you to use the UI stuff, because we've solved all these problems.

A couple concepts that I need to talk about. The API is object-oriented, and it's available in both C and Objective-C. So all the Objective-C objects are NSObjects, and all the C objects are actually CF types. They're not toll-free bridge to each other yet, but that's something we might do in the future.

But since they're CF types, the C objects follow retain release conventions. You could throw them in collections, you could throw them in a dictionary or an array without having to do a special callback. All the functions have really consistent naming conventions, which if you've used CF, you get the very consistent naming conventions. And then all the objects also have property dictionaries.

So in general, rather than adding API calls for every little thing you can do, we have a property dictionary. And you take the property dictionary, you specify whatever properties you want that That's how you control its behavior. So here's the block diagram. The first thing we're going to zoom in on is the Core Engine.

So the Core Engine. The Core Engine handles burning, handles erasing, device handling, and media arbitration. Burning and erasing are asynchronous processes. What that means is you start the burn and then we go off and do it in the background. You don't have to worry about anything fancy. We handle all the thread scheduling for you automatically.

We'll send notifications to your run loop on what's going on. In the Core Engine, you're providing the data. You're providing the entire track for each track that you're burning. So the Burn Engine itself doesn't know anything about content. It's just a mechanism for you to deliver a stream of data to the drive.

We can do multiple burns at once, we can do multiple erases at once. This is really not a problem. I kind of have to wonder why, you know, people weren't doing it before, but it's really easy, so we threw that in. We handled device handling, and like I said, we handled the media arbitration. And those are all part of the Core Engine.

So we've got a core set of objects that handle all this. There's really only four objects in the whole Core Engine. We have an object representing a burn, we have an object representing a track, we have an object representing an erase, and we have an object for devices.

We also have our own notification center. If you've ever used CF Notification Center, we have our own variant on it, which lets you just sign up for notifications. We'll deliver all of our notifications through this notification center. and we'll get into that in a bit. So, let's look at the objects.

We have the DR Burn. By the way, DR Burn is the Objective-C name for it. DR Burn Ref is the C name for it. We're just gonna use drburn because it's the same object. drburn represents a burn. and represents the act of burning. You create one of these and then you tell it to burn and it burns.

And what it does is it writes a layout. So as you know, CDs can have multiple tracks on them. You stick CD in your CD player, you have a certain number of tracks that come up. Well, if you have a CD-ROM, that only has one track on it. That's your data track. You can also have multi-session discs where you have one session of audio and then one session of data, things like that. So it writes a layout, and the layout is just a CF type ref.

And that CF type ref will examine it on the fly and figure out what it is. You can pass in either a single track, you can pass in a CFArray of tracks, or you can pass in, for multiple sessions, you can pass in a CFArray of CFArrays of tracks. And again, everything happens asynchronous, happens in real time, and we send you notifications for progress throughout the burn and when it's done.

The next object is dr_track. This is the object that represents a track. Now, it could be a CD audio track, could be a data track, a CD or DVD data track, or it could be really anything in MMC. If you're familiar with CDs and you know about all the weird block sizes, the funny things you can do with video CDs and things like that, You can do all that using the Core Engine. The Core Engine does not constrain you, does not know anything about the content you're burning. You just tell it what to burn. And you provide the data through a callback during the burn.

And basically we'll call you real time during the burn to say, "Hey, I need my data. Let's have it." And it'll go into a RAM cache. You know, you are time constrained in that and that you need to produce the data fast enough for the burn to happen, but you're going into a RAM cache, so you're not going straight to the drive, so you're a little bit protected, so if you need to do something that takes a little longer, you're okay.

Um, like I said, there is a maximum data rate. So you can run-- you have your track production. Say you're doing something CPU intensive, such as decompressing MP3s, which iTunes does. We provide a way to run a speed test before the burn at basically safe time, um, to find out how fast you can produce your data.

And we'll run the speed test, and, you know, depending on how much CPU is available and so on, if you're on a Bondi original iMac, you're gonna have-- you know, you're gonna be a lot slower than if you're on a dual 1 GHz G4. So we'll find out what that maximum data rate is, and then we'll burn at a speed that's less than that. So we'll automatically--you don't have to do a test burn. You get the automatic, um-- you automatically burn at a rate that's good enough. And this is why iTunes burns generally don't underrun.

So the next object is DrErase. DrErase represents an erase. It's the act of erasing. Again, you start a racing with just one call, and it kicks off in the background and it runs asynchronously. And we send you notifications for progress if the drive reports it. Sometimes drives just go off and they don't tell us anything. And we'll send you a notification on completion.

Now the last main object is drDevice. And this is the object that represents a device. encapsulates a bunch of things. It handles device discovery. So find me the list of devices that are on the system. It handles device capabilities. Does this drive support CDR burning? Does it support DVDR burning? What's the name of the device? Can this drive erase disks? So on. We'll tell you about media inside the device. This is information that can change, obviously, because you can take discs in and out of the device.

You can do actions on the drive. You can mostly just disc burning-related actions, you know, open or close the tray or eject the media. and we'll send you notifications when devices are hot plugged, when they're plugged in or unplugged via USB or FireWire. We'll send you notifications when media is inserted or removed, things like that. So, we've introduced the objects. Let's now take a minute and walk through burning a disc.

Step one in burning a disc, well, you select a device. And I'm not going to go too far in-depth on this because we really want you to use DiscRecording UI and this, we give this to you automatically. We pop up a user interface, say, and give us a list of devices.

Here's a list of devices. Tell us what you want to burn to and then so on. So, but you, then you've got your device. Well, you need to wait for media. You can't just start burning without a blank disc. So, again, DiscRecording UI does this for you automatically. You're still, so this is just one call to DiscRecording UI and we're handling all this.

The next thing is create a burn object. Well, again, that's also handled by DiscRecording UI. We pretty much do the entire setup phase of the burn for you, because we want you to just worry about the content that you're producing. We don't want you to have to worry about all the extra stuff that's going on.

Then you create your tracks. And this is where you actually specify the content that you're burning. So here we have--we're going to actually call dr_track_create in C and provide the callback to produce the data. And it's just a callback function, and we'll call you back and say, you know, "Hey, I'm getting ready to burn. You know, open files, do whatever you're going to do. Hey, I'm burning. Give me some data. Give me some data." You know, repeat that a million times, and then we're going to say, "Okay, I'm done with the burn.

You know, go clean up." and that's it. Then, the properties on the track, every object has a properties dictionary. The properties on the track specify the length of the track, the block size, and things like that. All the MMC description of the track. And again, you want to make sure you run a speed test to find out how fast you can produce the data. And that's how you make sure you avoid underruns.

And again, in Objective-C, I'm a C Carbon sort of guy myself, but we also have a Cocoa guy on our team, so he made sure that whenever I had a C API up on the slide, we'd have the same Objective-C API up there. So the Objective-C API is pretty straightforward. You create a track, then init it. Instead of specifying a callback function, you're actually specifying a class which implements the DR track data production interface. and other than that, it's pretty straightforward. We send that class the messages and you handle them.

Well, so you've created your tracks, you've got your burn object, what's next? You start the burn. And this is where we call DR Burn Write Layout. Or in Objective-C, DR Burn Write Layout. So you start the burn. And you pass in a layout, which is a type, or it's a CF type, or it's an NSObject. That's either your array, or if we're just doing one track, it can be just a track. And we'll figure it out, do the right thing.

So the burn kicks off in the background and it starts happening. The next thing you need to do is actually display progress to the user. Since burns can take anywhere from 30 seconds up to an hour, Probably want to give the user some feedback. We'll send you notifications on that. But the easy way to do it, again, is DiscRecording UI.

Then you wait for the burn to complete. Or you can do something else. So we--in Mac OS X, we take advantage of the kernel scheduling. We make these--bump these threads up to high priority. And you don't have to worry about, you know, not touching the machine. You can launch Photoshop, do a render, do whatever you need to do, and you're not gonna underrun.

We actually reserve the right amount of CPU so you can go and do whatever you want while you're burning. Gone are those days of 1999 where you had to click and, you know, step back from the machine. We all did that. Come on, you step back from the machine and let it burn, and if you breathed on it, the burn might fail. No, no, we don't do that. The burn just works. And so you don't have to make your application modal at this point. actually go off and do something else.

So let's look at the code to do the basic stuff. Um... So up here at the top in C, we've got choose device, and what we're doing here is we're putting up some kind of UI to select a device. That returns a DR device ref. Um, we're not gonna show that on the slide, because device handling is actually pretty complicated.

You have to--you can--you can, you know, we can ask--you can ask us for a static list of devices that are attached, but then if a user hot plugs something, well, you don't know about the newly attached device, so you need to sign up for notifications and handle hot plugging. In order to do it all right, it's kind of complicated.

So DiscRecording UI will actually do all this for you. So we're just gonna, you know, say, "Here, choose device." And once you've chosen your device, you're gonna put up some UI saying, "Okay, now give me some media." And once you've got the media in the device, then you can create your burn. So we're creating a burn. A burn is, you pass the device as a parameter. Then you create a track, and you specify your callback function, and you specify track properties, which are the MMC description of the track.

And then you called DR Burn Set Properties. And you called Burn Right Layout. So, set properties is just, you know, if you want to change some of the properties of the burn, the speed of the burn, um... You know, whether you're going to mount the disc on the desktop or eject it after the burn, you control a lot of things there. Then you call writeLayout and we start writing. We're passing in the track, we're just doing a single track burn. Then you put up progress and you wait for the burn to finish.

So that's it in C. Now, same thing in Objective-C. It's pretty much the exact same thing, just in Objective-C. We're choosing a device, we're waiting for blank media, We're creating a burn for the device. We're creating a track. We're initializing it with a producer. We're going to have our own object be the producer. We set some properties on the track. We set some properties on the burn. And we call writeLayout. And again, we just wait for the burn to complete, and that's it. And that's burning in a nutshell.

And that's really, that's the basics of the Core Engine. So we talked about, you know, if you have your callback, you know, if you know what data you're going to produce, it's really, it's easy to burn that data. But how do you get that data to produce? Well, say you want to burn a file system.

File systems are hard. Especially if you're burning a hybrid disc, you're putting maybe ISO, Joliet, HFS+, maybe you're throwing UDF on there. You've got four file systems on there. You've got one copy of your data. You've got all these different file systems, but they're all pointing at the same data, so they're all kind of mixing together.

That kind of layout, that kind of creating the stuff on the fly is really not easy. So that's why we've got the Content APIs. The Content APIs help you create file systems for data discs. The Burn Engine, the Content APIs handle ISO 9660, Joliet, UDF, and HFS+. And they'll create hybrids of any or all of these formats together. And it's really easy to use and they're really powerful and flexible.

So, how does it work? Well, amazingly, there's really not many objects in this, in the API. We have a file object and we have a folder object. And that's pretty much it. If you know how to use a file system, then you already know what a file and a folder are. So the concepts are pretty clear. I'm gonna walk you through how we're gonna do that. There's a couple different ways to create these and put them all together.

So, there's two types of file and folder objects. There's real objects and there are virtual objects. So, real files and folders are copied from an existing file system. So that means if you have, for example, iTunes, when it burns its MP3 CDs, well, the burns that it's doing are from your music library. The files already exist on discs somewhere. They're not necessarily in the right locations, they're not grouped into a nice hierarchy, but the files are on disc. So when iTunes burns, the files are copied from an existing file system.

Uh, the name and the properties can be overridden. So iTunes actually changes the name, you know, puts a track number in front of, in front of it, but it doesn't go and rename the original on your hard disk, because that would be kind of dumb. It actually just renames it on the fly.

And then we have virtual files and folders, and these are actually created through the API. The data is specified at runtime, I mean, through the API. And this is actually really powerful and it's really pretty cool. So you can use this to basically lay out your own file system and have whatever you want on it, have data being spontaneously created, whatever. So the virtual folders really are how you define your hierarchy.

When you have a real folder, we copy everything underneath that real folder for you. But when you have a virtual folder, you can go ahead and add all the things to it. So we'll cover that in a sec. When we do this little walkthrough, we're going to walk you through how to create a file system.

So presumably you have some idea of the file system you want to create. You know what structure you want. So you create a bunch of file and folder objects. So we've got a bunch of APIs to create all the different kinds of files and folders. You can create, you know, creating real files and real folders is pretty straightforward. DrFileCreateReal, DrFolderCreateReal.

You can create a virtual folder. You just have to specify the name for the folder, and everything else is pretty much default. You can--again, you can change the properties if you want. And we have a couple different ways to create virtual files. You can create a virtual symbolic link or hard link or alias. You can create... You can create it using just a pointer and a length. If you have a small file, maybe a couple hundred K or a meg, well, you can just say, here's the data, go blast this out into a file for me, and we'll do that.

Or if it's a larger file, say it's a gigabyte, you don't want to just malloc that into a pointer and pass it to us, even if you could all the time. So we just have a way for you to specify a callback function, and we'll ask you for data during the burn, right at the appropriate moment, and it all just works. Again, same APIs in Objective-C. I don't think there's any huge surprises here. It's pretty straightforward mapping.

So we've created all the files and folders. Well, now we can go in and we can change the properties on these. Now the great thing about these Content APIs is that literally everything can be changed. You can go in and make the most complicated disc you can think of. You can change the names of all the files, you can change the metadata such as, you know, types, creators, whether it's invisible, different things like that.

You can also specify different properties for each generated file system or different names for each file system, for example, because ISO 9660 has a different naming convention than HFS+ does. If you want, you can get right down in there and control the generated names on each file system so that you know what they are.

You can also... We're going to talk about how to make an item disappear entirely. If you're burning a game CD and you have two copies of your application, if you're burning for Windows and the Mac, you put your Windows executable on the Joliet and you make the Mac executable not show up on Joliet.

You can make the Windows .exe file not show up on the Mac HFS Plus volume. When you insert it into a computer, you only see the one executable. The users aren't confused by seeing which icon do I click on. There's just one thing. So you can do that. And so you can-- it's really, really powerful, and it's really pretty cool.

So once you set the properties and configure the file system the way you want, well then you build the hierarchy. Building the hierarchy is, again, it's pretty straightforward. You're mostly going to use one call for this, "add child." - You can also get children, remove children, do it all dynamically. You can put up a whole user interface for building a disc if you want.

but you're just gonna basically call add child till you get one hierarchy and one root folder. Something to note is that when you're gonna add children to a folder, you can only do that to a virtual folder. A real folder contains, you know, automatically contains everything underneath it, so you can't go in and, you know, iterate the children and remove children from that. You have to actually convert it from a real folder to a virtual folder, but when we do that, we'll go and we'll read all of the children and convert them to real files and folders, and we'll make the folder virtual.

And again, in Objective-C, no big surprises here. So we've built the hierarchy. We've got a root folder. We have one single point that says, "This is my file system. Here's what everything looks like underneath it." The next thing you should do is you create a file system track. And this track contains a callback already that's already set up by DiscRecording, or by the Content APIs.

And how do you do that? Well, again, it's just one call. Dr. FileSystemTrackCreate. So you build your hierarchy, you have your root folder. All you do is you pass in that root folder to this call, and bingo, you've got a track. You can set a couple of properties on the track to control whether you're doing-- you know, control various things about the file system generation. For example, the ISO level is controlled through a track property. Whether you're going to generate RockRidge or not, that's controlled through a track property.

There's a lot of properties, a lot of things you can customize. But it's all pretty straightforward. If you leave it at the defaults, you'll probably get, you know, a really just nice normal disc. Again, it's the same thing in Objective-C. Rather than being called DRFileSystemTrack, it's just implemented as a category on DRTrack.

Now you've got your track. Well, you already know how to use the Core Engine, so you just pass that track into the Core Engine, and you just burn it. That track does the right thing. It produces all the data on the fly, reads the files you specify, and it creates the file system. - And it burns it. You don't have to worry about it. You've specified what you want to burn, and we do it.

So let's look at the code to do, for example, what the finder does. So the finder mounts a disc image and burns the contents of that disc image directly without modifying anything. Well... Okay, it's two lines of code to do that. We create a real folder, and we create a file system track based on that. We let DiscRecording handle everything else.

And there we go, we've got a track graph. And we pass that to the burn, then we say, you know, okay, go ahead and do our burn right layout, and it's done. And that's just how easy it is. We can do the same thing in Cocoa. It's the same thing. Actually, there should be a CF release after we allocate the folder. I was going to fix that on slide, but we didn't get a chance to do it.

In Cocoa, everything's auto-released, so you don't have to do that. If you really wanted to, you could do this on one line. In fact, I think our Cocoa guy was playing around, and he actually came up with a way to do an entire burn using all the UI elements and everything in one great, big, enormous line. I think it wrapped several times, but it-- you could do it in one line, which is pretty neat.

Okay, so those are the Content APIs. We'll create file systems for you really easily. So if you're burning any sort of data disc, you probably want to use the Content APIs, unless you already know how to create file systems, in which case, go right ahead. So now, the last part to talk about is DiscRecording UI. These are the common UI elements. So DiscRecording UI is available in both Cocoa and Carbon.

So the Carbon support isn't there right now. We weren't sure if we were going to have it ready and it turns out we didn't, but it is going to definitely be there by the time Jaguar ships. We've got lots of sample code showing how to use it for both Carbon and Cocoa.

And so the DiscRecording UI provides a common UI for burning and erasing. It's really--it's a lot like the print panels. Everything just is very standard, and the user just gets one-- one experience of burning, and they really know--learn that really well. And there's only really two parts to it. There's burn setup and there's burn progress.

And we've also got some burn and erase icons for you to use in your own applications. And again, those are really easy to use. And I think now we're gonna come up and have Mike Shields come up and show us how to use DiscRecording UI and show us what it looks like. Mike? Okay, hi, I'm Mike. I'm going to be showing you the DiscRecording UI.

What we're going to do is take a look at one of the sample apps we're providing on the SDK. What this does is it provides a real, real simple audio burn application. So what we do is we'll launch it, and we got some audio AIFF files that we've ripped off of one of the CDs that we've bought.

And we'll just go ahead and select them. And here's the setup panel. As you can see, the setup panel, it has a list of all the devices connected to your machine. And... Has a little device connected to your machine, and you get to choose which one you want. So here's the internal DVDR and the two drives up here. So we'll go ahead and pop the drive open.

CD and stick it in. So, like Drew said, the first part is selecting a device. We've selected a device, now we need to wait for media to be inserted. So the drive sitting here is spinning the disc up, checking to make sure it's blank, you know, what it is. So it's recognized, we've got a notification, and at this point in time we're ready to burn if we wanted to. But first I'm going to show you a little bit more. So, you know, we can go in and configure the burn a little bit differently.

For instance, if for some reason we found we needed to slow the burn down, we can slow it down from the maximum speed. We can tell it whether to verify the burn or not and what we want to do once the burn is complete, whether to eject it or mount it on the desktop.

So we'll go ahead and mount it on the desktop once it's done. And we click burn and the progress panel comes up. So now that the burn's going, the drive's spinning up. It's going to be a little bit more of a slow burn. So we're putting data into its cache and starting to write it out to disc. So we tell you what drive, what disc the drive's going to. So if, for instance, you have multiple ones going on, the user can figure out which one's which.

Progress for each track. And a little bit of status over here just to give the user some feedback about what's going on. So like you said, it's pretty easy. So let's go ahead and look at the actual code that it takes to do this. We managed to fit all on one page. So first thing we'll do, we're going to create a track, create our array of tracks here. In this case we're creating audio tracks. And if this was a data burning application, we'd go and create some, create a data track and pass it back.

Once we've gotten the data track, or the audio tracks that we want in this array, we go ahead and we create, instantiate the setup panel. And once the setup panel's instantiated, you know, for you Cocoa programmers out there, this is probably pretty familiar from doing something like the open panel, for instance.

So we're going to go ahead and run this. Since we instantiated it, go ahead and run it as a modal dialog. We also have an interface to run these things as sheets on a document window. So you could, for instance, have a document-based application. And for each document you could burn separately to a different drive. So once the user's configured the burn, they can hit the OK button and they You instantiate the progress panel.

Once the progress panel is instantiated, you just say, "Begin progress panel for burn, pass up the burn object that the setup panel has preconfigured for you with the device, the burn speed, et cetera, and give it the track layout that you want to burn." And once that's done, the progress panel comes up, and you're off to go do other things in your application.

So, let's see how progress is going along. So, we're just about done with the burn. And at this point in time, the drive is synchronizing its caches, making sure that all the table of contents data is written to the disk, and now it's done. So, we're going to go ahead We'll go over into iTunes. There's the audio CD. And we'll go ahead and play it. So, four lines of code to go and create an audio CD for a user to go and play on their own machine. So that's in a nutshell. It's pretty easy.

You go ahead and... Like Drew said, the hard part's giving us the data. So I'll give it back to Drew now. Thanks, Mike. Thanks. So it's really that easy. Actually, we didn't show the actual producing of the data, but it's just AIFF data. You know, we used AIFF because it's easy. It's 44.1 kilohertz, almost identical to the CD audio format. So that just reads it in, spews it out to the disc, and there we go. So that's that. So we wanted to talk a little bit about how different things are from 1999.

So back in 1999, you could only do one burn at once. You really, you know, okay, so you did the one thing, you clicked the mouse, you stepped back from the machine, and you hoped it worked. Well, now drives are faster, we've got faster computers, everything's really fast. So with these APIs, we don't put a limit on what you can do at the same time.

We actually--oh, I guess we have the developer resources slide now, actually. So we have lots of sample code. We have API reference documentation complete. There's no description forthcoming. We've got some conceptual documentation that's getting cleaned up, being pushed through tech pubs. So we've got a mailing list for everyone to discuss what's going on and get our help adding burning to their application. So back over here, um... So, you know, like I said, doing one burn at once, that's pretty easy.

What if we did more than one at once? What if we did... five burns all at the same time? So, oh, Mike? Actually, Mike, so we've got five down there. We've got two up here. You're dropping the hug. Well, actually, so... Wait a second, we've got seven drives. Think we should try seven burns? Whoo! Yeah. Oh, that's the one with the broken button.

We had to scavenge up seven drives that were all the same so they would stack very nicely. Oh, that's got the disc in it. Yeah, that's the one that's already got a disc in it. All right, so let's switch back to the demo machine on the slides. Can we switch back to the... Great. Seven blank CDs.

Okay. So what I did here is I just wrote a little, quick little sample, quick little app that all it does is as each drive is recognized and the media gets inserted, it fires off a burn for each one. So let's go ahead and launch it. And now that it's sitting here, I'll just start sticking the disks in the drives. And as each one comes up, you'll see the progress panel come up and the burn will start. And it'll take a second for each, for each drive to recognize that the, that the disk is in it.

Okay, so there's the first one. And I can hear them all starting to spin up here. One! Okay. I guess the demo gods are not smiling on us today. Did you hot plug? Everything's plugged in. We dropped the hub on the way up. That might have had something to do with it.

[Transcript missing]

Aha. All right, so you know how we were talking about hot plugs. Listening for notifications. Well. So let's see what happens. Oh, we've got one! Okay, that didn't really count. That was one at once. Okay, that was pretty boring.

[Transcript missing]

So there we go. Now we got them all coming up. So we got six drives going at once. Six going all at the same time. And we'll, uh... Just so you know, we're not trying to fake this thing. We'll just wait for it to at least finish one of them. What we're doing is we're burning an actual disc image, and you can come up and take a look at it if you wanted to, just to prove to yourself that we actually did do a burn here.

So there we go, we're almost done. Burning it, I think these things are burning at about between 32x, somewhere around. Some of them are as fast as that. If you'd seen the demo from the Core Graphics, we're sitting here doing the fractal scaling here, and we're burning. And while the CPU is getting pretty much maxed out, our threads are real-time, so they're basically preempting anybody else, and we aren't going to be blocked waiting for data or something like that. And I'm starting to mount on the desktop now. Okay. Well, instead of seven at once, we had six at once. Still pretty good.

Let's go back to the slides. Okay, so we've shown you the APIs, we've shown you what they can do, and with these APIs, we really hope that you guys too can, you know, start burning and call yourselves recording artists. - So we've got documentation. It's preliminary. It hasn't been cleaned up by the tech writers, but it's available through the ADC seed. Go to the member site, go to Download Software for Jaguar, and you should find the documentation right there.

As far as roadmap goes, since we're an abstraction layer, we kind of hide you from all the other stuff. You could go to the I/O Kit sessions, but you don't need to. You could go to the Kernel sessions, but you don't need to. So one of the nice things is we do actually send notifications, and those are handled by CF Run Loops, so we encourage you to learn how those work, because that'll be helpful. But again, when you use DiscRecording UI, you don't have to do that, so if you're using DiscRecording UI, you really don't even need to make this session. So that's that, and I'll bring John up for Q&A.

All right, well, so if you have any questions about this material or if you seek additional documentation or whatever after the show, this is your contact point. It's me. We don't want to have you contacting the engineering team because they're making it even better so that next year we can demo like 32 burns at the same time or something.