old-www/LDP/LG/issue70/tranter.html

402 lines
16 KiB
HTML

<!--startcut ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>CSL, The Common Sound Layer LG #70</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->
<CENTER>
<A HREF="http://www.linuxgazette.com/">
<IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.png"
WIDTH="600" HEIGHT="124" border="0"></A>
<BR>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="spiel.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue70/tranter.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="williams.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
<P>
</CENTER>
<!--endcut ============================================================-->
<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>
<P> <HR> <P>
<!--===================================================================-->
<center>
<H1><font color="maroon">CSL, The Common Sound Layer</font></H1>
<H4>By <a href="mailto:tranter@pobox.com">Jeff Tranter</a></H4>
</center>
<P> <HR> <P>
<!-- END header -->
<H2>The Problem</H2>
Imagine you're writing a cool new game for Linux, and like any modern
game, it has to support sound. There are a number of sound toolkits
out there, but if you're like many game programmers, you just talk
directly to the audio device, <TT>/dev/dsp</TT>, which gives you
maximum flexibility and performance.
<P>
Your game is looking good, so you pass a copy to a friend to try out.
Strangely, the sound doesn't work. It turns out your friend runs the
GNOME desktop, and under GNOME the sound device is taken over by the
<TT>esd</TT> sound server. GNOME applications are supposed to talk to
<TT>esd</TT>, not directly to the sound device. So you go back, learn
the <TT>esd</TT> API, and add an option to your program to work with
<TT>esd</TT>.
<P>
You now pass the game over to a second friend to test, and again sound
doesn't work for her. She likes to run the KDE desktop, and under KDE
the sound device is managed by the <TT>artsd</TT> sound server. So you
spend a couple more evenings learning the <TT>artsd</TT> sound API and
adding support to your game so it can work with KDE too.
<P>
A third friend has heard about this great game and wants to try it
too. He is running Solaris on a Sun workstation, but that's okay, he
can just recompile the code for his architecture. Unfortunately sound
does not work properly, because the Solaris sound device and APIs are
not the same as on Linux. You could work on adding support for Solaris
too (if you had access to a Solaris machine), but what about the
friend who runs AIX, and the one who uses the Network Audio Server
(NAS), and the one who uses the ALSA kernel drivers? Just providing
basic support for sound is getting to be a lot of work. It's too bad
you can't just write the program once and have it work on all
platforms.
<P>
Enter CSL, the Common Sound Layer.
<H2>What is CSL?</H2>
CSL is intended to solve just this problem. CSL is the Common Sound
Layer, a C-based API for sound programming. CSL is intended to address
the problem of providing sound support in applications independently
of the underlying sound drivers. It also hopes to become the common
library for sound support under the KDE and GNOME projects.
<P>
It currently works on Linux systems using the OSS sound drivers and
the aRts sound library (which runs on both KDE and GNOME desktop
environments). Applications that use CSL have no further dependencies
on any libraries or other components.
<P>
CSL was designed to provide similar performance to platform-specific
code, with support for latency management and full duplex. This makes
it particularly suitable for real-time type applications such as
games.
<P>
CSL is somewhat unique in that, despite all the talk of "desktop wars"
between KDE and GNOME, it is being co-operatively developed by Stefan
Westerfeld, a KDE developer, and Tim Janik, a GNOME developer.
<H2>Features</H2>
CSL is currently available as preview version 0.1.2 which includes:
<UL>
<LI> a C API for digital audio playback and recording
<LI> back ends for the Linux kernel OSS sound drivers and for aRts on KDE and GNOME
<LI> network transparency and authentication when used with aRts
<LI> support for multi-threaded programs
<LI> API documentation generated using <A HREF="http://www.doxygen.org">Doxygen</A>
<LI> a HOWTO/FAQ document
<LI> several utility and example programs
</UL>
<P>
CSL has some limitations, mostly by design: it is a C API only, so
don't expect an object-oriented interface. It is a low-level API for
digital audio only (no MIDI, no mixer, no codecs for complex formats
like MP3). If you want features like 3D sound, you should look at
something like <A HREF="http://www.openal.com">OpenAL</A>.
<P>
Currently, it supports only the OSS sound drivers or the aRts
sound server. (aRts ships with KDE, and there is a GNOME version. Many
multimedia applications like xmms and the RealVideo player will work
under aRts as well).
<P>
While CSL is not finished yet, the API is quite stable and most of the
functionality is there.
<H2>Obtaining and Installing CSL</H2>
In order to use CSL, you need a Linux system with working sound drivers
(either OSS or something compatible with it like OSS/4Front or ALSA
with OSS emulation). If you want aRts support, you need aRts version
0.5.4 or later, which is included in KDE 2.2, or a standalone version
can be obtained from <A
HREF="http://www.arts-project.org">http://www.arts-project.org</A>. If
you are running GNOME, there is a special version of aRts for GNOME
available there are well. Other than that, you only need the usual
development tools like <TT>gcc</TT>, <TT>gld</TT>, and the GNU auto
tools.
<P>
CSL is currently only provided in source format. You need to download
the tar archive from <A
HREF="http://www.arts-project.org/download/csl-0.1.2.tar.gz">http://www.arts-project.org/download/csl-0.1.2.tar.gz</A>
(there may be a newer version available by the time you read this).
<P>
Building and installing CSL follows the usual GNU build procedure,
documented in the file <TT>INSTALL</TT>. Briefly, you need to run the
commands:
<PRE>
%./configure
% make
% make install
</PRE>
<P>
The last must be done as user root.
To test CSL, you can run two of the included utility programs.
The <TT>testsine</TT> program generates raw samples for a 440 Hertz
sine wave and <TT>cslcat</TT> accepts raw sound sample from standard
input and sends them to the audio output device. Piping them together
like this
<PRE>
% tests/testsine | csl/cslcat
</PRE>
<P>
should produce one second of a 440 Hertz sine wave tone (the above
command assumes you are in the main CSL source directory).
<P>
If you have any raw sound files, you can try playing one with the
<TT>cslcat</TT> utility, for example:
<PRE>
% cslcat -r 44100 -w 8 -c 1 /usr/lib/games/koules/start.raw
</PRE>
<P>
You can also try the programs in the <TT>examples</TT> directory.
<H2>An Example</H2>
I'll go through a short but complete example program that uses CSL.
This is based on the program <TT>cslpcm1.c</TT> that is included in
the CSL release (I've removed comments and error checking code here
for brevity). There are additional examples included with CSL that
illustrate more of the API functions. A text version of the program is
available <A HREF="misc/tranter/cslexample.c.txt">here</A>.
<P>
<PRE>
1 #include &lt;unistd.h&gt;
2 #include &lt;stdio.h&gt;
3 #include &lt;fcntl.h&gt;
4 #include &lt;csl/csl.h&gt;
5
6 int main (int argc, char **argv)
7 {
8 const int size = 1024;
9 CslDriver *driver;
10 CslPcmStream *stream;
11 CslOptions options;
12 short buffer[size];
13 int i, j, fd;
14
15 options.n_channels = 2;
16 options.rate = 44100;
17 options.pcm_format = CSL_PCM_FORMAT_S16_LE;
18 csl_driver_init (NULL, &amp;driver);
19 csl_pcm_open_output (driver, "cslpcm1", options.rate, options.n_channels, options.pcm_format, &amp;stream);
20 fd = open("/dev/urandom", O_RDONLY);
21 for (i = 0; i &lt; 500; i++)
22 {
23 read(fd, buffer, size);
24 for (j = 0; j &lt; size; j++)
25 buffer[j] = CLAMP(buffer[j], -4000, 4000);
26 csl_pcm_write (stream, size, buffer);
27 }
28 csl_pcm_close (stream);
29 csl_driver_shutdown (driver);
30 return 0;
31 }
</PRE>
<P>
In line 4 we include <TT>&lt;csl/csl.h&gt;</TT>, the header file that
defines all of the CSL API functions.
<P>
In lines 9-11 we declare variables to hold some of the important CSL
data types. A <TT>CslDriver</TT> is a handle associated with a
particular backend driver. A <TT>CslPcmStream</TT> is a PCM audio
stream, associated with a <TT>CSLDriver</TT>, opened for either input
or output, and with specific sampling parameters. It is used much like
a file descriptor. The type <TT>CslOptions</TT> stores options for a
<TT>CslPcmStream</TT>. For convenience, CSL can parse standard command line
options for sampling parameters and put them in a <TT>CslOptions</TT> variable.
<P>
Lines 15-17 set the PCM options: number of channels, sampling rate,
and data format. In this case two channels (stereo), at a 44100 sample
per second rate, using 16-bit signed little-endian samples.
<P>
Line 18 obtains a handle to a <TT>CslDriver</TT>. We could have
specified the backend to use (e.g. "oss" or "arts") but the special
value of NULL instructs CSL to select a driver automatically. You can
also ask CSL to return a list of available drivers.
<P>
In line 19, using the driver handle, we pass the sampling options and
receive a handle to the <TT>CslPcmStream</TT>, in this case an output
stream for sound playback. If we wanted to perform sound recording we
would have opened an input stream.
<P>
In line 20 of the example we open the Linux random device. We are going to use it
to obtain random numbers which we will send to the sound device.
<P>
Lines 22-27 form a loop in which we read data from
<TT>/dev/urandom</TT> into a buffer and then write the data to the PCM
stream using <TT>csl_pcm_write</TT>. Because the data is random, it
can contain large sample values which may be quite loud. We use the
convenience macro <TT>CLAMP</TT> provided by CSL to constrain the
value within a smaller range (recall that here we are working with
16-bit signed values). The result of writing the random data to the
sound device should be a hissing sound from the speaker. This white
noise of no particular frequency confirms that the random number
generator device is indeed a good source of random data.
<P>
In lines 28-29, after looping 500 times (which corresponds to about 3
seconds), we clean up by closing the stream and shutting down the
driver.
<P>
By studying this and the other examples, and looking at the HTML API
documentation, you should quickly get a feel for how to use the library.
<H2>Porting Applications to CSL</H2>
It is relatively straightforward to port applications that use the OSS
sound drivers to CSL. You will then have an application that will work
nicely under systems running aRts, and still work with the kernel
sound drivers. As an example, I ported a sound application I had
written (<TT>wave</TT>), which consisted of about 550 lines of C code,
in about an hour. Many of the CSL API functions, like
<TT>csl_pcm_write</TT>, are similar to the underlying C library
functions commonly used for sound programming, like <TT>write</TT>.
<H2>Current Status and Future Plans</H2>
CSL is currently in a preview release. Work remains to finish some
missing features, perform testing, and fix bugs. Possible work in the
future includes implementing support for <TT>artsc</TT> (the C API for
arts) and the <TT>esound</TT> API used by GNOME. Stable releases
should also be made available as binary packages.
<H2>Conclusions</H2>
I believe CSL offers a solution to the problem of incompatible sound
support, especially on Linux desktop environments, and therefore deserves
attention from multimedia developers. I invite you to try CSL,
consider using it in your existing or new applications, and maybe even
help contribute to it.
<H2>References</H2>
<OL>
<LI> CSL HOWTO and FAQ (included in CSL source code)
<LI> CSL API Documentation (included in CSL source code, generated using <A HREF="http://www.doxygen.org">Doxygen</A>)
<LI> <A HREF="http://www.arts-project.org/download/csl-0.1.2.tar.gz">Source code for CSL 0.1.2</A>
<LI> <A HREF="http://www.arts-project.org/doc/csl-0.1.2.html">Release announcement for CSL 0.1.2</A>
<LI> <A HREF="http://www.arts-project.org/doc/gnome-arts-0.1.2.html">Release announcement for GNOME aRts 0.1.2</A>
<LI> <A HREF="http://www.arts-project.org">Home page for the aRts Project</A>
</OL>
<P>
There is a mailing list for CSL. You can join the list by sending a
message with the word <EM>subscribe</EM> as the message body to
<TT>csl-request@space.twc.de</TT>. The mailing list is archived at <A
HREF="http://www.mail-archive.com/csl@space.twc.de">http://www.mail-archive.com/csl@space.twc.de</A>.
<!-- *** BEGIN bio *** -->
<SPACER TYPE="vertical" SIZE="30">
<P>
<H4><IMG ALIGN=BOTTOM ALT="" SRC="../gx/note.gif">Jeff Tranter</H4>
<EM>Jeff Tranter has been using Linux since 1992. He is the author of the
Linux Sound and CD-ROM HOWTOs and the O'Reilly book </EM>Linux
Multimedia Guide<EM>. He has worked in a number of diverse areas of
Linux, most recently on the KDE desktop environment focusing on
multimedia. He is currently employed at a new Linux company,
<A HREF="http://www.xandros.com">Xandros Corporation</A>.</EM>
<!-- *** END bio *** -->
<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P -->
<H5 ALIGN=center>
Copyright &copy; 2001, Jeff Tranter.<BR>
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
Published in Issue 70 of <i>Linux Gazette</i>, September 2001</H5>
<!-- *** END copyright *** -->
<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="spiel.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue70/tranter.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="williams.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->