(note: the pongserver research evolved into the
java-based disc-o project, which is part of the
JPMCKDMS project.
whew.)

the pongserver

douglas irving repetto

douglas@music.columbia.edu

download the pongserver.0.3 source (GPL):
pongserver.current.tar.gz

(this is beta software! use at your own risk.)



what is the pongserver?

i'm glad you asked. the pongserver is a bunch of client/server programs that talk to one another. what they talk about is the current location of the client objects in the server's playing field.

there are two types of clients: control-clients and status-clients. a control-client releases a client object (a ball or a paddle) into the server's playing field. as the object moves (or is moved) around the playing field, the server constantly sends messages to that client about its current position. the client does with that information what it wishes. so far i've created clients that make sound, using the x-y coordinates to control the sound's properties, and others that draw graphics. a client can do whatever you want it to do; you could have the client water your plants every time it collides with another client if you wanted to.

status-clients do not release objects into the playing field. they receive constant updates about the current position of all of the clients in the playing field. there are currently three status-clients: guiclient, wire client and addsynclient.

guiclient uses the positional information to draw the field and all of the client objects. it has a gui that allows you to drag clients around with the mouse and to delete clients by right-clicking on them. guiclient also takes midi input so that you can control the clients via midi controllers. i've been hacking up joysticks for this...it's really cool.

wireclient is a simple status-client with a variety of drawing options that are selected via a configuration file. "wire" draws a straight line between each of the clients. this makes a type of wireframe drawing, using the clients as the nodes. "star" selects one client as the center of the star and then draws a star pattern using the rest of the clients as points. "petal" is similar to star, except that it uses loops instead of points. finally there's "electron", which draws concentric ovals using the location of the clients to determine the height and width of the ovals. as the clients move so do the nodes/points/loops/ovals, so what you get is a very dynamic, flowing geometric design. i particularly like opening a guiclient and a couple different wire clients and lining up their windows in a grid, as in the screen grab above.

addsynclient is a status-client that makes sound. it does additive synthesis using the client positions as the source of frequency and amplitude data for a set of sinewaves. it also draws a simple frequency/amplitude graph to display the additive synthesis parameters.

i'll be adding more graphics drawing status-clients soon.

there are a bunch of control-clients. mostly they make some sort of sound based on their position in the field. the sourcecode for each client explains what it does.

summary: the main difference between control-clients and status-clients is that a control-client corresponds to one object on the playing field and only receives positional data for that one client. a status-client does not correspond to any object on the playing field, and it receives positional data for all objects.

required:

linux x86 (ppc untested). i'm doing development on a 650Mhz PIII running RH6.2. all code now compiles cleanly on RH7.0 as well, although there seems to be some funky behaviour.

ptheads: you probably have this already. if you don't have it, you need it!

qt and qt-devel: you only need these for the guiclient. i'm using qt-2.1.1-01, others should work

making it:

tar zxvf pongserver.current.tar.gz
cd pongserver.x.x
make clean; make

please let me know if you have trouble compiling pongserver.

running it:

first you need to run a pongserver. this can be on a remote machine or on your local machine. the argument is a port number.

./server/pongserver 52000 &

next run some clients. i usually start with the guiclient so that i can see what's happening. the arguments are a port number (must be the same port number you gave to the server), the name of the host that the server is running on (localhost works if you're running the server and clients on the same machine) and the config file. there are example config files in the various directories.

./status-clients/guiclient/guiclient my.server.org 52000 ./status-clients/guiclient/guiclient.conf &

now start up some sound making clients. here are some examples:

sineclient is a simple sinewave generator. frequency and panning are controlled by the ball's position. the third argument below is the sound output device.

./control-clients/sineclient my.server.org 52000 /dev/dsp ./control-clients/sineclient.conf &

noiseclient is a noise source fed through a bandpass filter with variable Q. center frequency and Q are controlled by the ball's position.

./control-clients/noiseclient my.server.org 52000 /dev/dsp ./control-clients/controlclient.conf &

the sampleclient takes an aiff file as an additional argument. sample playback speed and panning are controlled by the ball's position.

./control-clients/sampleclient my.server.org 52000 /dev/dsp sounds/bell.aiff ./control-clients/controlclient.conf &

now put some paddles in there to make things interesting. the silentclient doesn't make sound (!), so it doesn't need a dsp argument. device.

