Introduction

This is the reference manual for version 3.1 of VSS, the "Virtual Sound Server". Developed at NCSA and ISL, VSS is multiplatform software for data-driven sound production controlled from interactive applications.

VSS controls, coordinates, and synchronizes sounds produced by direct software synthesis, sample playback, and external synthesizers such as MIDI, Max, and Open Sound Control.

VSS's original SGI audio scheduler is based on HTM, a real-time sound synthesizer developed by Adrian Freed at the Center for New Music and Audio Technologies.

VSS comes in several distributions:

Each distribution includes the reference manual and the tutorial, also available here. (The distribution now omits the tutorials because they're too big.)

A client first makes a connection to VSS. It then requests the server to make a sound, whereupon the server does so and replies with a "handle" for the sound. The client can then send further messages using this sound handle to modify the sound and eventually delete it. Finally the client breaks the connection with the server.

Interaction between the client and sounds is coordinated through entities called actors. Actors are requested by the client and then manipulated using actor handles, in similar manner to sounds. Actors are classified by the types of actions they perform, including the types of sound synthesis being used to generate the sounds. As with an object-oriented class hierarchy, in the actor hierarchy, an actor may control several related sounds, so that they all may be manipulated at once with a single message to the actor. An actor accepts messages from VSS clients or from other actors, and can send messages to other actors. Some actors process real-time input and generate real-time output in various formats, primarily audio and MIDI.

Running VSS

Run VSS on an SGI computer with audio hardware and IRIX 5.3 or later, by typing "vss" at a shell prompt. Run a client on the same host, or on a different host accessible to the server's host over the network. In the latter case, tell the client where to VSS is, with a shell command like export SOUNDSERVER=myvsshost.foo.bar.edu.

Run only one instance of VSS per machine. If you find a VSS already running, either use it, or, if you must run your own copy, first type vsskill to terminate the current one.

If the client can't connect to the server, it times out after a few seconds and prints an error message.

When VSS exits, it emails to audio@ncsa.uiuc.edu a report consisting of which actors were loaded and how many of each. (This is so only for the licensed, non-demo versions.) These reports help the VSS team set priorities on which features to add, what code is really worth optimizing, and so on. If you prefer not to have these reports sent, set the environment variable VSSMAIL to "0" (export VSSMAIL=0). If you export VSSMAIL=foo@bar.com, the email will be copied to that address.

Command-line flags

-srate n
Set sampling rate to one of 8000, 11025, 16000, 22050 (Irix default), 32000, 44100 (Linux+Windows default), or 48000 Hz.

-chans n
Set number of channels to 1 (default), 2 (Windows default), 4, or 8.

Note that 8-channel mode on SGI requires Irix 6.3 or greater, an ADAT fiber optic output such as those found on Octanes or Onyxes, a hardware device to convert the fiber to eight analog audio jacks, and apanel's default output to be set to "adat".

-chans nintom:a,b,c,...
Set number of channels computed by VSS to n. Set number of channels actually played by the computer to m. Assign m channel numbers a,b,c,... to be the ones played. This uses more CPU than plain old "-chans n", but enables tricks like:

  • swap left and right: -chans 2into2:1,0
  • hear individual channels of an 8-channel sound on 2-channel hardware: -chans 8into2:6,7 (or loosely build up an 8-channel mix from several 2-channel hosts)
  • customize a 2 to 4 channel map (left -> front, right -> rear): -chans 2into4:0,0,1,1

-input [n]
Enable input of sound (to analysis actors). The optional n sets the number of channels of input, which defaults to 1.

-graphoutput
Graph output signal (Irix only).

-graphspectrum
Graph output spectrum (Irix only). Derived from code by Xavier Rodet, CNMAT.

-mmio
Use low-level MMIO audio instead of DirectSound. Useful if your sound card has no DirectSound driver, or if you need to output more than 2 channels. Windows only.

-hog n
As root on Irix, set cpu-hogging behavior following n's value:
  • 0 - normal
  • 1 - prevent swapping out
  • 2 - nondegrading highest-priority process

    As root on Linux, vss runs niced -10 and locked into memory (setpriority(PRIO_PROCESS, 0, -10) and mlockall(MCL_FUTURE)).

-lowlatency
Reduce input-to-output latency (on IRIX, recommended in combination with locking VSS to one CPU with mplockpid).

-latency lwm hwm
Bound latency by setting the low and high water mark, in samples (if you don't know what this is, don't ask).

-antidropout x
Increase resistance to audio dropouts from cpu starvation, to a duration of x milliseconds (Linux OSS only).

-soft
Enable soft clipping.

-limit
Prevent hard clipping.

-nopanel
Hide the graphical control panel.

-silent
Disable sound playback, if you want output to a sound file only.

Useful programs in the "util" subdirectory

vssping
Ping VSS to see if it's running.

vssflush
Reset VSS (by deleting all actors).

vsskill
Terminate any running copy of VSS on this computer.

audtest
Read and execute a .aud file, optionally running message groups from the command line.

audpanel
Read and execute a .aud file, with sliders and presets and scaling and buttons. Fancy enough to mock up your own application.

Writing Client Applications

The Trivial Client

  #include "vssClient.h"
  main()
  {
      if (!BeginSoundServer()) {
          printf("UDP connection to sound server failed\n");
          exit(2);
      }
      /* Break connection to sound server */
      EndSoundServer();
  }

To build this client, set the directories in which to find vssClient.h and libsnd.a:

  CC -c foo.c -IVssIncludeDir -fullwarn
  CC -o foo foo.o -LVssLibDir -lsnd -ll -lm

or

  CC foo.c -IVssIncludeDir -LVssLibDir -lsnd -ll -lm -fullwarn

Compiling and Linking

To compile VSS clients, try gcc and g++. On Irix, Mipspro C and C++ work well too.

Link with CC or perhaps cc -lC, but definitely not cc or ld. The latter may mystify you with errors like __vec_new and __nw__FUi.

How do I know if libsnd.a, vssClient.h, and VSS are all compatible?

If you use several versions of VSS and their components get mismatched, reconcile their versions thusly:

Using .aud files

The .aud file provides an interface through which the bulk of an application's audio code may be isolated from the compiled code. While the events which may trigger sound originate from within the client application, the specific way in which those events ultimately map to sound are described through the .aud file. This interface then allows the sound to be tweaked independently of the application, e.g. without recompiling the application, thereby simplifying the development and the debugging of the complete, sonified application. The interface will also help trivialize the process of porting the audio component of the app to other apps or platforms.

Three main functions implement the client-side interface to the .aud file:

int AUDinit(const char *filename);
Initialize. filename is the name of the .aud file, e.g. "../AUDFILES/foo.aud".

float AUDupdate(int handle, char *msgGroupName, int numFloats, float *floatArray);
Interact with messages in the .aud file referenced by the handle returned by AUDinit(), by sending an array of float data floatArray of length numFloats to the Message Group msgGroupName. For trigger and flag-type events, numFloats may be zero and floatArray NULL.

(Typically you can ignore the float return value. But if you know that the message group *msgGroupName contains a BeginSound statement, the return value will be a handle to that sound (the last one, if there are several). This is useful if you don't know at compile time how many sounds you'll need simultaneously.)

void AUDterminate(int handle);
Clean up, again using the handle returned by AUDinit().

A shortcut form of AUDupdate(), float AUDupdateFloats(int handle, char *msgGroupName, int numFloats, float f1, float f2, ...); , conveniently lets you dispense with declaring and stuffing floatArray. But it's unwieldy for very large numbers of arguments (though it'll accept a thousand), and the arguments must have type float or double (an int like 42 instead of 42.0 produces garbage).

