« | Home | »

LAMEncoder, Spawn of FaceSpan!

FaceSpan 5 is under development. That means it isn’t finished. But it also means that to some degree — indeed, to a rather impressive degree — it is finished. It isn’t all there, but there is certainly something there. And that something is remarkably viable. To illustrate this, I took advantage of FaceSpan 5 to do the very thing FaceSpan 5 is intended to do — to write a complete, useful, “shippable” application. In fact, I’ve actually “shipped” this application, which is called LAMEncoder, and you can download it (here) and try it out.

The very fact that I was able to do this should serve as an indication of just how rich and how powerful FaceSpan 5 is already, even in its current state.

Glass half empty, glass half full

There are actually two main areas in which FaceSpan 5 isn’t finished yet:

  • The IDE. By this I mean the environment in which you work as you develop your application. For example, you can drag a button into a window to tell FaceSpan that there should be a button at this location in this window. But, so far in FaceSpan’s growth, no guidelines appear to show you when the button is at the correct position (a certain number of pixels from the edge of the window, or aligned with other widgets in the window), and you can’t yet double-click on the button to change its title (you have to work in FaceSpan’s “inspector” palettes). Also, when you’re debugging, certain powerful Script Debugger features, such as breakpoints, aren’t yet implemented in FaceSpan.

  • The “widget” repertoire. Certain standard interface elements that lots of people would like to use just aren’t there yet, or are present only in rudimentary form.

Despite these current limitations, the actual process of developing LAMEncoder was wonderfully fast and easy. In fact, I’d have to say (not without a certain amount of prejudice, to be sure) that FaceSpan 5 is already shaping up to be the best application development environment I’ve ever used. The IDE has enough functionality, and we have enough interface widgets in place, that we’ve passed a certain tipping point of usability and usefulness.

Indeed, I can specify for you quite precisely what tipping point it is. Very early on, when FaceSpan 5 was just a gleam in Mark’s eye, he posed me a challenge: At some point, he hoped, there would come a day when I would tell him that I’d rather develop using FaceSpan than any other development environment. That day is here. Not since HyperCard has an IDE felt so satisfying and easy to me. In a future article, I’d like to write more about that, using the organization and development of the LAMEncoder code to illustrate.

In this article, though, I’ll just describe the finished product, LAMEncoder itself, particularly with regard to its interface. This (and using LAMEncoder itself, of course) should give you an idea of just how powerful FaceSpan is, even now.

The LAME game

So. What does LAMEncoder do? It encodes WAV and AIFF files to MP3 using the freeware LAME encoding engine. I prefer LAME to iTunes’ MP3 encoding engine. But LAME is a command-line tool, and I can never remember the commands. LAMEncoder’s purpose is to remember and construct those commands for you. You hand it some WAV or AIFF files, and set the parameters the way you want them. Then you press the Convert button, and LAMEncoder uses the LAME engine to encode the files to MP3.

If this sounds familiar, it should. The idea comes straight from the LAME Encode Automator action developed starting on p. 452 of my AppleScript book. That Automator action wraps an AppleScript script in “just enough interface” to make it convenient and powerful. LAMEncoder wraps the same functionality in even more interface — enough interface to constitute a full-fledged, stand-alone application.

Here’s the main window:


In the screen shot above, notice the tooltip. All the interface widgets have tooltips, and, like this one, many of them are dynamic – they change depending on the situation. Here, the tooltip is explaining why the file list area is blank. Once we hand LAMEncoder some files to convert, the tooltip will automatically read differently (as we shall see later).

There are three ways to hand LAMEncoder some files to convert. One way is to press the Add File button in the toolbar at the top of the window. When you do, a standard Open File dialog appears:


In the above screen shot, I’ve selected an AIFF file. Now I’ll press Add. The Open File dialog closes and the selected file appears in the list:


Notice that the Clear and Convert buttons have become enabled as well. They were disabled before, because, with nothing in the file list, there was nothing useful they could do.

Another way to add files to the list is to press the Add Folder button in the toolbar. When you do this, a standard Choose Folder dialog appears:


When I choose the “wavs” folder and click Add, any AIFF or WAV files in that folder are added to the list:


Naturally, the toolbar isn’t the only place to access the Add File and Add Folder functionality; after all, the user could hide the toolbar, or even customize it to remove those buttons. So the same functionality is also present in the menu, complete with keyboard shortcuts:


The third way of adding files, not illustrated here, is to drag them from the Finder into the list.

HTML View benefits

At this point we should pause to answer a burning question that I’m sure you’re racking your brains over right now: what the heck is this interface widget in which the file list appears? It clearly is not a standard Table View. And that makes sense, because the Table View is one of the important interface widgets that hasn’t been written into FaceSpan 5 yet.

This was probably the biggest limitation of the FaceSpan 5’s current state that I faced when writing LAMEncoder. It meant that I had to find a workaround means of displaying a scrolling list of the files the user wanted to encode. The workaround was to use FaceSpan’s HTML View widget. Yes, that area in the middle of the window is actually a Web browser! LAMEncoder structures the list of files as HTML and hands that HTML to the HTML View widget.

An HTML View widget is a powerful animal in FaceSpan. To see how powerful, take a look at this next screen shot:


