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


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:

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