For special circumstances there are a few other functions: AUDreset(), AUDupdateTwo(), AUDupdateMany(), AUDqueue(), and AUDflushQueue().

This code builds upon the previous example, putting these three functions in context:
  #include "vssClient.h"
  
  void UpdateState(float *data)
  {
    /* generate three numbers between 0 and 1 */
    data[0] = drand48();
    data[1] = drand48();
    data[2] = drand48();
  
    /* rescale two numbers */
    data[1] *= 20;
    data[2] *= 20;
  }
  
  void main()
  {
    int     i;
    int     handle;
    float   data[3];
  
    if (!BeginSoundServer()) {
      printf("UDP connection to sound server failed\n");
      exit(2);
    }
  
    handle = AUDinit("example.aud");
    if (handle < 0) {
      printf("Failed to load audfile example.aud\n");
      exit(3);
    }
  
    /* Send state messages to VSS */
    for (i=0; i<10; i++) {
    UpdateState(data);                    /* run my simulation */
    AUDupdate(handle, "Whack", 3, data);  /* send message group 0 */
    sleep(1);                             /* wait a sec */
    AUDupdate(handle, "Clang", 3, data);  /* send message group 1 */
    sleep(2);
  
    /* data[] maps to the "*" parameters in the .aud file
     (see below, "Messages in .aud files").  In the .aud file immediately
     below, data[0] sets the amplitudes of sounds in all three BeginSound
     messages; data[1] and data [2] set the tone color of sounds in two
     BeginSound messages that are synchronized.
     */
    }
  
    AUDterminate(handle);
    EndSoundServer();
  }

