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: wwdc2006-410
$eventId
ID of event: wwdc2006
$eventContentId
ID of session without event part: 410
$eventShortId
Shortened ID of event: wwdc06
$year
Year of session: 2006
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC06 • Session 410

Designing Standards-Based Devices

OS Foundations • 1:11:18

Designing standards-compliant devices for the Mac OS X platform is a huge win for both developers and users. Learn what it takes to make your products work out-of-the-box with Mac OS X, without requiring custom drivers. You'll learn about how to design mass storage, audio, video, and communication products to work seamlessly with FireWire and USB.

Speakers: Kai Kaahaaina, Fernando Urbina, Russ Winsper, Torrey Walker, Eric Anderson

Unlisted on Apple Developer site

Transcript

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

Hi everyone, welcome to session 410, Designing Standards-Based Devices. Today we're going to have four speakers. I'm the first. So my name is Kai Kaahaaina, and I work for-- well, obviously I work for Apple Computer, but I work for the mass storage software team, implementing and maintaining storage device drivers for OS X.

Today I'll be talking about USB mass storage class devices. And so for the next about 10 to 15 minutes, we're going to quickly go over the specifications that we follow and adhere to when implementing and maintaining storage drivers in OS X. Common errors we've had reported to us by customers, developers, and our own internal QA. Mac platform-specific testing we recommend that you perform in the course of developing your USB storage devices for OS X. And Mac platform-specific-- sorry, Mac platform enhancements which we offer you to give your users on the Mac OS X side a richer experience.

So first up, the USB specifications that we follow. Naturally, there's the Universal Serial Bus Specification and the Universal Serial Bus Mass Storage Class Specification, both of which are extremely important. I recommend that you should at least read very thoroughly the Universal Serial Bus Mass Storage Class Specification. Next up are the two transport protocol specifications, which are USB Mass Storage Class Bulk-on-Lin Transport, which is what the majority of devices we've seen utilize, and USB Mass Storage CBI Transport, which is underutilized but has many benefits, and I think many of the devices we see could have been implemented better had they used this other transport. So please consider both before you start to design a device. And lastly is the USB/UFI specification. The USB/UFI specification is of course for the ubiquitous USB floppy drive, which is still in production.

I thought it was funny. So the next category of specifications which we follow are the-- oh, and these can be downloaded from t10.org, by the way, sorry-- are the SCSI primary command specification, which all SCSI devices need to adhere to. And then the next three are a specification which you would choose based upon the type of device you're trying to implement.

So most of your block storage devices for USB have traditionally been SCSI block command devices, or SBC. And these are going to be your flash drives, your mass storage compliant camera and such. Next up are SCSI multimedia commands, MMC, which are all of your optical-based devices, so your CD and DVD burners.

And lastly, there's reduced block commands, or RBC, which we've largely seen only on the FireWire side of the world. But there's absolutely no reason why you couldn't implement your USB storage devices, RBC. It's actually quite a bit simpler to implement than SBC, and I recommend you definitely consider that if you have the opportunity to start a device from scratch.

So these are the common device types that we see the most often. And these, of course, are the semi-ubiquitous, bulk-only transport SBC devices. These include the Apple iPod, flash drives, cameras, media card readers, USB hard drives, just about everything, except the following, which is bulk-only MMC devices, which again, are the CD and DVD burners of the world, and the UFI floppy drives, which continuously stay in production.

Next up are common errors. These are the ones we get the most in regards to internal testing and tech support calls. Some of these are architectural differences between how we handle certain things such as power management, like in the case of suspend resume and other operating systems. So suspend resume is one of the power management features that we try to exercise a lot in OS X. And we've seen a lot of devices which simply upon receiving a suspend or resume command, just simply freak out.

And they stop working, and we have to reset the device. And that's if we know it doesn't support the command. If we don't know it doesn't support the command, say after sleeping and waking a system, a user will find that their device is now not usable. So that's not good.

So if you're going to implement a USB storage device, please ensure that it handles both USB suspend and USB resume correctly. Next up is bulk-only reset, which is part of the bulk-only transport protocol. We've actually seen a large number of devices which just simply don't implement this feature. For bulk-only transport devices, it's our preferred mechanism for trying to recover a device after it's encountered an error.

So if this feature isn't properly implemented, what happens is there's the original device error, then a subsequent error on our attempt to recover the device, and then we have to do a second recovery effort with a full USB device reset, which is very heavy-handed. And if it's a multiple interface device, it can have other consequences. So we prefer not to do as much as possible. But if bulk-only reset is not implemented, we have to. So please support bulk-only reset. It's there for a very good reason.

Another bulk-only feature which we sometimes see left off is the bulk-only get max LUN. So for us, if this command is responded to with an error, we just assume your device has a max LUN of zero, which, if you have a multi-LUN device, is pretty poor because it means only one of your LUNs is going to get used.

So another thing about Max LUN is not to confuse Max LUN with LUN count. We've seen a number of devices where they report their Max LUN as a count of their LUNs they have. So we go to utilize this phantom fifth or seventh LUN, which doesn't exist. So it's very important to not confuse the two and report the maximum logical unit number you have for get Max LUN.

And lastly for this slide, it's very important to us that you provide a very unique vendor ID and a product ID. And there's really two reasons for that. One is user interfaces will report this data in, say, system profile or disk utility. And it's easier for the user to tell their devices apart if they actually have unique IDs. And the second is, if we ever have to implement workarounds in OS X, we use these keys to help identify your device.

So another area where we see a lot of issues is the SCSI inquiry data for devices. We see a lot of devices where they report the additional length with inquiry data, additional length incorrectly. So as a consequence, we either end up asking for too much or too little inquiry data, and that just never ends well. So the next two fields are for your product and vendor identification strings in the inquiry data.

We've seen a lot of devices which simply say generic, or storage, or USB mass storage, or blank. And we have a number of apps like Disk Utility and Disk Recording where the user is going to try to select your device from a field or from a pop-up menu, and they're not going to quite understand that, oh, my DVD burner is a generic bulk-only storage device, you know, blah, blah, blah. So please choose sensible and unique product and vendor strings to identify your device, because the user will see these.