./control-clients/silentclient my.server.org 52000 ./control-clients/silentclient.vert.paddle.conf &
./control-clients/silentclient my.server.org 52000 ./control-clients/silentclient.vert.paddle.conf &
./control-clients/silentclient my.server.org 52000 ./control-clients/silentclient.horiz.paddle.conf &
./control-clients/silentclient my.server.org 52000 ./control-clients/silentclient.horiz.paddle.conf &

i tend to put all of this into a script and then just launch the script with a port number as an argument. there's a sample script in the top level directory.

the 52000 is just a random port number. i tend to use 52000 and above. if you stop the server and then try to start it again with the same port number it will probably fail. just use a different port number.

everything can be run on the same host (using localhost as the host) or they can all be on different hosts. you just have to point the clients at the host where the server is running. of course updates will be slow and choppy on a less-than-speedy net connection...

try running status clients on a bunch of different machines at the same time...it's pretty cool!

killall pongserver

is the easiest way to shut everything down.

what to do:

in the guiclient, left-click and drag on a client to move it.

clients bounce off of the walls and each other. use the paddles to deflect the balls. use paddles to build pathways for the balls, or to trap them in little dungeons. run serveral guiclients, each on a different machine, and play pong.

clients have a "collisionDrain" factor, which determines how much energy they gain or lose when they collide with another client or a wall. if you just let the balls bounce around on their own, after awhile they'll slow down and stop. you can get them moving again by nudging them with another client.

right-click on a client to delete it. you can delete any client, whether it was launched from your machine or not.

join an online pongserver session: i'll (try to) keep a pongserver running at music.columbia.edu on port 52000. to join you'd do something like this:

./status-clients/guiclient/guiclient music.columbia.edu 52000 ./status-clients/guiclient/guiclient.conf &
./control-clients/noiseclient music.columbia.edu 52000 /dev/dsp ./control-clients/controlclient.conf &
./control-clients/silentclient music.columbia.edu 52000 ./control-clients/silentclient.vert.paddle.conf &

note that you'll see all clients, but you'll only hear the sound-producing clients that are running on your machine! however you could write a status-client that makes sound using all of the balls on the field...

using midi:

you can control the velocity of any client in the playing field via midi. the setup is a little bit funky, but it works well. i'm using a peavey pc1600 midi fader box that i've customized to work with analog joysticks. any midi device that can send controller messages should work, although i think that a 2 dimentional controller like a joystick will be more intuitive than something like a slider box, since you can map the joystick's x/y movement to the client's x/y velocity.

the guiclient is the only client that listens for midi. it can listen to up to three midi streams at a time, meaning that you can control three clients at the same time. the three currently selected clients have colored centers. one is red, one green and one blue. two midi controllers can select the same client at the same time, in which case you'll only see one of the colored centers. it's fun to fight for control of a client...all midi messages should be sent on channel 1.

here's what does what:

noteon 0 or 1, velocity > 64: change the red selected client
noteon 2 or 3, velocity > 64: change the green selected client
noteon 4 or 5, velocity > 64: change the blue selected client

controller 0: change x velocity of red client
controller 1: change y velocity of red client
controller 2: change x velocity of green client
controller 3: change y velocity of green client
controller 4: change x velocity of blue client
controller 5: change y velocity of blue client

as you send noteons you'll cycle through all the clients in the field. when you get to the last client you loop back to the beginning.

todo:

send info to status-clients about who else is logged in. i.e. name, machine, etc.

get guiclient to tag the clients in some way so that it's easier to keep track of which client is which. or maybe not, it's kind of fun not knowing...

document the socket negotiation process so that other people can write clients without having to untangle my code...right now writing a control-client is pretty easy, just drop your own dsp loop into the dsp loop.

figure out how to allow clients to be added from a status-client. deleting is easy, i just send a message from the guiclient to the server, which then sends a message to the client telling it to exit. but it's not clear how the server should tell a remote machine to launch a client...


change log:

24.nov.2000 -- pongserver.0.3
added configuration files for all types of clients
added drawing options to wire client
added addsynclient
added polepositionclient (brrrrrmmmbrrrrrrrrmmmmmm!)
replaced paddle client with silentclient
cleaned up code and simplified code structure
made it easier to create new control clients (they now use common files)

9.nov.2000 - pongserver.0.2 (not released)
added midi control to guiclient
added really cool wireclient (need to work on double buffer graphics code)
added loopclient, ringmodclient, inputringmodclient, pwclient
cleaned up #includes to get rid of some errors on RH7.0
restructured Makefiles/directories a bit

?.nov.2000 -- pongserver.0.1.beta
initial release