The client connects to VSS. Then it calls AUDinit(), which reads the .aud file example.aud (shown below), parses out the message strings, and then sends the messages to VSS. VSS also returns a file handle to reference example.aud and to interact with actors which example.aud caused to be created.

The client then updates the state of a data array, here 3 floats, and then makes successive calls to AUDupdate(). Each call passes new data values to each of the two Message Groups named Whack and Clang. The Message Groups are created from messages within the .aud file. (Details of .aud file messages are covered later.)

Here is the corresponding example .aud file, example.aud:
  // Have the server echo messages
     SetPrintCommands 1;
  
  // Load the DSOs that we will need
     LoadDSO msgGroup.so;
     LoadDSO marimba.so;
     LoadDSO tubebell.so;
  
  // Create two Message Groups
     Whack = Create MessageGroup;
     Clang = Create MessageGroup;
  
  // Create generator actors for the message
  //    groups to route messages to
     Woody = Create MarimbaActor;
     Belly = Create TubeBellActor;
  
  // Create list of messages for "Whack"
     AddMessage Whack BeginSound Woody SetAmp *0, SetStickHardness 3.0;
  
  // Create list of messages for "Clang"
      AddMessage Clang BeginSound Belly SetAmp *0, SetModIndex *1;
      AddMessage Clang BeginSound Belly SetAmp *0, SetModIndex *2;

Again, .aud file messages are detailed below; only certain aspects are pointed out here.

Dynamically Shared Objects (DSOs) are loaded with the LoadDSO message. A DSO contains the code for one or more actors used by VSS, so it must be loaded before these actors can be used. Therefore, LoadDSO messages are usually placed near the start of the .aud file.

The Message Groups are then created. The names of the Message Groups within the .aud file must match the names used in the client's AUDupdate() calls: these names are the interface between client and server.

Messages are then added to each Message Group. The messages define the group of actions to be taken by VSS when a particular Message Group is triggered by a client-side AUDupdate(). In this case, the message "Whack", upon receipt by the server, will begin a marimba sound with stick-harness of 3.0; the message "Clang" will begin two Tubular Bell sounds with two different degrees of tonal brightness. The set of actions taken by a given Message Group occur in the order in which they appear in the .aud file.

Through this grouping of messages, one AUDupdate() can trigger many, possibly diverse, actions. Diversity of actions is accomodated by allowing an array of data values to be passed through the call to AUDupdate(). From within the Message Group, individual elements of the array may then be referenced and used, say, to set different sound parameters. For example, in the line
     AddMessage Whack BeginSound Woody SetAmp *0, SetStickHardness 3.0;
the element array[0] is referenced through the notation *0 (generally, array[N] is referenced through *N) to set the amplitude value of the Marimba sound to be played.

A .aud file has no variables per se, no "scope". All the state of a running .aud file is hidden inside its actors. Therefore, at first blush if you use BeginSound from inside a message group
  	AddMessage Clang BeginSound Belly;
then there's no way to get at the handle returned by BeginSound (if you want to modify or end that sound). The following doesn't work:
  	AddMessage Clang myBell = BeginSound Belly;   // "myBell =" is illegal
  	AddMessage Clang SetAmp myBell 0.1;