And lastly, product revision level. Every time you release a new revision of your product and you've done all the work, please bump the product revision level as well. It makes it easier for us when we get bugger requests to say which version of your device was used which may have caused a problem that we need to address in the host.

So, one we've been seeing more and more lately is devices which, in the ModeSense data, do not properly report back, if whether or not the device is write-protected. So, obviously what happens here is that we assume that the device isn't write-protected if it reports itself as not being write-protected.

And we end up with this kind of mismatch between what the GUI represents and what the actual state of the machine is. So we get these cases with, in particular, certain phones, per se, where the user, it looks like, for all intents and purposes, can copy a file to their phone. But they can't because it's actually write-protected. And we get really bizarre errors for the user, which makes for a really poor user experience. So please, honestly report write-protected status correctly. Next is manual eject.

And this is kind of a trickier one. So in OS X, we like to control the media as much as possible. Because we're trying to prevent users from untimely removing media from a device before we've had a chance to gracefully unmount the volume. This is particularly true of devices which are using a journaled file system.

So how we do this is we send a start-stop command-- sorry, a prevent-allow-media-removal command. And if you can't physically bar the user from removing the media-- let's say you have a flash card reader or some such-- it's very important that you report back not supported or failed a command so that we know we need to pull your device for media removal or addition.

Synchronize cache. So the primary file system of OS X is HFS+ journaled, or HFS+J. And part of what makes this file system work correctly, especially the journal aspect, is support for the synchronized cache command. And we've seen a large number of USB to ATA and SATA bridges which simply take the synchronized cache command and then drop it on the floor and never pass it on to the ATA device.

As a result, we defeat a lot of the good support that the journal file systems get us. And this isn't just for HFS+J, it's for a lot of the number of Linux and other journal file systems which exist. So, especially if you're doing USB hard drives, it's very important that you support the synchronized cache command.

Next up is max transfer size. We've seen a lot of devices which simply just do not provide more than 128 blocks in a single transfer. For performance reasons in OS X, we like to reduce the amount of overhead for doing large transfers as much as possible. So we will always try to ask for as much data as we think we can reasonably get from your device. So please try to support more than 128 block transfers. And if you can't, please don't pad out the rest of the request with zeros, because we've seen that too. That leads to data corruption.

So Mac OS X-specific testing. It's real basic. What we recommend most often is just connect your device and plug it in, make sure it mounts, make sure it works, copy files, try to do all the basic things you would expect a user to do. But in addition to that, also try doing sleep-wake testing, where you put the system to sleep, wake it up, and make sure the device still works correctly. If you have a removable media device, we recommend that you try putting it to sleep and then waking up without media in it, and then try to see if it'll still accept new media after it wakes up.

and also do some restart testing where you power off the machine and then turn it back on or restart from a powered-on Mac to see if the device remounts after power on. And lastly, try testing with some non-FAT16 or FAT32 file systems. HFS+ and HFSJ work a little bit differently, so it's great if you can try them out on your device, in addition to the FAT and FAT32 file systems you'll be using mostly for other operating systems.

So some cool enhancements we have for OS X. So we have a lot of media card readers that we use at work, for personal and for professional use. And they're kind of neat. But the thing that's kind of disappointing about them is, it doesn't matter what kind of media you put into them, you get the same icon.

So it doesn't matter if you put in smart media or compact flash, you're going to get the same generic white removal media icon. So we thought of a really cool way of making it so that you can get more than this. So how this works is, there's a vendor specific data field in your inquiry data.

And what you can do is, you can put in the correct identification string for one of the icons we have into this field, and when we see that you have new media, we will then read your inquiry data and parse the string in this field. If it matches with one of the ones in our table, we give you the icon appropriate.

So if you use our strings and put it in the right place at the right time, so what does that get you? Well, today I'll get you this if you don't do it, or if it's a string that we don't recognize. It's the generic rule media icon which you've had since as far as I can remember. But let's say you put in the string for smart media, you could have something which looks much more like this.

Which, you know, actually looks like what was the user put into their media, which-- sorry, put into the reader, which, if you're running with multiple types of media at the same time, enables you to tell one apart from the other without even having to bother to read the volume name.

So, do we support more than the smart media? Oh yeah. So we have CompactFlash, Smart Media, MemoryStick, Secure Digital and MMC, which at the moment I'll omit are actually the same icon, but I'm working on that. And that's what we have in Tiger today. You can actually go home, edit your firmware for your device, and try these out now. These have been shipping since 10.4.2 and are not going anywhere. So what are we bringing to Leopard? We're adding a few more.

We're adding XD, MiniSD, MemoryStick Duo Pro, and TransFlash. Now, I've only brought these up in the context of media card readers. There's absolutely no reason why you couldn't use this for your digital camera, phone, or anything else. You just need to put the right string into the inquiry data.

If you have any other ideas for what you want your device to be, you can always contact ADC, and we can see what we can do. It's a neat little enhancement, and we think it provides for a better experience for your Mac customers. And, well, I like it, because I've got to do something gooey for a change. So with that, I will please ask Nana to come up to the stage.

Thank you, Kai. I would like to tell the people in the overflow room that we have a couple seats left here and you're welcome to come on over. My name is Fernando Urbina and I'm going to talk to you about the USB video class. This is like the third or fourth year that I've been mentioning it.

And finally, we're coming to the point in the market where a lot of hardware developers and firmware developers are producing these devices. And I'm really looking forward now to having lots of options with supporting these new devices. The official name of the spec that you can find in the USB Implementers Forum is the Universal Serial Bus Device Class Definition for Video Devices. And currently it's at Revision 1.1. The changes from 1.0 to 1.1 were fairly minor and were based just on some feedback that we received once it got out into the public.

If you are developing a device, I want a sample of it. I want to make sure that my driver works with as many devices as possible. There's lots of things that you can implement and that you can not implement, or perhaps implement a little bit differently. So it would be great if we have samples so that we can test them, make sure they work, and your customers will be happy.