The above screen shot displays the tooltip for the HTML View when the list actually contains some files. Notice that it has changed from the tooltip we saw earlier. Notice also that it claims we can click on a file name to play that file. Let’s try it! We click on the last file in the list, and a dialog appears:


You can’t hear it, of course, but in that screen shot the dialog really is playing the WAV file. That part is easy, because FaceSpan has a Movie View widget; the dialog’s interface is nothing but a movie controller, and QuickTime knows how to play AIFF and WAV files. But how is it possible that you can click in the list of files in order to play a file? Well, as I said, an HTML View widget is a powerful thing in FaceSpan. One of the powerful things it can do is intercept the user’s request to navigate to a link. The names of the files are links. So when the user clicks on the name of a file, that’s a link navigation request; the HTML View hears about this, and instead of actually navigating to anything, it hands the information about the link over to the file-playing dialog, which opens and plays the file.

Incidentally, the power of an HTML View is also why we can drag and drop a file from the Finder in order to add it to the list. This is quite remarkable, because in general, drag-and-drop is one of the things that isn’t implemented yet in FaceSpan! But an HTML View is its own little world, and it already knows how to respond to drag-and-drop. When it does, this counts as navigation (basically, it counts as an attempt to open a file). In LAMEncoder, the HTML View intercepts this attempt, and instead of navigating anywhere, it effectively hands the file over to the Add File button.

Encoding in action

So now that we’ve created a list of files to convert, let’s actually convert the files in the list. First, we use the “Conversion parameters” area of the window to set up how the conversion will be performed. In this next screen shot, I’ve decided to use CBR (constant bitrate) encoding, and I’ve entered a bitrate value of 320 for very high quality:


Notice that the text above the popup menu has changed from lame --preset standard to lame --preset cbr 320. That text represents the command-line parameters that will actually be sent to LAME to perform the encoding. The change in the text happens automatically as you play with the “Conversion parameters” interface.

Furthermore, however you set the “Conversion parameters” interface is automatically remembered by LAMEncoder when you quit, by being written into the application’s user defaults (its Preferences .plist file); when you start up LAMEncoder again, that information is fetched from the user defaults and the “Conversion parameters” interface appears just the way you left it when you quit. That sort of thing, which adds a nice professional touch to our application, is extremely easy in FaceSpan.

Anyway, now we press the Convert button. The Terminal opens and LAME is started, with the files and conversion parameters that we specified in LAMEncoder’s window:


That may seem a little nerdy, but for that very reason I like it. LAME provides nice progress feedback as it runs in the Terminal, so it makes sense to me to hand over the actual conversion process to the Terminal and let LAME do its thing. Meanwhile, LAMEncoder itself is free for further use; having handed off the correct command to the Terminal, it returns instantly and sits idle. The user can even quit LAMEncoder at this point, while the Terminal chugs merrily along, encoding the files.

Finishing touches

Now I’d like to point out a few of the finishing touches in the LAMEncoder interface that give it a full-fledged, “professional” application quality. First, there’s a standard About dialog:


All the underlined blue terms are links that the user can click to go to the relevant Web pages.

LAMEncoder also has a second About dialog, which properly attributes the LAME engine and provides the text of the LGPL agreement under which it can be used in an application. That’s required, because LAMEncoder actually includes a copy of the LAME engine inside itself:


(Incidentally, the above window is the only part of LAMEncoder containing an interface widget that isn’t really built into FaceSpan. The scrolling Text View containing the text of the LGPL is implemented through a “plug-in”, which is essentially a bundle of Objective-C code. Eventually, the Text View will be a native FaceSpan widget.)

Next, LAMEncoder has some preferences that the user can set. When you choose Preferences from the LAMEncoder menu, the preferences dialog appears:


As you can see, we have two preferences here.

  • First, using radio buttons, the user can decide whether to use the LAME engine built into LAMEncoder, or to use a copy of the LAME engine that may already be installed on the user’s computer. This is because it’s possible to compile LAME yourself, possibly using settings optimized for your processor, and we wouldn’t want to prevent a user who has done so from using that specially compiled LAME.

  • Second, having chosen the second radio button, it is also necessary to press the Set button and tell LAMEncoder where that on-disk copy of the LAME engine is. In this case, I’ve specified a bogus location; there is no copy of LAME on my desktop. If I press the second radio button and try to dismiss the preferences dialog, I’ll get an error alert:


    The preferences dialog then opens again, forcing me either to use LAMEncoder’s internally provided LAME engine or to specify a location where there really is a copy of the LAME engine on my hard disk.

Finally, like any good application, LAMEncoder provides online help:


The user chooses from the Help menu, and the online help appears (in this case, it’s a page of HTML, and opens in the user’s default browser).

Future directions

So much for LAMEncoder itself. There are two kinds of future directions I’d like you to be thinking about.

First, there are future directions for LAMEncoder. Now that this version of LAMEncoder is finished, it’s easy to add further features. For example, right now LAMEncoder implements only the --preset subset of LAME commands (because those are the only ones I really use). It would be easy to add even more LAME commands, making LAMEncoder an even more powerful, complete front-end interface to LAME.

Second, there are future directions for FaceSpan 5 — and for you. If LAMEncoder is the kind of application FaceSpan 5 can create right now, think what kinds of application it will be able to generate in the future. Clearly, this is an application development tool worth watching. Stay tuned!

About this entry