Issue 4-49, December 8, 1999

Be Engineering Insights: Do You Have 24 Ears?

By Jon Watte

I don't, but I have at least 11 friends who can play instruments and sing. With the coming of Maui, we can all jam together and record the results using BeOS and an appropriate third-party software package. That's because we've introduced support for multichannel audio devices and file formats out-of-the-box. This means some additions to the Media Kit API that I'll go over in this article.

First out, the media_raw_audio_format struct needed to be enhanced to convey information about things like how many bits of an int32 sample are actually valid data, and which channels are assigned to which logical speaker positions or matrix channels. Unfortunately, media_raw_audio_format had no padding to take, so we invented media_multi_audio_format which is the same thing, plus the extra fields, plus padding. media_format.u.raw_audio is now a media_multi_audio_format, as is media_raw_audio_format::wildcard. Because of the wonders of C++ inheritance, most of your code will compile unchanged, but you'd do well to string-replace all occurrences of "media_raw_audio_format" with "media_multi_audio_format".

The new fields in media_multi_audio_format are:

channel_mask

Contains a bit mask of the logical channel assignments present in the format. If there are more channels in the format than bits in this bit mask, the rest of the channels are undefined. Channel assignments include B_CHANNEL_LEFT, B_CHANNEL_RIGHT, B_CHANNEL_CENTER, B_CHANNEL_SUB, B_CHANNEL_REARLEFT, B_CHANNEL_REARRIGHT, and about 10 more that you can find in MediaDefs.h or the next version of the BeBook.

valid_bits

Contains a count of how many bits of an int32 sample actually contain valid data. The rest of the bits may contain out-of-band data, zeros, or noise. If this value is 0, assume the entire value is valid.

matrix_mask

Contains a bit mask for which matrix encoding format was used, if any, for the data. These include B_MATRIX_PROLOGIC_LR and B_MATRIX_AMBISONIC_WXYZ. Currently, the Be System Mixer does nothing with this information, but I think an Ambisonic "renderer" Node would be an excellent and fun application using the Be Media Kit.

Unfortunately, struct media_encoded_audio_format contained a media_raw_audio_format with no extra padding, so the extra fields have been split out into a multi_info field of type media_multi_audio_info. media_multi_audio_format actually multiplies inherits from media_raw_audio_format and media_multi_audio_info for this reason. Something to be aware of when you're coding away.

There were some other places in the Media Kit which used a naked media_raw_audio_format without padding; most notably the constructor for BSoundPlayer. BSoundPlayer has thus gotten a new constructor which takes not only a media_multi_audio_format argument, but also a media_node and media_input, so that you can point it at the Node/input of your choice. This is a good way to send data directly at one of what may be many installed sound devices, without involving the Be System Mixer (which does stereo-only output in Maui).

Judging from questions I've received, I feel it is worth reiterating: BSoundPlayer is NOT being retired, but the helper class BSound IS being retired. Any bugs filed against BSound will go unfixed. The header may disappear at any moment. There may be secret code in the media server that deletes the header file Sound.h from your hard disk at some random date in the future. If you can't just use a BSoundPlayer directly (either by overriding PlayBuffer() or by using the hooks) then I suggest you look into BGameSound and its most-derived classes BSimpleGameSound, BFileGameSound and BPushGameSound. Indeed, while most of the high-end Media Kit is gone in our separate "Stinger" product for Internet appliances, BSoundPlayer and BGameSound are still part of that product. BSound is not.

As far as file formats go, we've added support for the new WAV_FORMAT_EXTENSIBLE flavor of WAV files that was recently defined. Our WAV file writer and extractor will transparently read/write this flavor when dealing with formats that are not unambiguously describable using the old style of WAV header. Thus, if you use our WAV writer to write a 16-bit stereo file, that file will play fine on a friend's system running some other operating system product, whereas a 4-channel or 24-bit file may not, as his OS may not yet be prepared to deal with those files.

What about recording? This article comes with sample code for two utilities, one that plays a sound file back at the named sound device of your choice (from the command line) and one which records a multichannel file from the device of your choice. I've tried these with the Layla from Echo, a 10-in 12-out 20-bit device, and it works there; your system may vary. Feel free to snarf the parts of the sample code that you need into your own application, as long as you don't use that code for a non-BeOS product.

Sample Code: <ftp://ftp.be.com/pub/samples/media_kit/multiaudio.zip>

While debugging the new format negotiation in BSoundPlayer, we found some more ill-behaved applications which pass bad format descriptions to the BSoundPlayer constructor, and/or don't actually check which format is being used but assume some format which happened to be chosen on their system when they wrote the program. We've inserted code to stay compatible with these programs, but I suggest that you make sure to look at the format used by a BSoundPlayer and conform to that; don't just blithely assume some specific format, even if that's what you ask of it or what it has used in the past.

One humorous e-mail exchange started with, "I'm fixing bugs in app-name-deleted and it can't play audio anymore; it comes out as noise." It seems the developer had assumed floating-point samples, but changed the code to actually check and use whatever the BSoundPlayer wanted (in this case, int16). Our workaround for the old version of the program assumed he was still giving us floats, and thus noise came out. The solution for him was to change his application's MIME signature, which is the information we use in BSoundPlayer to activate possible application bug workarounds.

That said, you cannot assume that we'll cushion bugs in your code as we update the system. Some bugs are deemed too hard to work around or too egregious in nature to support, and a user upgrading the OS will see those applications stop working. Sometimes, we don't even have a copy of the application to test with, so we can't find the bug in the first place. Writing code that follows the rules is always your best defense. Check error codes, check modified non-const arguments, and don't assume any parameters (buffer size, sample format, etc.) will stay fixed just because they're on your machine.