The spec itself is composed of four different sets of documents. There is the core video specification that has all the descriptors, the requests, negotiation, everything that is at a fairly general level. Then we have what we call the payload format specifications. Quite obviously, each of these documents describe different payload formats that are supported by the spec and how they look and what needs to be in the data stream, etc.

There's also a transport terminal specification for devices where you can actually send video and control the playing of that video on the device. That's from host to device. And there's a couple of miscellaneous documents. One that is the identifiers document that actually has the values that are used in the different descriptors.

An example of a simple video class device and how all the descriptors look. And finally, there's also a frequently asked question document that is fairly good. To tell you about how we reach some of the decisions on what we're supporting and maybe some things that are not quite clear in the specification, but that they're valuable for you to read and see how it works.

In Mac OS X, since Tiger came out, we have supported USB, UVC devices, modules on bugs. But that keeps getting better as I get more devices and can test my software better. We still only support webcams that have a motion JPEG or uncompressed payload format. We have not seen many, if any, devices that support the still image portion of the specification, so we don't have that support in there yet.

If and when we start getting those devices, we are going to add that support and tie it in somehow with the image capture framework. We are looking at how best to support extension units from the specification. Extension units are... A method to allow vendors to extend the specification.

We obviously don't want vendors to have to reinvent the wheel and implement a whole UVC driver in order to add support to their particular enhancements. So if you have any thoughts about how best it would be for us to implement this support, please get in touch with me and I will be more than happy to listen and see what we can do to best do that. Currently we only expose the traditional analog control of brightness, saturation, hue that QuickTime exposes.

So there is no way for us to test in a generic way the white balance, auto exposure, power line frequency, all those other processing unit requests that the SPECTOX2, that the RSS talks about. But I'm looking into ways that will allow me to expose this at least for testing. UVC webcams will be supported in that part in iChat and Photo Booth. We are also looking at supporting other payload formats from the spec. Again, this is possible only if we get devices that support other payload formats.

As far as testing your device, there's two sections. One's testing it at the USB implementer's forum level, and that's what I call the compliance testing. First of all, you should make sure that your device is a good USB citizen, and that's why you use the USB-CV tool from the Implementers Forum.

In order to use this tool, you need to use Windows and attach it to a high-speed hub. Of course, you can now use Boot Camp on the same hardware and test it that way. And it is essentially a Chapter 9 test, Chapter 9 of the USB 2.0 spec.

The latest beta of this USB-CV tool is 1.3 beta, and that has support for verification of USB video class devices. It is only an indication, it's only a descriptor type of verification. Obviously, it doesn't test whether all your formats do display video, add frame rates, and all that stuff. But it is something that will give you an idea whether all your descriptors are correct or not. Finally, I'm sure that if you're developing a UVC device, you would also test with Windows XP, but I put that bullet anyways to remind you to do so.

On the Mac OS, the software entity that includes the UVC driver is the QuickTime USB VDC Digitizer component that lives in the system library QuickTime folder. Time Player Pro will allow you to preview, Video Streaming and Recording: Over on the developer site, we have WAC-TV and the venerable HAC-TV.

You can download this, compile, it allows you to To change things and you have the source code so you can do lots of things with it. You also can access the video settings and get at the analog controls that are exposed by QuickTime that you cannot do in QuickTime Player.

Of course, we have USB Prober that is installed by the developer tools and by our logging families that are on the website. And that allows you to look at the descriptors for your device. I have tried to do my best to make sure that the coding is correct, but if you find a bug, please submit a bug report so that I can go ahead and fix it.

One thing that you should know is that we use the USB product name to display the camera name to the user. For example, iChat will use your camera name for the preview window. So put something in there that is good, that identifies your device, instead of just, like Kai was saying, a generic name.

A couple of things that are specific to Mac OS, and the first one is bandwidth management. Once we do the probe-commit negotiation to arrive at a certain setting for your device, I will go and look for the alternate interface that has the same or higher amount of bandwidth. But then, after I select that alternate interface, I will go and use our SetPipePolicy API to return bandwidth to the system.

And I use the negotiated DW Max Payload Transfer size to arrive at the bandwidth that your device is going to use. So if you don't report a correct Max Payload Transfer size, your device is going to overrun. And when we get overruns on ISOC, we drop the frame because we won't get the data. And I've seen some prototype devices that actually did that. So be sure that Max Payload Transfer size is reported correctly. Under QuickTime, as opposed to in the Windows world, when you are previewing, you have no control over the format that the preview is in.

Like YUV 422 or Motion JPEG if the camera supports both of them at the same frame rate and the same size. The digitizer component essentially chooses which one it will report, and as it happens, we always report YUV uncompressed if it's available. So I have a little default that will allow you to test motion JPEG by telling the video digitizer that you would like to prefer motion JPEG. And the command that you would use is up there on the screen. Once the digitizer sees this, then it'll prefer motion JPEG and you can preview that. With that, I would like to bring up Russ Winspear to talk about communication class devices. Thank you.

Thank you, Daniel. My name is Russ Winsper, and I am responsible for the communications class driver, amongst other things, and commonly known as the CDC driver or comms class driver. I'm going to talk a little bit about the standard itself, what we've implemented, and then go a little bit into the architecture of the driver, and then touch on some common problems. The CDC standard really is defined as a number of control models that are kind of roughly grouped into the groups you see here. There's actually currently 13 models described. Modems has about four. ISDN has a couple. The networking, there's a couple more.

Basically, the most common, which is the abstract control model for modems, the Ethernet control model for networking, and a fairly new one, which is the device management model, and I'll get into that a little bit later. The abstract control model modem assumes that on the end of the wire is a full-function modem with everything in there, data access arrangement, data pump, and all those kinds of things.

The other models which define kind of less functionality in the device, there's the direct line model, the telephone line model, so by far the most common is the abstract control model. The Ethernet control model is an attempt to allow a host to be connected to Ethernet using a USB-connected device. And unfortunately, there's a few shortcomings in the Ethernet control model, which have kind of not made it widely implemented.

