^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
BE ENGINEERING INSIGHTS:
Multiaudio API
By Steven Olson -- <solson@be.com>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I'm in the family bunker deep in an Idaho hillside. Y2K is
officially over but I'm still not sure if it's safe to come
out yet. The only communication line I have is a fiber optic
link to Be's world headquarters in Menlo Park. Because of
some poor planning on my part, though, there's no gas for
the electric generator. Instead, I have to use a candle
(signal) and deck of playing cards (modulator) to send this
article. Fiber optic cable was the right choice for the
bunker because of its high speed and bandwidth capabilities.
Coincidentally, BeOS is also known for high speed and
bandwith capabilities. In particular, the new multiaudio
driver API takes full advantage of BeOS's superior speed and
bandwidth.


Multi

Not all of you may be familiar with the multiaudio API, as
it's intended only for driver writers. User level add-ons
and applications will talk to the multiaudio node, or
"multinode" as it's called. The advantage of the multiaudio
API over other APIs (such as legacy and game) is that it's
ideally suited for professional and semiprofessional audio
cards. These cards generally have more inputs and outputs,
higher sampling rates (typically 48Khz or 96Khz), and
greater bit depths (up to 32 bits per sample) than typical
game sound cards. They may also have support for other audio
formats such as S/PDIF and ADAT. The "complete"
documentation for the driver API is included in three files:
multi_audio.h, multi_audio.gb, and multi_audio.txt. To get
these files, write to trinity@be.com. Without rehashing all
the information in the files, I'd like to hit the highlights
of the new API.


Highlights

The API is different from the other audio APIs in that
read/write calls are combined into a single ioctl,
B_MULTI_BUFFER_EXCHANGE. This call is synchronous -- it
returns after playback data has been transferred (or queued)
and capture data (if any) is present in the capture buffer.
A ping-pong type of buffer management normally used -- one
buffer is being played (or filled with capture data) while a
second buffer is being prepared. In some cases, a ring
buffer may be required.

Another area of interest is the mixer ioctls. Extensible
mixer implementation is tricky, and this API is no
exception. However, the burden is now off the driver writer
and on the node and add-on writers instead. That's good news
for us driver writers. (There should be example code in the
future to make nodes and add-ons easier too.) The ioctls
B_MULTI_LIST_MIX_CHANNELS, B_MULTI_LIST_MIX_CONTROLS, and
B_MULTI_LIST_MIX_CONNECTIONS return mixer components
associated with the device. This allows the mixer GUI and
implementation to be handled by the user mode components.


Masters

One item that's slightly different from the documentation is
the ganging together of controls. The multi_mix_control
structure has a member named "master." It is intended that
this value be 0 if the control is not slaved. If it is
ganged, then the ID of the master control goes here. In
order to facilitate the implementation of parameter webs, I
suggest that the master control use its own control ID here
and not 0. This reduces to using 0 if the control is not
ganged or slaved, and the master control ID if it is. The
documentation will be updated to reflect these changes.


Complications

Some things are tricky. For example, say your card supports
a 32Khz sampling rate, but only if you're sample-locked to
an incoming 32Khz S/PDIF signal. You should report the
actual sample rate (32 Khz) when requested
(MULTI_GET_GLOBAL_FORMAT) but don't show 32 Khz in the
MULTI_GET_DESCRIPTION ioctl. This will prevent users from
manually trying to set the rate to 32 Khz.


Confusion

Some people have reported confusion over the terms "bus" and
"channel" as used in the multiaudio API. Busses are the
connectors to the world outside the computer, while channels
carry audio data inside the computer. Busses may be digital
(e.g., ADAT) or analog. Channels are what's "processed" by
the computer. In a typical capture scenario, an analog
signal is converted to digital PCM data by an ADC. The
digital PCM data is associated with the input channel, while
the analog signal is part of the input bus.


Latency

The purpose of the multiaudio API is create an environment
in which high-performance audio cards can excel. So the
question "How fast is it?" invariably arises. The answer is
"It depends." How fast is your CPU? How fast is your hard
disk? How fast is your memory bus? Do you want multitrack
hard disk recording or are you more interested in "real
time" (<10 ms) effects processing? In audio, the primary
concern is latency. How long does it take to get an analog
signal into the computer, process it, and then send it back
out? What if you also wish to write processed data to disk?
There are many items which contribute to the latency of the
entire system, including the OS, the API, A/D D/A converter
latency, buffer size, etc... (If the OS is not designed
properly, you may be able to get two channels of audio in
and out fairly quickly, but you may not be able to access
the disk simultaneously.) So how fast is the new API? The
only way to know is to test your machine and card.


Test

Everyone has a preferred method for testing audio latency
and I'm no exception. I recommend the following: input a
sine wave from a signal generator to the sound card, run a
loopback program that doesn't bypass the converters, then
measure the phase difference with an oscilloscope. Make sure
that the period of the input signal is greater than the
buffer playback time. A very simple loopback program is
available at
<ftp://ftp.be.com/pub/samples/drivers/multiaudio_test.zip>

This program does not currently use the multinode but
instead talks directly to the driver. Consequently, it
should give driver writers a basic understanding of how the
new driver API is used and the extremely low latencies that
are possible with a good sound card and the new multiaudio
API.
