Bergen Sound Server & Library, Version 0.4.1
by Dave Pape (pape@evl.uic.edu)
Introduction
Bergen is a very simple, freely redistributable audio server and
client library.
It was created for use in CAVE applications, to get around a few of the
limitations in the VSS library; most of those limitations have been fixed,
but as VSS is a fairly advanced tool, Bergen will stick around as a more
basic alternative.
Send any comments or bug reports to me.
As with VSS, there are two basic parts to Bergen -- the client library
(libbergen) and the server (snerd).
There are also some basic client programs --
bergenPlay, bergenReset, bergenKill, and bergenDemo.
The library, server, client programs, and complete source code are here
in bergen0_4_1.tar.gz.
They are also available (at EVL) in ~pape, in my lib/ and include/ directories.
Change Log
- Version 0.4.1
- Modified Linux version of snerd to reduce the latency between when
a play command is received and when the sound is heard, by
telling the audio driver to use a smaller buffer of sound fragments.
- Version 0.4
- Added Linux support.
- Added a duration() function to the bergenSample class.
- Added a "gain" command to the main snerd program, which allows one to
set an overall gain factor for the sound.
- Corrected a bug in the SampleFile class. Samples will stop correctly
when they reach the end of the file; previously, an explicit
"stop" command had to be sent by the client, or the sound could
not be played again.
- Added port number option to snerd and to bergenServer class, to override
the default port (5900).
- Version 0.1
- snerd now handles varying sample rates, channels, and sample sizes
in sound files, and accepts an "-srate" command line option.
- bergenServer now has a reset() function.
Known Bugs
- The UDP code does not convert the port number to network-byte-order
on Intel machines. Since the server and the clients use the same code,
this problem is not apparent as long as both are run on the same type
of machine. But, a client on an SGI cannot communicate with a server on
an Intel PC, or vice versa (except by fudging the port number via
BERGEN_PORT; i.e. if snerd is started with the default port of 5900, then
on the client do "setenv BERGEN_PORT 3095" [5900 = 0x170c; 3095 = 0x0c17]).
To be fixed in version 0.5. (Note that fixing it will break existing Linux clients.)
Library Interface
The Bergen library is entirely C++ oriented. It consists of classes
representing
the connection to the server (bergenServer) and the individual sounds
(bergenSound and bergenSample). The following is a simple demo
showing how the library is used:
#include <unistd.h>
#include "bergenServer.h"
#include "bergenSample.h"
main(int argc,char **argv)
{
bergenServer * server = new bergenServer;
bergenSample * sound = new bergenSample("sound.aiff",server);
sound->setLoop(1);
sound->play();
sleep(1);
sound->setAmplitude(0.25);
sleep(1);
delete server;
}
bergenServer class
This class handles the network connection to the server (snerd). It must be
created before any sound objects can be created.
Multiple bergenServer objects, talking to the same or to different servers,
can be created by a program; they will not interfere with each other.
If the object fails to connect to the server program, it will print an error
message; when this happens, messages which are to be sent to the server by
sound objects will be discarded, but the client program will run without crashing.
When a sound object is created, it must be given a pointer to the server object;
the server object maintains a list of all sounds which are created, so that it
can automatically delete them all when it is deleted itself.
#include "bergenServer.h"
- bergenServer::bergenServer(char *host=NULL,int port=0)
- The constructor will make a UDP network connection to the snerd server
program, sending it a "ping" message to verify the connection. The argument
host, if given, is the name or IP address of the machine which snerd
is running on; if it is not given, the value of the environment variable
BERGEN_SERVER is used; if this variable is not set, the connection is made to
the local machine.
The argument port is the port number that the server is listening
to; if it is not given (or is 0), the value of the environment variable
BERGEN_PORT is used; if this variable is not set, the default port of
5900 is used.
- bergenServer::~bergenServer(void)
- The destructor will automatically delete all sounds which are in its list
of bergenSound objects (maintained by addSound() and removeSound).
- void bergenServer::setDirectory(char *dir)
- Sets the default directory for sound objects. bergenSample objects will use
this directory if their sample file name does not include a path.
- char * bergenServer::directory(void)
- Returns the default directory name set by setDirectory().
- void bergenServer::reset(void)
- Re-initializes the connection to the server program, and re-creates all the
sound objects (that it manages) on the server. This can be used to reset things
if snerd crashes & is restarted, or if it is started after the bergenServer
object is created.
- void bergenServer::sendMessage(char *msg)
- Sends the given text string to the server program. This is mostly for internal
use, by the bergenSound classes.
- int bergenServer::receiveMessage(char *msg,int size)
- Gets the next message sent by the server program. This is mostly for internal
use, by the bergenSound classes.
- void bergenServer::addSound(bergenSound *sound)
- Adds a sound to the server object's list. This is used internally, by the
bergenSound class, and should not be called by applications.
- void bergenServer::removeSound(bergenSound *sound)
- Removes a sound from the server object's list. This is used internally, by the
bergenSound class, and should not be called by applications.
bergenSound class
This is a generic class representing any type of sound; it defines the basic sound object
interface.
The actual sound objects which are created will be of subclasses of bergenSound;
presently there are three subclasses -- bergenSample, bergenTone, and
bergenWhiteNoise.
#include "bergenSound.h"
- bergenSound::bergenSound(bergenServer *server)
- The constructor must be given a pointer to a server object; it will tell
the server object to add this sound to its list of sounds.
- bergenSound::~bergenSound(void)
- The destructor does an automatic kill before the sound object is
removed.
- int bergenSound::handle(void)
- Returns the handle which the server program has assigned to this sound
object; this is used in all messages to the server program which control the
sound.
- bergenServer * bergenSound::server(void)
- Returns the pointer to the server object which was given when the object
was created.
- void bergenSound::setAmplitude(float amp)
- Sets the sound's current amplitude; sends a message to the server program
to accomplish this.
- void bergenSound::play(void)
- Sends a message to the server program to start playing the sound.
- void bergenSound::stop(void)
- Sends a message to the server program to stop playing the sound.
The next time a play command is issued, the sound will start again
from the beginning.
- void bergenSound::pause(void)
- Sends a message to the server program to pause the sound.
The next time a play command is issued, the sound will resume from the
point at which it was paused.
- void bergenSound::kill(void)
- Sends a message to the server program to remove the sound, and tells the
server object to remove this sound from its list. The sound object should
not be used after kill() is called; this is meant to be called from
the destructor, and should not generally be used directly by applications.
bergenSample class
This class represents a single audio sample file; it is a subclass of
bergenSound.
#include "bergenSample.h"
- bergenSample::bergenSample(char *filename,bergenServer *server)
- The constructor must be given the name of the sample file which the sound
will play, in addition to the server object pointer.
- void bergenSample::setLoop(int loop)
- Sets the sound's looping flag -- if it is true (non-zero), the sound will
loop continuously when it is played.
- float bergenSample::duration(void)
- Returns the total playing time of the sample file, in seconds. If the
server failed to find the sample file, this will return 0.
Note that this function requires sending a message to the server and
waiting for the response, so it is potentially slow.
bergenTone class
This class plays a simple sine-wave tone.
#include "bergenTone.h"
- bergenTone::bergenTone(void)
- Creates the tone sound object.
- bergenTone::setFrequency(float freq)
- Sets the frequency of the sound to be freq cycles per second.
The default frequency is 1000 Hz.
bergenWhiteNoise class
This class plays random, white noise.
#include "bergenWhiteNoise.h"
- bergenWhiteNoise::bergenWhiteNoise(void)
- Creates the white-noise sound object.
snerd
snerd is the server program which the Bergen client library communicates with
in order to play sounds. Communication between clients and snerd is by UDP/IP.
Start snerd on your audio machine before running any client programs.
It has two commmand line options:
- -srate rate - sets the output sample rate. The rate should be
one that is supported by your sound hardware. e.g.:
snerd -srate 22050
The default sample rate is 32000.
- -udpport port_number - sets the UDP/IP port number that snerd
will listen to for commands from clients. e.g.:
snerd -udpport 9000
The default port number is 5900.
snerd uses the SGI audiofile library to read sample files; this means that it
can play samples in any format supported by that library (AIFF, AIFC, WAVE, etc.)
It accepts 8- or 16-bit, 2's-complement or unsigned files of any sample rate.
It will automatically resample the data to 16-bits, 2's-complement at the
selected output rate. The resampling method is very crude; input files with a
low sampling rate may sound very bad if snerd is running at a much higher output
rate. For best results, use 16-bit, 2's-complement sound files and run snerd at the same
sample rate as that of the files.
Files can have any number of channels, but only the first channel will be played.
Last modified 10 November 2000.
Dave Pape, pape@evl.uic.edu