By Ethernet devices, but it did find a home with cable modems and DSL devices, so it is used. And then the device management model is fairly new, and it really revolves around multi-function devices and the ability to control them on a device basis. And again, I'll talk a little bit more about that later.

Futures. Basically, Apple has planned to support class devices if the devices appear. We're currently interested in a new model, which is the Ethernet Emulation Model. This really differs from the Ethernet control model in the fact that it's built for low-cost devices that don't really want to have a full media access control in them and connect them to the host. So it's not connecting a host to Ethernet, it's connecting a device to the host, using Ethernet-like protocols. Currently being worked on is a new model that's being called the Network Control Model. This may not be its final name.

The thrust of this is really to change some of the shortcomings in the Ethernet control model. And what it'll finally turn out to be is going to be interesting. As the work goes on, they're pushing a little bit higher up into the IP stack. And again, that may or may not be the case in the end.

But we'll see. It's very, very early. And in fact, the early draft, I'm not even sure .8's been posted yet. But they're in that very, very early stage. And again, like some of the other guys have mentioned, the best way to get Apple's attention with any of these new devices is to send us a device. And we'll see if we can make it work.

Okay, just a few words about the USB Implementers Forum. The CDC Device Working Group is an active working group, which I've mentioned. They are working on the network control model. I did talk a little bit about the differences between ECM and the NCM. But again, NCM is trying to fix some of the shortcomings of ECM. And the specs are posted at the approved docs website.

What I'd like to talk about now is a little bit about the driver architecture, which we changed fairly recently. And there's been a number of questions about, first of all, why we changed it. And then what we did to it made it a little more complicated from an overall point of view, but actually made some of the drivers a bit more easier. But anyway, starting with the hardware and the USB family devices plugged in, device matching gets kicked off, and we have a very small device driver that gets loaded.

This guy looks at the device to make sure there's a valid configuration we can play with, either Ethernet or abstract control model. And if there is, he then does a set configuration, turns around, which causes interface matching. Now, the way the standard's built, there's a control interface and a data interface for each entity, for ACM and ECM, for the Ethernet and the ECM, and for the ACM. And so, for the simulation model, that's not true, but for the main two that we've implemented, it's true. So, we have to load two interface drivers, one for control, one for data.

These interface drivers then, with the help of the device driver, have to rendezvous -- rendezvous being a generic term here -- with one another. And so, the right control driver and the right data driver can hook up and provide the services that they need. Once that's happened, the ECM takes a look at the specifics of the interfaces, and if he figures that we can actually drive this device, he then creates the necessary ports through the upper layers, with, in the case of the ACM, the serial family, and in the case of the ECM, the networking family. So, from a -- From a high level, it looks fairly complicated, but in actual fact, the ACM control and ACM data drivers and the ECM control and ECM data drivers are a lot simpler than the original device driver.

And again, why did we do this? Initially, when we first started to see modems in particular appear, they were single-function devices with just one interface on them, with one CDC interface on them. They had a control and data interface, obviously. And a single-device driver was OK for these devices.

Then we started to see multi-function devices. We started to see devices with mass storage interfaces on them. We started to see them with audio interfaces on them. We started to see one of the standards as an OBEX interface. So interface drivers are definitely the way to go. So we had to change it to make sure that once our device-- if it's classed as a COM device, once our device driver instantiates the interfaces, or does the set config to instantiate the interfaces, then the right drivers get loaded for the other devices-- the mass storage, the audio, and all the others. So that was really the reason-- like I say, it looks a bit more complicated. But in actual fact, it's kind of made it a little easier.

And lastly, common problems. Again, what we see, a couple of the guys have already touched on, Kai in particular, suspend and resume. Suspend and resume never seems to work. And if you suspend a device that doesn't like being suspended, it does weird and wonderful things. So if you're building devices, make sure that they support suspend and resume.

And the other problem we see with com class devices are problems with the, what's called a functional descriptors. And we see problems with where, sometimes where these functional descriptors are placed, placed in the wrong place, so that once we've found the control interface, we can't find the functional descriptors. And then common problems are the union descriptors and some of the SCM functional descriptors and the ECM functional descriptors pointing to the wrong data descriptor.

And if that happens, especially if there's more than one interface on a device or we've got multiple devices and we have a real hard time hooking up the right control and data. So just make sure that you really have the right descriptors sorted out in the functional descriptors. And basically, that's kind of it. I turn it over now to Torrey and talk about audio.

Thank you for not handing me the sharp end. My name is Torrey Walker. I'm with the CPU Audio Software team, and I'm going to be talking a little bit about the USB audio device class. So, show of hands here, how many of you have ever taken, say, a USB headset, or microphone, or breakout box, or anything like that, plugged it into your computer, and have it just work? And keep your hands up if you like the fact that you didn't have to install a driver to get that to happen.

Alright, so this is what the class driver is going to afford you. In Mac OS X, the class driver is called Apple USB Audio, and it supports full-speed devices that's USB 1.1, full-speed devices that conform to the USB device class specification for audio devices, release version 1.0, which I'm just going to call the USB audio spec from here on out. And it's available for download at USB.org.

It's going to allow access to the basic functions of your audio device. Even when there's no third-party driver present, it's going to be thoroughly tested from release to release to make sure that compatibility is retained. And that will allow some immunity to things like platform changes, moving from PPC to Intel, 32-bit to 64-bit. Also, it hides the differences between the three different USB controller types, OHCI, UHCI, and EHCI. So, the user doesn't have to be concerned about them, and nor does the developer.

Also, it peacefully coexists with third-party drivers, so if you want to write a driver still to support your device, then we report a low match score and we'll gracefully back away and let you support it. So... How can I design a class-compliant USB audio device using established technology? Well, if you're already adhering to the USB specification, all you basically need to do is make sure that you properly report the capabilities of your device in the descriptor, which is basically section 4 of the USB audio specification. So, I want to talk a little bit about what works and what causes problems, and then we'll discuss a few techniques for designing class-compliant descriptors.