Message Groups have a special syntax to handle this case, where the message group itself begins a sound instead of modifying an already existing sound. The syntax is similar to *0 *1 etc.: "*?" stands for the handle to the most recent BeginSound. So the previous example becomes, correctly:
  	AddMessage Clang BeginSound Belly;
  	AddMessage Clang SetAmp *? 0.1;
You can modify the note at some point in the future by using the LaterActor, as follows:
  myLaterActor = Create LaterActor;
  ...
  AddMessage Clang BeginSound Belly SetAmp 0.1;
             // Might as well put the SetAmp in the same line.
  AddMessage Clang AddMessage myLaterActor 0.5 SetModIndex *? *1;
             // Wait 0.5 seconds, then SetModIndex.
  AddMessage Clang AddMessage myLaterActor 1.5 SetModIndex *? *2;
             // Do it again, 1 more second later.
  AddMessage Clang AddMessage myLaterActor 5.0 Delete *?;
             // End the sound after 5 seconds.

Simplified syntax when using only one .aud file

If your C program uses only a single .aud file, it can use a simplified form of the C functions AUDinit(), AUDupdate()/AUDupdateFloats(), and AUDterminate():

Using Text Preprocessors with .aud Files

After mastering the basics, you may find this to be a useful way to manage very large .aud files.

In Irix, filter programs can modify a .aud file before it gets parsed. Filters read text from standard input and emit (modified) text on standard output. Examples of these are the C preprocessor, perl, m4, and handwritten C programs. To invoke a filter, make the first line of the .aud file

  //pragma filter "myprogramname"

where myprogramname is the name of the filter (technically, anything that /bin/sh can parse). The C preprocessor, for example:

  //pragma filter "/usr/lib/cpp -P"

This line can't have leading or trailing whitespace, or trailing comments. Also note that because the filtered output text isn't stored, line numbers of any reported syntax errors will probably be incorrect.

Miscellaneous Limits

Not using .aud files

In special circumstances you may want to call C functions directly from your VSS client application, instead of going through a .aud file. Here are some of the functions you can use then (these are the same functions which are called by the parser of .aud files). Beware of subtle errors, though. This fragment of documentation doesn't pretend to adequately explain this interface, out of laziness and out of discouraging its use.

  int   BeginSoundServer(void);
  int   BeginSoundServerAt(char * hostName);
  void  EndSoundServer(void);
  int   PingSoundServer(void);
  
  void  actorMessage(char* messagename);
  void  actorMessageF(char* messagename, float);
  void  actorMessageFD(char* messagename, float, int);
  void  actorMessageFDD(char* messagename, float, int, int);
  float actorMessageRetval(char* messagename);
  
  void  MsgsendObj(OBJ obj, struct sockaddr_in *paddr, mm* pmm);
  OBJ   BgnMsgsend(char *szHostname, int channel);
  void  Msgsend(struct sockaddr_in *paddr, mm* pmm);
  void  MsgsendArgs1(struct sockaddr_in *paddr, mm* pmm, const char* msg, float z0);
  void  MsgsendArgs2(struct sockaddr_in *paddr, mm* pmm, const char* msg, float z0, float z1);
  void  clientMessageCall(char* Message);
  
  float actorGetReply(void);
  float createActor(const char* actorType);
  void  deleteActor(const float actorHandle);
  void  setActorActive(const float actorHandle, const int active);
  float beginSound(const float hactor);
  void  killSoundServer();

VSS Message Reference

Built-in messages

VSS itself understands these messages, independent of whatever actors it has created.

Create actorName
Create an actor of type actorName.

DumpAll
Send the Dump message to all actors. For debugging.

KillServer
Terminate VSS immediately, even if other clients are connected to it.

LoadDSO dsoName
Load a DSO into VSS. The only way to get an actor into VSS. The argument dsoName refers to a file in, or path/file relative to,
  1. the server launch directory ("."),
  2. the directory $SOUNDSERVER_DSO (in csh, "setenv SOUNDSERVER_DSO myDsoDir" on server machine),
  3. the directory containing the executable file vss, or
  4. /lib or /usr/lib.

