402 lines
16 KiB
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 <unistd.h>
|
|
2 #include <stdio.h>
|
|
3 #include <fcntl.h>
|
|
4 #include <csl/csl.h>
|
|
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, &driver);
|
|
19 csl_pcm_open_output (driver, "cslpcm1", options.rate, options.n_channels, options.pcm_format, &stream);
|
|
20 fd = open("/dev/urandom", O_RDONLY);
|
|
21 for (i = 0; i < 500; i++)
|
|
22 {
|
|
23 read(fd, buffer, size);
|
|
24 for (j = 0; j < 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><csl/csl.h></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 © 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 ============================================================-->
|