So, what works in USB Audio 1.0? Number one, simple device topologies. There are a number of different units and terminals that are supported by the class driver, and a few of them we can use to publish controls, such as Feature Unit or Selector Unit. However, we have to make a choice about which of these to use to publish controls to the user.

For example, let's say that you have a very simple device topology, and this one has just an input terminal and an output terminal between it and an extension unit, which the driver is not going to know what to do with because that's vendor-specific. But then there's a single feature unit that has controls. Now, for this speaker jack, or for this speaker, we know that if there are going to be controls that are published for this device, they have to be associated with this one feature unit, because there's only one on the signal path, there's no ambiguity.

On the other hand, if you want to take a look at a little more complex example here, you'll see that there are two feature units here, and there's a mixer unit between them, and then maybe the mixer unit is connected to other stuff as well. The driver has to make a choice about which of these to use to publish controls, and if there's more than one, we're going to make a choice, but there's no guarantee that it's going to be the one that the developer had actually intended. So you can help avoid confusion like that by only publishing what you actually want the controls to come from.

Another thing that works in USB 1.0 audio is reporting the maximum packet size correctly. I want to mention this specifically because we used to not care, and now we do. If your maximum packet size is too low, you could end up generating overruns, and that will cause streaming artifacts to make your beautiful, soothing classical music sound like something that will truly make your hair stand on end. You can guess I've probably had a few experiences with devices like this, and other unpredictable behavior could also occur.

Another thing that works: publishing compatible input and output formats. This is probably the most egregious and widespread problem that I see with devices. If a device cannot simultaneously support two different types of sample formats, then they cannot be published at the same time. This isn't explicitly written in the specification, but it kind of follows as an unwritten corollary. Take for example, you've got a device that supports two different sample rates: 44.1 and 48k for input and output.

However, you've got this single sample clock that has to control both of them. So if the user says, "Hey, let me change the input sample rate from 44.1 to 48k," and the output moves as well, the driver has no way to know that. And because of that, you'll start to generate things like overruns and errors, and then eventually, you know, your device may sound like this.

Okay? So, one way to work around this is to maybe provide a hardware switch. And the hardware switch will provide a different descriptor for each setting, where there will only be this one sample rate that's supported. So maybe, while it's set at 44.1, the device can only do 44.1.

You switch it to 48k, unplug it, plug it back in, new descriptor, only 48k. If something like this is beyond the scope of your hardware project, you may even want to consider only publishing a single sample rate that you think will be very important to your customers. And this way, there's not going to be any confusion.

How do I go class-compliant? One way to do this is to go out and acquire a class-compliant device and check out its descriptor using USBProber, which is included in the developer's package. Also, Apple USB Audio is open source. You can download it, compile it, take a look at what Apple USB Audio does for your device. You can look at the logging in USB Prober using USB logging.

You can download the FireWire SDK and change it to printf style, and look at that logging as well. And also examine the logs of other devices, particularly if your device is doing something wrong, you can take a look at a device that does something right, and try to figure out what the difference is there.

Also, if you're going to use Apple USB Audio as a base for your third-party driver, please keep in mind the open source agreement. If you make changes to the driver, then you need to make your changes public so that other people can look at them as well. Finally, use Apple as a resource.

We really want to help you develop class-compliant stuff. So if you send us a device and you're like, "Hey, I think I'm doing this right, but I see strange behavior under Mac OS X," we'll take a look at it. And if there's a problem with the driver, we will fix it. And if it's a problem with your firmware, please fix it.

All right, so what's on the horizon? USB 2.0 audio. So the question here is, how can I make my USB 2.0 audio device work with a class driver? Right now there's no support for USB 2.0 audio descriptors in the class driver, but the specification has yet to be released. So the rapidity with which Apple USB audio will come to support these devices will depend on how quickly we get devices that have class-compliant firmware that we can use to bring up our new driver.

Once again, the support will basically come from what capabilities are reported by the device and the descriptor. So, I'll talk a little bit about the audio specification, Frankenstein devices, as we like to call them, and why you shouldn't develop them. And then we'll talk a little bit about one of the largest changes about the new specification: clock domains. So, the USB 2.0 audio spec.

It's in review right now and will soon be available for download. Actually, I was hitting refresh on a web page while Nano was speaking, sorry, and it's not up there yet, but I do expect it to be posted very soon. And it will be for download in USB.org.

Actually, there was a better link earlier that was provided. It's in the developer section. It supports both full and high-speed devices. So if you've got a full-speed device and you want to take advantage of something in the USB 2.0 audio spec, you don't necessarily have to be a high-speed device to use it.

The USB 2.0 audio spec contains some major changes to the USB 1.0 audio spec. Particularly, there are some changes in the standard device descriptors, so if you're familiar with how they were formatted before, double-check them and make sure that they still work. And also, these changes are going to be detailed in a document called Migrating USB 1.0 Audio to USB 2.0, which is going to be made available to you shortly after the specification has finally been released. Most of the work is already done on this, but it would be irresponsible of me to provide it to you without first verifying it against the final specification.

So, now, Frankenstein devices. Maybe this name caught your attention. A Frankenstein device is a high-speed device that broadcasts a USB 1.0 audio specification descriptor. Meaning, you say you're a high-speed device, but you're acting like you can be supported by this old specification. Now, this is bad because the USB 2.0 audio spec specifically disallows the creation of such devices. And I've seen a lot of devices now where, say, you've got a composite device that has video on it and audio. And it's a high-speed device, so it can move all that video media. And then it has the USB 1.0 audio descriptor as well.

This can cause a lot of problems. And I've heard that there are a number of Frankenstein devices that have already been released into the wild. But even if they do appear to work fine with Mac OS X, this is not by design. Apple USB Audio does not officially support these devices.

And moreover, if you decide to make a device like this, you do it at your own peril. Apple USB Audio could be changed to disallow the support of these devices. So if you want to make a high-speed USB audio device, you need to go ahead and start taking a look at the specification. And get us a device, and we'll help you out with it.

[Transcript missing]