One simple test is to run your program with "Real-Time Audio" enabled and disabled (restart media services in between) as enabling this option will make audio buffers smaller (how much depends on your sound card and CPU) and disabling it will make them bigger.

Are you one of the developers who reported sound glitch bugs with the MediaPlayer application? You're not alone. It turns out that the MediaPlayer was violating the "one clock" rule, and dropping/doubling buffers of audio when the audio stream played at a slightly different speed than system_time(). B_DONT_DO_THAT. It also had a knack for tickling a bug in the mixer which resulted in faint "sparkles" in the sound. Both problems have been fixed as I write this article.


Developers' Workshop: Tonight on BBC2: How to Make Documentation Bookmarks

By Doug Fulton

Along with personal jetpacks and submarine cars, documentation at your fingertips is one of those cold war promises that we've been looking forward to kicking and screaming. It's not enough to fish around for hard copy tucked open and face down under a pile of unprotected hard drives that we think we're going to get around to looking at again someday when, actually, they've long since been permanently de-gaussed by the janitor that doesn't work here anymore. All that amusing e-mail, gone. Expectations have been raised to such an upper shelf that we no longer tolerate the 10 mile snow trudge to explicitly open the on-line documentation and perform a search in the manner of the ancients. We want our tools to work for us. We want compilers that can correct the typos that our autocompleters create. We want servers that autodetect our network cards and software that deletes the spam that arrives therethrough. And we want to point to a function and say "Tell me about it."

As we all should know by now, the BeIDE responds to this request, and has since about the winter of 19-aught-98. Alt double-click a symbol defined by Be in the BeIDE editor, and the documentation for the symbol pops open in a browser window (more or less).

But let's say you have your own library with HTML documentation. How can you play in this game?

Simple. So simple that I'm going to have to pile a few more pointless but oh-so-sassy and probably grammatically correct nonsequiturs onto just about every sentence in order to plump this article up to a size that won't get lost somewhere between the legitimate technical discussion above and the agitprop that follows. I could bang my head on the keyboard, for all this paragraph is going to tell you. 567rytuifghvbn 567tyuighjvbnm 4675tyuighjkvnbm.

When the BeIDE goes looking for a symbol, it creates a query that looks for files of type "application/x-vnd.Be-doc bookmark". Each such file represents a single symbol definition (function, class, constant, etc) in the Be Book. The file's name is the symbol itself; functions retain their parentheses, but without arguments (e.g. MessageReceived()). The file type is associated with four special attributes:

The BeIDE lookup logic doesn't depend on the be:class_name, be:kit_name, or be:short_description attributes—all it cares about is finding a symbol (i.e. a filename) that matches (or contains) the current selection. The attributes are used, however, to differentiate multiple hits.

If you want the BeIDE to find your documentation, all you have to do is create a "application/x-vnd.Be-doc bookmark" file for each of your symbols, fill out the attributes, and put the files anywhere you want (except the Trash). The BeIDE query isn't restricted to the Be Book bookmark directory, which is somewhere inside the don't-look-here-oh-okay-go-ahead-and-look /boot/beos phone closet.


Opera on BeOS

By Jean-Louis Gassée

As most BeOS followers have known for a while, the BeOS version of Opera has been making steady progress. I've used successive betas over the past three months and have been happy with the experience. Opera is a Norwegian company located in Oslo. Founded in 1995 by Jon Stephenson von Tetzchner and Geir Ivarsøy, it acquired a very good reputation for the quality of its independently developed browser. Opera 3.6 is now commercially available on Windows, with versions planned for Unix variants, MacOS, Epoc (the system inside the Psion organizers now spreading to other devices) and OS/2. More details are available at www.opera.com.

When you read Opera's home page, you can't miss their references to bloatware (their word, not mine). In fact, the commercial Windows version download needs 1.29 Mbytes and the application, once it's installed, requires 2.68 Mbytes. That's just a little more than Neoplanet itself, merely a "skin" for Explorer. Today, you can try Opera on Windows for 30 days and see how well it compares with the integrated offering from Microsoft. For BeOS, there's the beta release already mentioned.

If you try it, I'm confident that you'll see why the technology and product philosophy are attractive to us, and why we've entered into a joint development and licence agreement with Opera for their browser. The legal agreement is a little more wordy than this last sentence, but the idea is to give us the opportunity to produce a nice BeOS version of their market-tested browser. More details are available in the press release and related material available at <http://www.be.com/press/pressreleases/99-12-08_opera.html>

Now, you might ask, why did we pick Opera over NetPositive? We looked at the two products and saw Opera as a clearly more evolved, functionally richer product. We've known the small group of people who produce it for awhile and respect their work. In licensing browser technology, we follow the example of our worthy elders: Explorer is built on a Spyglass license, and Navigator on code licensed from the NCSA at the University of Illinois.

A better browser, "integrated" or not, makes BeOS a better platform for desktop and appliance applications. And that's what the Be community -- developers, users, and business partners—get as a result of this agreement. Looking back, we see this Opera agreement as being in line with recent technology and business agreements, such as Java and Real Networks. We're delighted with this opportunity to work with a fine group of people and to make our product more competitive.

Creative Commons License
Legal Notice
This work is licensed under a Creative Commons Attribution-Non commercial-No Derivative Works 3.0 License.