Core OS • 1:03:08
This session reviews recent enhancements and highlight upcoming features of Apple's DiscRecording APIs. Learn how you'll now be able to self-qualify your drives, how the new Audio APIs will make it even easier to write audio CDs, and how Carbon applications can easily add disc recording support using the Carbon UI framework. We also show several third-party solutions as well demonstrate how easy it is to add support to your drive using these new APIs.
Speakers: Drew Thaler, John Bertagnolli, Reese Schreiber, Mike Shields, Ed Wynne, Murray Jason
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Hello. My name is Patrick Collins, and I'm the Digital Hub Technology Manager in Developer Relations. We're going to be covering DiscRecording APIs today. So we have the whole burning issue team here to run through everything. They'll be here for our Q&A after the session, and we'll get started with Drew Thaler. Thank you.
welcome. So today we're going to be talking about disc recording. My name's Drew Thaler. My title is Recording Artist. I work in the Burning Issues group at Apple Computer, and we handle everything that has to do with CD and DVD burning. So one year ago, the DiscRecording APIs were introduced with Jaguar. So this is our second session. And we're going to talk about what went on in the past, and we're going to talk about what's new for Panther. So our topic's in session. We're going to go over the introduction.
We're going to talk about the new features in Panther for those of you that are already familiar with disc recording. And then we're going to go ahead and do an overview of the API covering both old and new stuff. and we're going to talk about a new feature which we call device profiles. That'll be at the end of the session.
So let's talk about disc recording. What is disc recording? Well, no one can be told what disc recording is. You have to experience it for yourself. No, no, I'm just kidding, really. Actually, you can be told what disc recording is, and I'm going to do it here for you today.
Before we talk about what disc recording is, though, let's talk about why. The basic problem that you have to deal with if you're an application that wants to provide digital media on CDs and DVDs is that really burning discs is actually pretty hard. It takes several man years of work to implement all the various levels of things that you have to do.
You have to talk to many different layers of the operating system. You have to do the user interface. You have to go all the way down to talking to hardware. You have to deal with all the layers of the operating system in between, including threading, IOCIT, disc arbitration, things like that.
You have to talk directly to the drives. Different drives might have slightly different behaviors. And you don't necessarily want to deal with that from your application. You also have to stream your data from the beginning of the disk to the end. A CD is generally not a random writable thing. You can't just copy files to it. You have to start at block zero of the disk, stream all the way to the end. And you also can't just use normal file systems. There are specialized file systems which are designed for CDs which are cross-platform.
So there's thousands of pages of specifications. There's this whole sea of acronyms, and these are just the publishers of the specifications, not even the specifications themselves. You've got all these color books. You've got the red book, the yellow book, the orange book, the green book, the blue book, the other blue book. There's a lot of stuff to read, and you have to pay attention to every little sentence, and it's kind of just a big pain. And lastly, and and many others.
Very much not least, since this is the Mac, your application needs to play nicely with all the other applications. You don't want to completely take over the drive. You want the user to be able to seamlessly move between your application, iTunes, the Finder, whatever else. So you need to play nice with the other applications.
So solving that problem, we really need something that's easy, that's fast, and that's powerful. For easy, it really needs to be accessible to application developers. We need something object-oriented that's going to give you a nice, high-level, easy-to-interpret view of the task at hand. You need to hide the hardware differences. You need to have an abstraction layer that smooths out the differences between all the devices and just treats a CD burner as a CD burner.
Because of the things with file systems and creating the different types of data, there are some pretty common tasks in there that would be duplicated. You don't need every application to become a master of three different file system formats. You just need to-- it would be nice if there's a helper to help you do that sort of thing.
Having a common user interface between applications is good. It should be kind of fast. Some applications function by writing out all the data to disk first, creating a CD image on the hard drive, and then sending it to the disc, sending it to the CD. And that works, but you wind up touching the data three times. Once while you're producing it, once getting it on and off the disk, and once sending it to the drive. And that's actually a lot slower than just going straight from content production to the disk.
And it really should be powerful. You need to be able to not just burn a folder. You want to burn exactly the format of data you want. You want to be able to really burn anything. For people that really know what they're doing and want to get down to the guts of it, they really should be able to burn anything without having to go out of their way. It shouldn't be purely high level. There should be access down to the low levels.
So that brings us to disc recording itself. So what is disc recording? Well, to begin with, it's a device abstraction layer. There's lots of devices, there's lots of connection interfaces. You have USB, you have FireWire. All these drives might behave a little differently underneath the hood, but you don't really need to worry about that. There's lots of things like that.
So disc recording is an abstraction layer that makes it very easy to talk to devices. This recording is a data streaming engine. Fundamentally, CD burning, most CD burning is streaming. You start at the beginning and you write all the way to the end. And that involves real-time data production.
It's a content generator. Again, generating the content is not trivially easy. You have to generate multiple file systems at the same time, interleave them on the disk. And if you're burning an audio CD, for example, then you need to take your MP3 file, decompress it, and send it to the drive. and it's a system framework. Most importantly, Apple has already done all of this work and we've packaged it all up for your application to use. It's the exact same stuff that iTunes, the Finder, all of Apple's applications use and it's available for your use.
So this means for applications that leverage the DiscRecording services that burning discs is really natural. It becomes basically a type of printing for your digital media. You produce the content, whether it's music, whether it's movies, scientific data, whatever it might be, and we get it onto the disc for you. So your application is integrated into the digital hub. So for those of you who are a little bit familiar with DiscRecording already, we're going to touch upon the new features in Panther.
So the first thing that's new in Panther is that disc recording is now an umbrella framework. So we've taken some of the components of disc recording and broken them up into sub-frameworks. You might be asking, well, what does this mean to me? Really probably not much. The only thing that it might have to do with you is if you include -- if you include a
[Transcript missing]
In Jaguar, there were separate entities. In Panther, they're now exactly the same. A DR track ref is the same as the DR track. We've got audio file burning. So if you're burning an audio CD from MP3s, you don't have to write your own MP3 decompressor or figure out how to use QuickTime to do it. We've got that code for you.
We've added some pro audio features, media catalog number, UPC code, the international standard recording code for tracks, support for the serial copy management system, subtract index points, and you can also specify your burn strategy, such as track it once or session it once, and so on. We've added Carbon accessors for the user interface panels.
We've got something that we're going to talk about at the end of the session called Device Profiles, which is the new way that we're going to be doing device support basically from Panther onward. And it's not just this extra thing that we're giving you. It's the way Apple's going to be doing it too. So we're very interested in making it work and making it work right. So for those of you that are interested in Device Profiles, we'll be wanting your feedback at the end of the session.
and we've added a command line utility to give access to some of DiscRecording's features. From the command line. So let's dig down a little bit into the API and talk about the general concepts. So DiscRecording is an object-oriented API. It's got these high-level objects. are available from both C and Objective-C.
And again, new in Panther, they're toll-free bridged. So all the C objects are CF types. All the Objective-C objects are obviously NS objects. The C objects, you know, since they're CF, they follow retain release conventions, they have CF collection support, there's consistent naming conventions between them, between the functions.
In general, every object has a properties dictionary, and the properties dictionary controls its behavior. So rather than having a whole bunch of accessor functions, there's just one dictionary. You set properties in it, and when it goes to do something, it checks the property, and that's how you control it. Of course, all the APIs are thread-safe, so you don't have to worry about calling stuff re-entrantly or adding all kinds of extra locks to worry about things. Everything's thread-safe.
So there are really three main parts to the DiscRecording architecture. Down at the bottom, we have the burn engine. And the burn engine is responsible for handling devices, for burning and erasing. Those are its primary features. Building on top of that, we have the Content Creation APIs. And these handle file system creation. And in Panther now, they handle audio track creation from an audio file.
Then parallel to that, also building on top of the burn engine, we have the user interface. So we have panels that you can use for burn setup for progress during a burn. And these are really the fundamental tasks. This is everything you need to do, hopefully, except for actually producing your content. And we've even got stuff to help you with producing your content. So let's zoom in on the burn engine and talk about the objects inside.
So the burn engine handles four things, really. I said three before, but it's really four. Handles burning, handles erasing. It handles devices. It'll tell you about devices, and you can do certain things to the devices. And as part of its device handling, it handles media arbitration. So the burn engine is what's responsible for helping your application play nice with iTunes and the Finder and everything else.
This is all done with really just a small set of objects. There's four core objects. Two of them represent actions, the burn in a race object, and two of them, one of them represents your data, and one of them represents the device that you're burning to. You can also sign up for notifications. And so we have our own notification center, which we'll cover in just a moment, where you can sign up for notifications on your object.
So the DR burn object represents the act of burning. And so you create it, and then you ask it to write a layout. And what's a layout? Well, a layout can be just one track. If you're perhaps burning a data disk, it can be multiple tracks. Say if you're burning a multi-track audio CD, can even be an array of array of tracks, in which case you get multiple sessions.
Now, burn is an asynchronous operation. So you kick it off, and it happens on its own thread. And then you get notifications for progress and completion. So you don't have to worry about giving it time from your user interface. You can do whatever you need to do. And we take care of it, and it just works.
and I are going to talk about the DR track object. The DR track object represents your track. It could be a CD audio track, a data track. It's flexible. We basically expose a lot of MMC down in the DR track so you can really do anything in MMC. You provide your data through a callback. and C is a function pointer and Objective-C is an object in the selector. We'll call you back at real time during the burn right when we need the data.
and obviously you might be doing some sort of computation to produce the data, perhaps decompression, decrypting, whatever. We know that the CPU is not infinite, so we'll run a production cycle for you so that you can find out just how fast you can produce the data. So you don't need to do that test yourself. We've already got the helpers in there to help you find the maximum data rate. And that helps us set the burn speed correctly so that it doesn't underrun.
So we've got the burn object, we've got the track which specifies the data, now we've got the device object. This represents basically where you're burning to. There's one DR device object for every device that's the burning device that's attached to the system. And the DR device object can report the capabilities of the device, which are basically static and unchanging. Things like this device can write CDRs. This device can write DVDRs.
It also can tell you about the media inside the device so that you can find out whether the disk inside is blank, whether it's already been burned, what type it is, whether it's CDR, DVDR, that sort of thing. It's also got a few commands that you can do, such as opening and closing the tray, unmounting and ejecting volumes.
And DRDevice will send its own notifications. And these are a little different. So basically, since DRDevice is not something you create, it's something that represents a device that's on the system. Well, we live in a dynamic world, and the user can go ahead and plug devices in and pop them out at any time with firmware and technologies like that. So we'll send you a notification when a device shows up. We'll send you a notification when a device goes away.
So you don't have to sit there and keep pulling the list will tell you when it changes. We also will tell you when media comes and goes because that's something else that you might need to pull for. Well, you don't need to pull. We do it all with notifications.
And it'll tell you when devices come and go, when devices are available or not. For example, if iTunes is running and it's doing a burn, well, you can't really do anything to the device while iTunes is doing a burn. So the device goes busy for the duration of that burn. Then it comes back afterwards. And we'll send you a notification when it goes busy. We'll send you a notification when it's available again.
To handle all these notifications that I've been talking about, we've got the DR Notification Center. If you've used the NS and CF Notification Centers, those are pretty much the same thing. They have basically the same interface. There's a couple of details of the implementation that differ. For one thing, DR Notification Center was designed for inter-thread notifications.
We're doing the burn up on a high-priority real-time thread, and we're sending notifications back to you on your main thread. So obviously, the burn thread can't stop and wait for your main thread. So the Notification Center sits in the middle, and it'll throttle things. and coalesce multiple notifications into a single one if you're updating your UI or whatever else.
and even though we'll coalesce some of the notifications, we guarantee delivery for all the important ones. You know, if the burn, if we send notifications for 1%, 2%, and 3% complete, you can miss one and two as long as you get 3%. But if, for example, the burn finishes, well, that's, you know, that's an important notification. We guarantee delivery of that one.
So you can use these notifications to key off the state, to understand the state of all the objects. So you'll get all the important transitions. and this is really strongly recommended. Sometimes it's easier to write the code that pulls. The problem with the pulling code is that sometimes you wind up in a state where things happen just a little too quickly and you don't pick up what happens on the pulling. If you sign up for notifications, we'll make sure that you get all the notifications you need.
So we've got our core objects here that we need for a burn. So let's look at how a burn works. So up at the top, we've got your application. You're going to create a burn object, which represents the act of your burn. And you're going to associate it with a device. You look at the devices on the system, pick one.
And then you set properties on the burn, for example, whether or not you want to verify the speed at which you want to burn, and so on. And then you tell the burn to write a layout. The layout is down at the bottom. In this case, it's an array of three DR tracks. So the burn starts to write, and as it goes, it sends notifications over to the Notification Center. The Notification Center then relays them to your application on its main thread, or whatever thread you chose.
And that's basically how the burn works. When the burn completes, one last notification goes up to your application, and then it's done. So erasing is really a lot like burning. There's not a lot of surprises here. It represents an erase rather than a burn. Again, it's an asynchronous operation. You start it with one call, kick it off, goes up, happens in the background. We'll send you notifications for progress and when it's done.
So if we look at the anatomy of an erase, it's pretty much the same thing, only without the data. You have your application, your erase that you set properties on associated with the device. Notifications go through and get up to your application. So we're going to give a little demonstration of how the device notifications work in the burn engine, just to give you an example and show you the kinds of things that you can do. So let's switch over to demo one.
Okay, so what we've got here is we've got a very basic application. There's a nib file which we'll see when it runs, but the nib file basically there's a window with a text field. There's nothing complicated in it. We've got a pretty empty application controller here. So, actually I need my script. and my script's gone. Let's see if I can get one of my helpers to bring my script up. I do know the first several things. So the first thing that we're going to need is we're going to need to include DiscRecording.h.
So we're using the DiscRecording services, so we're going to include DiscRecording. Then, once the application is done launching, we're going to create-- We're going to basically create an array which contains a copy of the current devices that are attached. And the reason why we're going to do this is because when we call, when we ask DiscRecording for the list of devices, we're going to get a list of exactly what's connected at that instant.
But the thing is, we can't-- You can't really rely on that staying the same from one moment to the next because devices come and go. So if you're going to do something in your UI, you need a separate copy that you can say, OK, I know the third device represents this device. Because if the second device goes away in between when you ask for the two sets of devices, it can be a problem. So we're going to keep our own local copy of the device list.
So down here, we're going to sign up for a notification. We're going to sign up for device disappeared notifications. The reason we sign up for disappeared notifications is so that we can keep track of-- we're going to sign up for disappeared before we sign up for appeared notifications.
This is basically for synchronization because, again, if a device shows up If a device disappears once we've built the list, then we'll get the notification right away. But we don't want to get into any race conditions where we don't find out about a device going away. Then we're going to add the device appeared notification.
So we've now signed up with these two selectors, and we've got these methods that are going to be invoked in our app controller. Well, so we're going to need those methods. So here's the device appeared. And all we're going to do, it's a standard notification response selector. So we get it. The object for the notification is the device, and we're going to add it to our list. And we're going to go and update the user interface.
So here we go. Here's the device disappeared notification. And again, we're just going to get the object, remove it from our list, and update our UI. So this application is basically just going to tell us a little bit about every device connected to the system, and it's going to respond dynamically as things come and go. So we've been calling update UI, so we need to give that an implementation. So here's a little bit of stuff to just enumerate our list of devices. Going to loop through and enumerate the list.
We're going to get device info. The device info is static, unchanging information about the device describing its capabilities and things like that. Part of the info is the device's name. We've got a nice thing that gives you a nicely formatted string describing the device. The connection is also here because the device is, for example, USB or FireWire or whatever else. So we're going to get that.
Then we're going to look at the status. And the status is things that can change. So it's a snapshot of the current status of the device. From that, we're going to pull out whether the device is dead or not. We're going to pull out the media state. The media state can be empty, in transition, which means the drive is spinning up or spinning down, or it can have media.
And then we're going to get the media type. So if there is media, and that's where we get the media type. So we're going to get the media info dictionary, which is a sub-dictionary underneath the status. We're going to pull out the media type from the media info dictionary. If there's no media, then we'll have a special string to indicate that. Otherwise, the media is in transition and it's spinning up or spinning down.
So what we're going to do then is we're going to log all of this information that we've gathered basically directly from the device. I'm going to log it into the text field. I'm going to add it to the text field and set it on the text field. So we've just gone through, looped through all devices, built up this string describing the state of the device, and we're done. and I think that's it for this one. Let's see if it builds.
We've got a couple devices connected to the machine over here. And these devices, we've got two FireWire devices plus the internal drive on the machine. So when it's ready to go, here we go. So this is our very simple text field. And so we've signed up from the notifications. So it's telling us all about each of the things.
We've got the internal-- and I have a Toppy Pioneer drive. We've got an external drive connected over FireWire. We've got another external drive connected over FireWire. None of them are busy. None of them have any media. So I'm going to change that. Let's open one, stick media in, close it.
Are we getting our notifications? Perhaps we're not. Okay. Well, there might be something wonky with our notifications, but we are getting the initial stuff. Let's try that one more time and just see what happens. Let's eject this guy. If he'll let us? No? Oh, I did not add-- you're right. That's why we're not updating. We aren't done with the demo yet.
So what we need to do is go back over here. So we've signed up for device appeared and disappeared notifications, but what we haven't signed up for is media state changes. So let's go up here to-- So we can detect when devices are there, but we're not really noticing what's happening to them. So let's go up to device appeared. When we get a device, we're going to sign up for notifications on the media. So here we go. We're adding another notification. Again, we just get the notification center, add an observer.
signed up for device status change notifications. When a device disappears, we're going to go down. and remove the notification that we've signed up for. So we've just signed up for status changed and removed ourselves. So let's go down here. Last but not least, we need to implement the device state change. So when the device state changes, all we're going to do is kick over and update the UI. So now, now that we've got all the code in there, let's go ahead and compile it and run it and see if we actually pick up all of the notifications.
So here we go. We've got our three drives. We've got the FireWire drive, or two FireWire drives. One of them has a CD in it. One of them doesn't. So let's put something in the bottom drive. So it's in transition. The drive is spinning up. It's detecting whether there's media, trying to see what it is. And there we go. It's noticed that there's CDR media.
and these drives might not have functioning eject buttons. So I guess we'll just leave the media in there for now.
[Transcript missing]
So we've signed up for notifications and we can watch what's going on on the device. If we were to do a burn in iTunes, iTunes would cause it to flip to device busy and so on. So you can find out anything you need to about the drives from the notifications. And that's it for demo one. So let's get back over here to the slides.
Okay, so we've talked about the burn engine. Now we're going to zoom in on some of the higher-level pieces. We're going to talk about content creation. Content creation is where all the helpers for creating content are. So the problem with burning is that you burn basically a data stream. And formatting that data stream can be kind of difficult. So If you're not up to formatting that data stream, we've got helpers to help you do that and bring it into a more natural set of APIs.
So the content creation now with Panther has two main parts. There's one part that helps you create file systems for data disks, including ISO 9660, Joliet, HFS+, and hybrids of any of those. and there's also an audio helper to help you take audio files, MP3s, AAC files, whatever, anything QuickTime can import and burn them to an audio CD.
[Transcript missing]
The content framework or the content creation APIs basically contain things that that cover their special kinds of DR tracks. They're DR tracks where we provide the callback for you and we give the data to the burn engine. So DR file system track represents a data track for a CD or DVD. And you specify a file system hierarchy that you want on the disk and we'll go ahead and put it onto the disk for you.
And again, this file system hierarchy is not just let's burn a single folder. We've got it hooked up so that you can actually do anything you want. And the objects are really very natural. So we have file and folder objects. And so for DR file objects, for example, there's different ways to create them. You can have them come from an existing file on the hard disk somewhere.
You can have them come from a data blob in memory. Or you can specify your own data through a callback routine. So if you're getting real-time sampling data, you can send it straight to the drive and have it actually show up as a file rather than just raw data on the disk.
So the way it works is you build your hierarchy. You build a hierarchy of file and folder objects, and there's different kinds of objects. So your files and folders can be either real or virtual. Well, let's talk about that distinction for just a moment. Real files and folders are pretty much copied straight from an existing file system. So if you have a folder somewhere or a file somewhere that you just want to bring onto the disk, you can go ahead and do that.
You can create a real file that points to that and put it into the hierarchy wherever you want. It doesn't have to be exactly where it was before. You're specifying a brand new hierarchy. So we'll pull stuff from any portion of the disk, bring it all together for you.
Objects can also be virtual. That means they're entirely created through the API. That means they don't exist on disk at all. You might be specifying the data at runtime. You might be saying, I just want this to be an empty file. You can do whatever you want. And that's all specified through the API. So what we've got is we've really got four classes of object. We've got-- Real files, virtual files, real folders, and virtual folders.
Now, the way this works is that three of these are basically you have a hierarchy, which is a tree, and the leaf nodes, three of these are leaf nodes, which means that they can't have children added to them. So real files and virtual files obviously are files and can't have anything added to them. Real folders represent -- will bring in what's underneath the folder, but you can't actually add children to them dynamically. So the virtual folders are how you really define your synthetic hierarchy.
So DiscRecording will take all of this and will generate file systems for you. And so the file systems we generate have different naming conventions. There's ISO 9660, which has one convention, Joliet, which has another, HFS+, which has yet another. And so the names can be whatever you want, but depending on what names they happen to be, they might not conform to what the file system wants.
So DiscRecording will automatically transform the file names to make them legal, to make them fit. So that they conform to the standards. However, we do this automatically, but we don't just do it behind your back. If you need to know the name of a file, for example, to build a disc relative path or something, you can actually ask DiscRecording and get the name for each file. And you can even change it if you need to. If you don't like what DiscRecording has done to it, you can go ahead and change it through your UI or programmatically.
So every object also has a properties dictionary. And the properties dictionary for file system objects describes the metadata on the object. Things like permissions, type and creator, owner group, things like that. And again, since every object has a properties dictionary, you can go into the properties dictionary and override the properties on real files, real folders, virtual files, virtual folders.
You can set all of these. and obviously real files and real folders will at first inherit the properties, you know, the owner group permissions type creator will inherit the properties from the real file. But then if you need to, you can go in and override those, change them, whatever you need to do.
Finally, each object in the Content APIs has a mask. And the mask determines the presence of each object in each file system. This is actually-- it's a very simple concept, but it leads to something pretty cool. You can actually take objects and turn them off in specific file systems. Perhaps you're writing a cross-platform game, and you have a Windows executable and a Mac OS executable. Well, you make the Mac OS one only show up in the HFS+ file system. You make the Windows one only show up in Joliet. And that's really easy to do.
When you set a mask on the root folder, that determines it basically carries downward because obviously if a folder doesn't include HFS+, none of its children can really include HFS+ either. So it carries downward and the way it works is the root is what determines what file systems will be on the disk.
So if you want a hybrid disk, you set a mask on the root folder that has a hybrid mask. And even though we'll put all of these objects in different file systems, really the file data is all shared between them. You don't have three copies of the file on disk. You actually have just one copy and you have essentially three different views of the file data.
So now that we've sort of gone over all that, let's look at a real data track. So up at the top, we've got the DR file system track object. And it basically just has-- it does have properties which aren't labeled there, but underneath it, there are our hierarchy, our tree of objects. So we've got a DR folder, which is our root folder.
We've got a couple of files. We've got one real file from somewhere on disk, and we've got a virtual file that we're going to be specifying the data for at runtime. We've got a real folder which automatically brings in everything underneath that folder. And then we've got a virtual folder.
So we've got a couple of real files, another real folder. And so DiscRecording can take this hierarchy, these files, like these real files that are up here, the real folders, they don't have to be in this tree already. They can be anywhere on disk. In fact, with virtual files, they don't have to be on disk at all. You can really build a synthetic file system from pretty much anything, and it's really pretty powerful.
So that's the file system stuff. Now, new in Panther, we have DR Audio Track. DR Audio Track is a set of helper APIs for creating a Redbook audio track, just a standard audio CD track, which you can play in your CD player. And it will import any file that QuickTime can read.
So you don't have to write the decompressors. You don't have to write stuff to translate it into the CDDA format. We'll do it for you. So movies, AIFFs, waves, MP3s, AAC files. As QuickTime moves forward and is able to import more stuff, this will be able to import more stuff. And again, this is new in Panther.
So an audio burn, an audio track by itself is not that exciting, so we decided to put a whole audio burn up here. So again, we've got the burn object up at the top with the properties. And DRAudioTrack, again, is just a special type of DR track where we provide the callback. And we've got a set of files up here. So we've got an MP3 file, an AIFF, and an AEC file. And when you burn this, DiscRecording will just write out a three-track audio CD containing the music from those files.
So let's talk about the user interface. That's the third component. The user interface provides a common interface for burning and erasing. There are setup panels for setting up a burn and erase. And we handle device selection. We handle all the logic of keeping track of state changes. If a user plugs in a device while the panel is up, the panel will notice. If the user unplugs the device, all that code's been written, so you don't have to do it. And we also provide a standard set of options for pretty much anything a user would want to do for burning and erasing.
And we also provide standardized progress panels. You may have seen them in Disc Copy and other applications. Just pretty much a progress bar. Keeps track of things. Can be presented as a sheet on your window or as a standalone panel. We provide a set of icons if you happen to need them for your interface. And the user interface is accessible from both Cocoa and Carbon.
And last year, we promised that we were going to get it in Carbon, we were going to make it available in Carbon, and it didn't quite make it for the release, so here it is for real. And so we're going to take the content and the UI. We're going to bring them together and build a pretty full-featured burning application in just a few lines of code. So let's go ahead and switch back to demo one.
So unfortunately, this is not quite as easy as, say, writing a web browser, because we're going to have to actually write some code. We can't do it entirely in Interface Builder yet. So what we've got-- and I will now move over to demo two. So what we've got, For this demo is we've basically got a very simple app controller. We've added a few skeleton methods to pick files. If you're familiar with NSOpenPanel, which you may be, then this will generally not be a big surprise to you. And other than that, we've got this empty user interface with a couple of big buttons on it.
Nice big buttons, here they are. And they don't do much, yet. So here we are. We've got -- so each of these buttons, there's one hooked up to each of these methods. So let's go through. So we go up to the top. We're going to include our DiscRecording headers. DiscRecording UI is a separate framework, so we're going to import that separately. I'm going to go down past the open panels, Down to here.
And we're going to go ahead and create an audio disc. Well, how do we create an audio disc? Well, the first thing is we're going to ask the user for some files. And once we've got that, we're going to loop through the files. enumerate through them. We're going to create a DR track for each file.
and so we're not actually doing error checking here because this is a demo, but if we were doing error checking, the DRTrack creation method would return nil if QuickTime can't read the file. So we're going to look at all those. Then we are going to invoke our method, which we're going to create in just a moment, for creating a disk.
So we're going to burn the layout. We've created all the tracks in an array. and I have added all those to an array and we're going to burn that as a layout. So then we're going to go up to here. So we've called this method on ourselves burnLayoutWithDescription. Well, we need to create that method.
So what do we do inside that method? Well, first thing we're going to do is create a setup panel. Setup panel is where the user sets up the burn. We've created the setup panel, and we're just going to run it. There are options you can set on it, but we don't really need to set any options. We're happy with the defaults, so we're just going to run it. And if the user hits OK, well, then we're going to go ahead and do the burn. And we do the burn by creating a progress panel.
We're going to put our description into the panel. and then we're going to go ahead and tell the panel to start up. So it begins the progress panel. We get the burn object straight from the setup panel. The setup panel pre-configures a burn object according to whatever the user has selected. So if the user says they don't want to verify That property is already set in the burn object. And we pass in the layout that came into this method.
and that's actually all we need for burning the layout. We're going to run the setup panel, we're going to set the description, then we're going to start the progress panel. So there's not much code there. So we could compile and run and create an audio disc right now. But let's go ahead and do the data disc creation. and I are going to show you how to create a data disk. We're going to call our method that brings up an open panel, select some data files. We're going to go through the files.
We're going to create a virtual folder. For now, since this is a demo, we're just going to give it a standard name of our own. We'll take every file that the user selects, loop through them, And look at it. Figure out whether it's a file or a directory. And if it's a directory, then we create a DR folder. This creates a real DR folder. Otherwise, we're going to create a DR file. So we're going to take whatever the user selects, throw it into one virtual folder. at the root of the volume.
And there we go. We're going to add it to the root folder of the disk. And so we're setting an explicit file system mask here. And this controls, again, which file systems are generated. So for example, if we wanted HFS-- the default is actually to create a cross-platform disk, which would be HFS+, ISO 9660, and Joliet. If we wanted to, we could say, OK, I don't want-- I don't want HFS+, we're just going to do an Isojoliet disk. You can really pretty much do any combination and we'll just generate the file systems that you ask for.
Once we've done that, we're going to again call our method. We're going to create the track right here, DR track, track for root folder. Boom, we've got a file system. and we're going to invoke our method to burn that, bring up the setup panel and do the progress. And that's all. So, let's go ahead and build this.
So what we've done is with just this little bit of code, we've created an application that can burn an audio CD, can burn a data CD, can really burn pretty much anything you need. and I are going to show you how to use this little bit of code to select files and bring up the panels. So let's run it. So here we go. Here's our interface.
So we've got our two buttons. Well, let's go ahead and create an audio disc. Happen to have some music right here. select the files, brings up the burn setup panel. So the burn setup panel, again, You can have options to set the speed, you have whether to verify or not, whether you want to eject or mount after the burn. We're just going to leave those pretty much straightforward. There's already media loaded in the drive, so let's just go ahead and burn.
So there we go, and we're burning an audio CD. That was easy. Well, let's go ahead and burn a data CD while we're at it. So go over here. Let's go to Panther. and others. We've selected three items. And what this is going to do is it's going to bring those all together. and others.
Here's our set-up panel. We're ready to burn. and I will be doing a little bit of a demo of how we can do that. There we go. So the audio disk is going over here. The data disk is building the file systems. and I are here to talk about the new Carbon API. We've created an application that can burn audio discs and data discs and it just works. Which is really pretty cool. Okay. So let's switch back to the slides.
and it really is just that simple. That much code, burning audio CDs, you're burning data CDs. It's really cool. Okay, so now we're going to talk about device profiles, those of you that maybe may be involved with creating and bundling hardware. You're going to be interested in this. So this is something that's-- this is the new way that device support is going to work. and Apple is adopting this for ourselves and we're giving this to you for you to hook into. So let's talk about what device profiles are.
So device profiles are a way for manufacturers, bundlers of drives to add support for their own drives. Without or with reduced interaction from Apple. So if you've been in this situation, you kind of know what has to happen. You have to send drives in, then you have to wait, and then we have to do the work, and you have to wait. And it's no fun for you.
It's no fun for us. And we kind of want to make it a lot easier and a lot smoother. So what we're going to do is a device profile and many others. This is a text file and it's an XML plist file that lives on the hard drive.
It contains two sets of things. If you're familiar with kernel extensions, it's very similar to the way that works in that there's a dictionary describing the matching, and that's called the personality for the profile. And then after we've got the matching criteria, we've got the actual data for the profile.
In each file, we've got information on how the device interprets the MMC specifications. If there happen to be any bugs, God forbid, or quirks in the firmware, as there occasionally are, if 1.0 wasn't quite perfect but the drive got released anyway, you can mark what's broken and still get it to work.
If there are any quirks, such as we'll try to ask the drive what it supports, but if the drive doesn't support it correctly or DiscRecording can't quite figure out what's going on, then you can help us along by telling us in the profile what the drive does and doesn't do.
So Device Profile Editor is an application that's going to be released that creates these profile files and they're and even though they're p lists we want to we want you to use the device profile editor because you know the format is a pretty complicated plist and we don't want to have any mistakes you don't have to dig in there with property list editor where you're going to get this nice ui and the device profile letter will be responsible for validating profiles so it'll when you tell when you tell us like what the drive supports we're going to run a battery of tests against the drive make sure that disk recording really can talk to the device so it's kind of eliminates a lot of the testing makes it automatic gets rid of some of the support hassles and this is going to be a requirement for you know official support So without further ado, let's do a demo of the device profile editor. Switch back over to demo one.
and here it is. Here's the device profile editor. So we're a vendor, say we're Say we're Example Co. and we're working on a CDRW 9000. Well, if we've shipped that under any other vendor names, perhaps generic or perhaps we've shipped it with no vendor name at all, then you can indicate that here. You can pretty much list any of the alternate vendor names that you may have rebranded the drive as.
Then we've got the basic feature support. In general, DiscRecording will try to use MMC and auto-detect all of this stuff, but occasionally there's something that the drive does or doesn't do that DiscRecording won't be able to automatically sense. So you can leave everything on AutoSense. In fact, for the CDRW 9000, we'll just say that we'll leave everything on AutoSense and we'll run the tests. And if it works, then great.
So the one thing that we do need down here is if the device-- DiscRecording has a couple of things. All Sony drives have a couple of characteristics in common. All Pioneer drives have a couple of characteristics in common. We know a little bit about drives from various vendors.
So if there's a device that's from a particular vendor, it helps to know that. So you can put the actual vendor name in here. And that helps DiscRecording a little bit. For example, if you've rebranded the drive, you can tell us who it actually comes from. And then we'll make sure we get the right stuff in there.
So various things, if you happen to know that there are some drives that can't handle particular CDB commands, if that happens, then Then you can go ahead and exclude them and tell DiscRecording never send this command because the drive might hang the bus or otherwise wedge. If we have different options, parameters that drive can't handle, if there's CD burn speeds that it can't handle, or if you want to enumerate just the good speeds, you can include them.
And so you'll create the profile with this. You can actually create more than one. So let's go ahead and create another one. Again, this is Example Co., CDRW5000. Let's say the CDRW 5000 is an older drive. It might report that it does session at once, but it was kind of broken and this recording can't really talk to it very well. So we're going to disable session at once.
and perhaps it doesn't report DVD support correctly. Well, we'll disable all the DVD burning too. And then you can run your battery of tests against this and again, if it all works, then it passes and you can, it'll create a file, a DR profile file, which you can save.
So that's our example code drive support. And we can install that with an installer or even have the user do it themselves. And then DiscRecording will be able to burn to that drive. And again, this is a Panther thing. So it's new in Panther. And we're still kind of working on it. So we would really like feedback on how it all works. Okay, so we're running just a little bit over, so let's kick back to the slides.
All right. So if you're interested in the device profile editor, come up to us after the session. Give us your card. We'll get you on a list. and we'll see that to you when it's ready for actual testing and we'll get you on a list for feedback. So developer resources, we've got a lot of sample code in both C and Objective-C.
The sample code covers audio and data burning and erasing. We're going to try to get-- we've got some new sample code, and we're going to try to get the demos that we just did up as sample code. There's the URL to the sample code. We've also got a public mailing list in which you can get on, ask your questions. It's good to ask your questions in public because someone else may have already had the problem you're having or someone else may encounter it in the future. And it's all archived so people can search the archives and get help that way.
So we've got documentation, DiscRecording services, and it's-- I believe it's also under Cocoa. We're kind of a technology that's both Carbon and Cocoa. So this path says that we're in Carbon, but also on connect.apple.com, we've got some new reference documentation for Panther only, and that's under connect.apple.com because it's Panther and it's under NDA for now. and I will bring Patrick back up to do the wrap-up.
To follow up, as Drew was mentioning, that we do want to get all your feedback. So the contact information up above would be the best way to do that and primarily go through me and then I can disseminate it to the appropriate engineers and keep everything in order. But this is something we're really excited about with Panther. And anyone that has to go through the process of getting Drive certified will see all the benefits.
So, anyway, um... So there's a few sessions that you might be interested in as well. Audio formats, today at 5:00. Cocoa user interface programming, tomorrow. QuickTime and enhanced CDs, which is Thursday at 10:30. And writing threaded applications. So if you want to stay on this subject, please attend those.