If you have the same clock source, we can put you on the same I/O audio engine, which is something we were never able to do before. If you've ever taken a look at digital audio workstations software, and you plug in a USB audio device that has input and output, a lot of times you'll see them show up as two different devices. We have to assume that they're independent because we don't know.

But in USB 2.0, we do, and we can finally take that and put them on the same engine. Now, if I can get you to take anything away from this talk at all, I would say first of all, if you follow the specification, we will do your driver development for you.

I don't know any other way I can put that to say, we're going to do free work for you if you just give us a device and you try to follow the spec. Okay? Next, if Apple USB audio is not suitable for your device, let us know so we can improve it.

One of the biggest complaints in the past about Apple USB audio was the latency. Our round trip latency through Core Audio was about 16 milliseconds. Well, I'm proud to announce that since our first shipping Intel Macs, on PPC and Intel, the round trip latency is just a little bit over 9 milliseconds. So that's something that you can look forward to if you were worried about... You can clap if you want.

If you were worried about the latency of the Apple USB Audio driver, maybe it won't be as big a concern for you right now. And if there are other advanced features supported by the specification that the driver doesn't deal with, let us know. We'll put that support in for you.

Also, I also want to stress, you can be class-compliant and still write your own driver. But when you write your own driver, you provide yourself a certain immunity to different platform changes. Like, the new Mac Pros are coming out, moving 32-64-bit DMA. With Apple USB Audio, you're already good to go. You plug in your device, it still works. And the same was true when we moved from PPC to Intel.

You plug in your device, it was still good to go. Because we test from revision to revision, we make sure that this stuff continues to work for you. Now, if your device is class-compliant, and your driver doesn't work on a new architecture, you can always say to your users, why don't you remove our driver for now, and let it be class-compliant for a while, and then we'll provide a new driver for you in the future.

This way, your customers can continue to use your device while you do your driver bring-up. And finally, if you are designing a full or high-speed class-compliant device, let us know so we can help you make it class-compliant. And with that, I will turn it over to our fifth of four speakers, Eric Anderson.

Okay, I was going to make a joke about the four speakers, but that's already been done for me, so moving right along. It's the same message as the first four said. We do want you to differentiate. We want you to make unique, novel products on your terms. Differentiate to make your product better, not just by mistake to make it different so that we have to cope with it in the drivers. The best way is to start with a standard and then differentiate from there to add value.

So I'm going to go over a variety of FireWire standards that we have standard support for. These are places you could start to base a product on. For each of these, I'll show you where to get the specifications, how to match your device, and review some of the common hazards that you might run into.

Much of the information will be duplicated, so the mass storage section will have a lot in it that really applies to the other five as well. In this section, there's going to be reference to a lot of tools in the FireWire SDK, so to try any of this stuff out, just go on the web and download the SDK. It's at the URL that you see there.

So, mass storage and SCSI-like devices. Probably the most common thing we find on FireWire is a hard drive, or an optical drive, or something that has a sort of SCSI architecture, like maybe a high-end scanner. The standards for these come from T10, the same as Kai mentioned earlier. These devices are often architected using a bridge. So, as the picture illustrates, you have a box, which is your hard drive. Most of it is occupied by a hard drive mechanism inside that has some native interface, like Serial ATA.

That native interface connects to a bridge that turns it into FireWire, which then connects to PHY silicon, which actually drives the FireWire ports. Illustrated here is a device with two FireWire 800 ports and one FireWire 400 port, all driven from the same PHY silicon. So, that's what we normally see in this kind of product, is this architecture of these devices chained together like that.

So, how do we support that in software? We have two drivers that may matter to you. One is in the boot ROM, so that we can boot from FireWire storage devices, and the other is built into Mac OS X, so that they will appear in the Finder. These drivers match the 1394 configuration ROM that we find in your device. Specifically, you publish a unit directory indicating that you use the SBP2, or Serial Bus Protocol 2, protocol.

This is the first place that you need to differentiate, is in the config ROM. You need to indicate your vendor and model ID, and you need to indicate a unique serial number in every device. In FireWire, that's known as a GUID, Globally Unique ID. Shown here on the lower left is Apple System Profiler for a FireWire hard drive. Actually, it's a Mac in target disk mode that I plugged in. Shown on the right is one of the tools from the SDK, Firecracker, which shows the 1394 configuration ROM in that device. So I just want to briefly point out how these correlate.

In the red block, you can see the GUID. It's a 64-bit number that comes from near the top of the configuration ROM. And that has been decoded a little bit by Firecracker to show who the vendor ID is, for example. At the bottom, you can see that also shows up in Apple System Profiler, just as a 16-bit hex number.

And then a little further down, in the config ROM in the root directory, there's two very important keys. Key 17-hex is the model ID. It's a 24-bit number that says, "Of all the great products you make, which one is this?" And that key is immediately followed by a text leaf that has an ASCII string describing the product. In this case, you can see the ASCII bytes for target disk mode, and that's what we put in Apple System Profiler to tell the user what this device is. So, I mentioned it's common to use bridge silicon to make these devices.

If you start with an evaluation kit from, say, the Cambridge Semiconductor Company, and you plug it in, the config ROM may have been filled in for you, but it may say something like Cambridge Semiconductor Evaluation Kit. So, it's going to look kind of dumb if that's what the user sees in Apple System Profiler when they buy your device. So, don't forget to go in here and change it to something sensible that identifies your device.

Another area that you need to check on your device is the self-ID packet. All FireWire devices, not just mass storage, send a short packet when they're plugged in as the first step towards device discovery. A storage device generally is not prepared to manage the FireWire bus, and so should not accidentally claim that it wants to take control, because we're very trusting and we might let it. So use the FireStarter tool, also from the SDK, to check out the self-ID that your device sends.

FireStarter shows the bus topology at the very lowest level and decodes a number of the bits so that you can see what they mean. The three that are important here are the contender bit, which needs to be zero so that you don't accidentally end up in charge of the FireWire bus. The link bit needs to be one so that we know there is somebody home and we should try to talk to you. And the power class should be set, whether you're consuming power or providing power. consuming power, providing power, or not.