VSS searches these directories in this order. LoadDSO fails if the dso is not in one of these directories. In Windows, DSO's (actually, DLL's) are searched for in the following directories, in this order:

  1. The directory containing VSS.
  2. The directory where VSS was run from.
  3. The Windows system directory.
  4. The Windows directory.
  5. Directories listed in the PATH environment variable.

Note that the LIBPATH environment variable is not used.

Ping
Confirm that VSS is running.

SetPrintCommands level
When level = 1, cause VSS to print all the messages it receives from clients (in green). When 2 or more, print messages that actors receive from other actors (in blue). When 0 or less, print none of the above.

EnableOfile 1 "filename"
Start logging the output of VSS into a raw audio file. Append to the file if it already exists (say, from a previous EnableOfile). The filename can be absolute, or relative to the directory that VSS was launched from.

EnableOfile 0
Stop logging. To convert the file into an aiff file, at a shell prompt type:
    sfconvert filename.raw filename.aiff -i rate 44100 int 16 2 chan 2 end format aiff
where 44100 is the sampling rate VSS was running at, and the number 2 after chan is the number of channels VSS was running at. (A "filename" optionally follows the 0. This filename is ignored, but allowed for the convenience of tools like audpanel.)

SetGear gear
Change the gear VSS is running in, by analogy with an automobile transmission. The argument gear takes one of three values: PRNDL_Parked, PRNDL_Low, PRNDL_Drive. PRNDL_Parked suspends computation of samples, and is appropriate during initialization (often the bulk of a .aud file, creating actors and sequences). PRNDL_Low is the default. PRNDL_Drive is appropriate when the app is running smoothly and sending only parameter-update messages. PRNDL_Drive handles a flood of incoming messages more gracefully than PRNDL_Low.

Client-side messages

The following look like messages when written in a .aud file, but in fact do not cause any message to be sent to the VSS server. They only affect the client that loaded the .aud file. (So don't put them in a message group; they are not messages, are not sent to any actor, not sent to VSS, not seen by AUDupdate(). They happen only during AUDinit(); they're useful only during the initialization part of a .aud file.)

ClientSleep seconds
Pause the client. ("Sleep" and "sleep" are historical synonyms for "ClientSleep".)

ClientSetTimeout seconds
Specify how long the client will wait for a handle back from VSS for a Create or BeginSound message. Default is 2.5 seconds, minimum 0, maximum 3600.

Sometimes the client should wait until VSS has completed a slow task that does not return a handle, such as a few LoadFile messages sent to a SampleActor when the files are on a network-mounted disk. Accomplish this with a Create or BeginSound message whose sole purpose is to force VSS to return a handle to the client:
  ClientSetTimeout 60;
  LoadFile ... ;
  LoadFile ... ;
  LoadFile ... ;
  dummy = Create SampleActor;
  Delete dummy;
  ClientSetTimeout 2.5;
ClientPrint "string"
Display something on standard error (for debugging).

Actor messages

Actors have a class hierarchy. They respond to messages at different levels, depending upon the actor type and the functionality needed.

Actors fall into three primary types.

Two examples explain these concepts. First, the LaterActor is a Control Actor:

The Create message instantiates a LaterActor. VSS returns the handle act_handle1 so further messages may refer to that particular instance. During usage, we may desire to delay, say by 0.5 seconds, the sending of a message message to an instance act_handle2 of the generator actor FMActor. We may accomplish this by issuing an AddMessage message using act_handle1, where the message contents use act_handle2. Thus, the LaterActor passes the contents of message from where it originated (e.g. the client or another top-level actor) to another actor, in this case a generator actor. So, the LaterActor works only at the top level.

On the other hand, the FMActor is a Generator Actor and operates at all three levels:

Again, a Create messages creates an instance act_handle2 of the FMActor. Two sounds are begun using the BeginSound message and act_handle2. This invokes the FMHandler, creating the two sound instances sound_handle1 and sound_handle2. For these sounds, the FM synthesis algorithm is used with default parameters. The internal state information for the sound synthesis is hidden within each existing sound, so that the sound generation may proceed independently among all sounds. (Each sound can then be called a child of its referring actor instance, or parent actor.)