So, just run Firestarter, plug your device in. What's shown here is a two-node bus, let's zoom in on that. Node 1 is Firestarter itself, the Mac that it's running on. So by careful elimination, we can discover that your device is Node 0. So then you can see the link bit is properly set. It says LINK in all capital letters. The power class in this case says up to 10 watts.

But the contender bit isn't shown in this line because it's somewhat obscure. But you can deduce that by looking down at the bottom, where we have totals for all the devices on the bus. And on this two-node bus, there are zero nodes with their contender bit set. So you've obviously got it right. Yours must be zero. It's very easy.

Okay, these devices typically need firmware. If at all possible, you should use the Silicon Vendor's firmware, because this firmware is very difficult to debug buried deep inside the peripheral device. And it's easy to make mistakes in there that don't appear right away, they only come up under stress with multiple devices or so on, and it's really unpleasant to the user if they have to update the firmware in the device just to keep it working.

If you do need to differentiate there, if you're going to add some unique features, that's okay, but please test it thoroughly. Don't just plug it into Windows and it mounts on the desktop and say you're done. There's more to it than that. Ideally, do both. Use the vendor's firmware and test it thoroughly.

How does the software matching work? In the kernel, the IOFireWireSBP2 KEXT loads when we see that unit directory that I showed earlier. If you have an RBC device, like Kai mentioned, this is common in FireWire, that's reduced block commands for a simple storage device, then IO FireWire Serial Bus Protocol Transport KEXT loads and provides storage-level services, or at least the lowest part thereof.

This, if you need to subclass or do your own driver, this would be a good place to do it. You can either subclass for minor changes or, like Torrey described, while honoring the open source requirements, just make a complete copy of that driver and then customize it to your needs. If you do that, please make sure, like I mentioned this morning, match carefully against your device so that you don't mistakenly end up being the driver for every hard drive out there.

But all of these services are available in user space. There is the SCSI Task User Client for talking to SCSI architecture devices. There's also an SPP2 User Client if you need a little bit lower level access. So if your device is not something that can be booted from, like it's a high-end scanner, say, you can probably do this all in user space and it's a lot easier there.

Okay, here's some common hazards that you may run into with this kind of device. The first would be if your globally unique ID turns out to not actually be unique. If you've got an eval board from Cambridge Semiconductor, it may have ID 12345. That's fine. If you plug it in, it'll work. Until you plug in another one of those that's also 12345, now we can't tell them apart. So we're having no tolerance policy towards this.

That device is immediately blacklisted. Not only will we not talk to the second one, we will cut off communication with the first one because we just can't cope with two hard drives and we don't know which is which. It's dangerous. So your customer should never encounter this, but you might run into it during development. So it's a good reminder to make sure your GUID really is unique.

Something else that customers don't do, but testers do a lot, is to unplug a device and then plug it right back in. You're trying to test the robustness of your hot plug support, so you get pretty good at this, it starts going really fast. So here's what happens. You drag the hard drive to the trash, you unplug it, you plug it right back in, and nothing happens. Why is this? Well, the FireWire stack is designed to have some patience before it decides that something's been unplugged.

Maybe you bumped the power cable, maybe you plugged in a third device, and there's a temporary power shortage. So when your device disappears, we don't instantaneously tear down your stack and say you're out of there. We wait a few seconds to make sure it's really gone. Once you get good at this, you can plug it back in so fast that we think it was never away, and so your driver doesn't unload and reload, and so your icon doesn't reappear on the desktop. So if this happens to you during testing, just unplug, wait 10 seconds, use a stopwatch or a clock, because most people wait about two seconds otherwise, plug it back in, everything will be fine. Finally, sorry, two more things.

The FireWire 800 silicon that's available today can support a FireWire 400 port. A lot of our Mac products do this, we offer both, and we've seen it on hard drives a lot also. That's fine. Be sure to tell the silicon what you're doing. As seen in the picture here, there's a pin on the side of the PHY that says one of these ports is not like the others. Run it only at 400.

If you forget to set this, the PHY will talk 800 through that port, and it might work briefly if you have the right kind of cable, but it probably won't. And then the customer will think the device is unreliable. So just set the pin on the PHY, tell it the truth, everything will work fine.

Finally, in a bridge-based device, it may be common to run the FireWire silicon using power that comes in over FireWire. But if you have, say, a big 3.5-inch drive mechanism, that's going to need an AC adapter. So that drive might be off, even though the FireWire silicon is on.

Don't advertise that you are a hard drive in your configuration ROM if you don't actually have a working hard drive. Because the software will load, we'll try to talk to it, we'll get errors, the user will be confused, it's bad. So there's creative ways to cope with this, like not advertising a config ROM and so on, to prevent this kind of problem.

Okay, most of that advice applies to all the rest of the device categories too, so I won't repeat it. We'll just cover what's different. Camcorders, television set-top boxes, DVHS, anything with audio and video in it. Totally different driver stack. The standards for these: AVC General is the audio/video command set that comes from the 1394 Trade Association. And then the specific commands for the AVC Tape subunit come from the same place.

Additionally, these devices stream audio and video using a standard known as ISO 61883, also available on the web. When one of these devices is plugged in, a text called "IO FireWire AVC" matches the AVC unit directory found in the config ROM. And you can see it here in Firestarter. The config ROM is very brief. All it says is "I speak AVC." From that point on, the discovery uses AVC commands rather than any further config ROM mechanisms.

So the first thing IO FireWire AVC.keks does is it sends AVC subunit info commands to your device to find out what subunits it supports. For example, in this camcorder I plugged in, it has a tape recorder player subunit and it has a camera subunit. So if you look in IO reg using terminal, I've simplified it here, but you can see the two different subunits, type 4 and type 7.

For video-type devices, your best choice, if you can, is to use QuickTime. If you're writing an application or a service that's all about just bringing in video in real time, such as PhotoBooth or iChat, if you can use QuickTime, then you won't be tied to FireWire. You can use a USB camera, you can use the built-in iSight in your newer Mac, you can even use a PCI capture board. As long as it supports QuickTime, it'll work with your app. So, that's your best choice if you can do it.

On the other hand, if you're building a more integrated application, something that fiddles with the camera, you know, runs the tape around or does fancier things, you may want more direct control. In which case, your best choice, probably, is to start with our audio-video services framework sample code from the FireWire SDK. It has very thorough and complete services to discover this kind of device, control this kind of device, and establish streams to and from this kind of device for real-time video and audio streaming.

FireWire audio devices, like an audio breakout box or synthesizer or mixer board, are a little different from the audio/video devices we just discussed. They're based on the same AVC standard and the same 16.18.83 streaming. Additionally, though, it's recommended that you follow the BridgeCo standard for AVC connection management. This helps the Mac to be able to have certain expectations about how to discover the inputs and outputs on your device and how to sensibly connect them and present them to the user.

The discovery is all the same. We use AVC subunit info commands, except we expect to see Type 1 for audio or Type 12, C hex, for a music device. If so, we can support you with Apple FW Audio KEXT and hook you into Core Audio, so you get standard audio services.

If the standard services are inadequate, you can also talk to these devices from user space, or if necessary, you can do your own kernel driver. It is recommended that you support the Level 1 or the Level 2 connection management according to the BridgeCo specs, so that we'll have the most seamless support for your device.

Coming in Leopard is Apple FW Audio 2.0, with a number of significant improvements. The connection management APIs will be available in user space in order to help avoid having to go work in the kernel. The audio streaming engine has improvements in lower latency and lower CPU overhead, so there's more time available for you to do your thing.

Support for multiple streams simultaneous and multiple formats simultaneous has been substantially improved, so you can do richer kinds of things. If you have an MLan device or a MIDI device, we'll have better support for those. And finally, the extended stream format from the AVC Music subunit will be supported in the 2.0 Apple FW Audio.

Recently, there was a joint working group formed between the 1394 Trade Association and the Audio Engineering Society to tackle a whole realm of use cases for these pro audio devices. Not just a simple home studio application, but say professional studios, building infrastructure, PA, all kinds of larger systems integrated out of these devices. If you're making an innovative product in this area, I recommend you get involved with these groups so you can find out what they're doing or maybe even give them some direction.

There's another class of cameras out there that's sort of webcam-like: IIDC, the Industrial and Instrumentation Digital Camera. The standard for this comes straight from the 1394 Trade Association. Also, the Apple EyeSight is based on this standard, and we publish a tech note that talks about the additional unique things that were added to the EyeSight, like its audio capability.

This is a little different from the devices before it because when you plug it in, nothing loads. Drivers are opened when an application needs them, say if you run iChat or Photo Booth, at which time QuickTime iIDC digitizer loads and finds this camera and it becomes available in the video input menu. When that digitizer loads, it matches the unit directory in the config ROM for this device, so you have to properly fill that in to show that you speak this protocol.

Okay, slightly different category of devices. The Mac Pro and the Mac Book Pro have expansion slots where the customer can add extra interface cards. PCI Express comes from the PCI SIG, as shown there. If you're going to make a FireWire card, it should be OpenHCI, which is available on the web.

And the PHY silicon just comes from the basic 1394 standard, which comes from IEEE itself. This is very important. If you're going to build this kind of card, pick good quality silicon and grill your vendors carefully. We have specifically designed the stack to not support subclassing at this point.

FireWire is a multi-device bus. Cameras, hard drives, audio devices. It's really hard to work around silicon bugs in a way that satisfies all of those devices. It's much better for everyone to just pick silicon that works. And there's plenty of good silicon on the market. So you can't write your own driver here. You can't subclass ours. You've been warned.

Finally, for a FireWire hub, there's practically nothing to do. There's no firmware, there's no software. You should check out the self-ID to make sure it's not claiming that it wants to manage the bus, which it's going to do very badly. In addition to FireStarter, we have a tool in the SDK called FiTool, which can look inside the Fi over the FireWire cable and read out its internal control registers. FiTool also has a copy of the 1394 spec in it, so as you mouse over each bit in each register, it'll tell you what that bit is supposed to be doing.

Okay, finally, if none of that was suitable, if you're going to go innovate something completely different, that's great. Here are some things that are recently going on in the 1394 Trade Association. There's an active group defining the LinkFi interface for the 1600 and 3200 megabit versions of the standard.

There's a major effort going on to implement 1394 over the coaxial cable that's already used for residential cable TV distribution. And in fact, this week at the Cable Lab Summer Conference in Keystone, Colorado, two companies are demonstrating implementations of this already. One of them running at 200 megabits, and one of them running at 400 megabits. It's very impressive stuff.

The 1394 TA has a new standard called VersaFi, which I showed the Fi tool screenshot there on the previous slide, adds a few more registers into the Fi and ways of talking to them, so that you might be able to implement a simple device with no link at all. So it simplifies the implementation, it reduces cost, it could open up FireWire's advantages, like long distance and high speed, to a broader category of device.

I mentioned the Pro Audio Working Group already, a very heavy activity level there. And if you've got some new idea, the TA might be a great place to come work on it. There's 130 member companies all making FireWire devices of one kind or another. You can gain access to the people who wrote the standards. You can influence where the standards go. There's a lot of opportunity there. So there's their website at that URL.

Okay, that's it. If you need more information on any of the five topics that we discussed today, you can contact Craig Keithley, or you can nab him. He's sitting in the front row here when we're done. He is the evangelist for just I.O. technology in general on the Mac. Plus, all of the sample code and other resources that we've discussed today are available in the WWDC 2006 section on Apple's developer webpage.

A couple of events coming up. There is a Plugfest tonight at Apple in the piano bar. We will have FireWire, USB, and Bonjour all together. Bring your device, or just come and we'll show you the tools and techniques that we've demonstrated here. And tomorrow morning, from 9 to 11, I think on the other side of this wall, there is a Kernel Lab where we will have our engineers present and you can come learn more, try hands-on developing or subclassing a KEXT on Mac OS X.