Messages may then be sent to existing instances of the Actor or Handler, with the different levels of interaction resulting in differing behavior. For example, SetAllAmp act_handle2 0.5; assigns 0.5 to the amplitudes of both sounds sound_handle1 and sound_handle2, but SetAmp sound_handle2 0.5; affects only the latter.

Messages for all actors

Active hActor bool
Activate/Deactivate this actor. An actor is active when bool=1 (default), which means that its act() method is being called. Certain uses of the EnvelopeActor require the Active message to be sent manually. VSS sends this internally, to silence an actor just before deleting it.
Debug hActor x
Set this actor's debug level to x. Individual actors use this value as they see fit.
Delete hActor
Delete this actor.
Dump hActor
Display this actor's contents. For debugging.

Messages for generator actors

Generator actors also understand the following messages. Italic arguments are optional. [Params] can be any number of parameter-setting messages appropriate to that actor.

BeginSound hActor [params]
Create a new instance of the synthesis algorithm and handler corresponding to this actor. Returns the handler's handle to the client.
BeginSoundPaused hActor [params]
Create a new instance, return a handle, and leave it paused (inactive, not generating samples).
SetAmp hActor x
Let x be the default amplitude for all future handlers created by this actor (0 = silent, 1 = nominal).
SetAllAmp hActor x time
Set the amplitude for all of this actor's handlers (its children) to x and set the default amplitude for all future handlers. If time is specified, modulate handlers to the new value over the specified duration. Regardless of time, the default value is set immediately,
SetGain hActor x
Set the default amplitude in decibels for all future handlers created by this actor to x (-100 or less = silence, 0 = nominal).
SetPan hActor x
Set the default pan position for all future handlers created by this actor to x (-1 = hard left, 0 = centered, +1 = hard right).
SetElev hActor x
Set the default elevation for all future handlers created by this actor to x (-1 = hard down, 0 = level, +1 = hard up). Use +1 to give your sounds a subtle aura of impecuniosity.
SetDistance hActor x
Set the default distance for all future handlers created by this actor to x (in feet).
SetDistanceHorizon hActor x
Set the default horizon distance for all future handlers created by this actor to x (in feet), if you need to tweak how the distance cues like SetXYZ work.
SetXYZ hActor x y z
Set the default position for all future handlers created by this actor to (x,y,z) (in feet, standard cave-coords).
InvertAmp hActor fInvert
By default, invert the signal (multiply amplitude by -1) for all future handlers created by this actor if fInvert is true.

SetAllGain hActor x time
SetAllPan hActor x time
SetAllElev hActor x time
SetAllDistance hActor x time
SetAllDistanceHorizon hActor x time
SetAllXYZ hActor x time
InvertAllAmp hActor fInvert
All these are analogous to SetAllAmp.

SetLinearEnv hActor bool
Interpolate amplitudes linearly (like before VSS 3.1) instead of exponentially, if bool=1 (default=1). Generator actors default to exponential.

Messages for processor actors (generator actors which accept audio input)

SetInputAmp hActor x
Set the default input scaling for all future handlers created by this actor to x (0 = silence, unity = nominal). Default is nominal.
SetInputGain hActor x
Set the default input scaling in decibels for all future handlers created by this actor to x (-100 or less = silence, 0 = nominal). Default is nominal.
SetAllInputAmp hActor x time
By analogy with SetAllAmp.
SetAllInputGain hActor x time
By analogy with SetAllAmp.

Messages for handlers

Handlers also understand the following messages. Italic arguments are optional.

SetAmp hSound x time
Set the amplitude for this sound to x. If time is specified, modulate to the new value over the specified duration.
ScaleAmp hSound x time
Set the secondary amplitude for this handler to x. THe secondary amplitude defaults to unity. It is provided if you need to control amplitude in a separate way from the main amplitude.
SetGain hSound x time
Set the amplitude in decibels for this sound to x. If time is specified, modulate to the new value over the specified duration.
ScaleGain hSound x time
Set the secondary amplitude in decibels for this handler to x. The secondary amplitude defaults to +0 dB.
SetPan hSound x time
Set the pan position for this sound to x. If time is specified, modulate to the new value over the specified duration. Pan from hard left to hard right as x varies from -1 to 1. In 4-channel mode, hard left and hard right meet directly behind the listener, and mod-2 arithmetic is used (-3 is also directly behind; 2 is also directly in front). Panning over a time interval in 4-channel mode is done "the shortest way around the circle". 8-channel is analogous to 4-channel.
SetElev hSound x time
Set the elevation for this sound to x. If time is specified, modulate to the new value over the specified duration. Move from "hard down" to "hard up" as x varies from -1 to 1. This message has an audible effect only if VSS is running with 8 channels.
SetDistance hSound x time
Set the distance for this sound to x feet. If time is specified, modulate to the new value over the specified duration.
SetDistanceHorizon hSound x
Set the horizon distance for this sound to x feet, if you need to tweak how the distance cues like SetXYZ work. No time may be specified here.
SetXYZ hSound x y z time
Set the position for this sound to (x,y,z) feet, in standard cave-coords. If time is specified, modulate to the new value over the specified duration. Note that SetXYZ is implemented in terms of SetPan SetElev SetDistance. This means that, for a given handler, you can use either SetXYZ or these other three. If you combine them, the acoustic result is undefined (though probably entertaining). But you can use SetXYZ for some sounds you wish to localize in threespace, and use SetPan etc. to position other sounds to taste, with no problems. You might also want to do SetDistanceHorizon hSound x (as above) where x is the largest distance you expect to a sound source.

InvertAmp hSound fInvert
Invert the signal (multiply amplitude by -1) if fInvert is true.
SetMute hSound bool
Mute/unmute this sound as bool is 1 or 0 (default). A muted algorithm still generates samples and stores them in its internal buffer, but these samples are not sent to the VSS main outputs. Muting is like temporarily zeroing a handler's amplitude.
SetPause hSound bool
Pause/unpause this sound as bool is 1 or 0 (default). A paused algorithm generates no samples. Pausing is like temporarily removing an algorithm from the audio-synthesis scheduler.
SetLinearEnv hSound bool
Interpolate amplitudes linearly (pre-vss3.1 behavior) instead of exponentially, as bool is 1 (default) or 0. (If a handler receives no SetLinearEnv message, it uses the linear-or-exponential interpolation behavior of its parent actor.)
SetNumChans hSound numchans
Let numchans be how many channels of audio this handler computes. This should be 1, 2, 4, or 8. (8 requires Irix 6.3 or later; Windows requires 1 or 2.) Most handlers default to 1, or, if they listen with SetInput, their input's number of channels. A handler can have a different number of channels than the number of channels VSS itself is running at (although more channels is inefficient and doubtfully useful).
SetChannel hSound n
Override any SetPan/SetElev/SetDistance for this sound, and simply assign it to channel number n. The value of n should range from zero to one less than the number of channels VSS is running at. This is useful if the loudspeakers aren't arranged in a spatial array and need to be addressed individually.
SetChannelAmps hSound [amp0 amp1 ...]
Override any SetPan/SetElev/SetDistance for this sound, and set the amount of sound to be sent to each speaker individually (0 = silence, 1 = nominal). The number of amplitudes specified in the array must equal the number of channels VSS is running at. Useful for implementing custom spatialization algorithms or for unusual speaker locations.

Extra messages for handlers of processor actors

SetInputAmp hActor x time
Set the default input scaling to x (0 = silence, unity = nominal). Default is nominal. If time is specified, modulate to the new value over the specified duration.
SetInputGain hActor x time
Set the default input scaling in decibels to x (-100 or less = silence, 0 = nominal). Default is nominal. If time is specified, modulate to the new value over the specified duration.

These messages are summarized in the following slightly obsolete diagram, drawn to resemble an audio mixing console.

Every "sound", i.e., handler of a generator actor, runs unless it got a SetPause message (taking a union break during a rehearsal). If it's not paused, it normally outputs to VSS's "main bus." But this can be interrupted with the SetMute message, for instance if you want to use only the "side" output which other actors (processor actors, typically) can grab with a SetInput message. Two independent gain controls are provided, so you can for example control them independently from two message groups. Finally, SetPan (and SetElev) sets the relative levels going to each channel of VSS's audio output (the "main bus"). The number of channels here can be one, two or four, set by the "-chans" command-line argument or from the control panel.

Speaker placement for multichannel output

Message reference, by actor

Credits