OpenAL Feature Pit


  I'm dedicating this page to collecting all the ideas, philosophy, features, wishes and otherwise wordly things others and me have about the design of OpenAL. At the end of this list, I've included the text that Terry Sikes sent me when I joined. We'll see if we deviate from it or not. It does make a very good start.


  • Ramps, envelopes and otherwise, user-defined, smooth modifications to sound parameters like volume, pitch and panning. Ideas: linear ramps, polygonal ramps, and user-defined envelopes. We should explore here what's important and what's not. This is very much affected by how the discussion on how complex we should make the API.


   This is the original spec, as sent to me by Terry Sikes (I'm sorry for all those places where the source-code tabulations were lost. ForntPage Express woes...):

Open Audio Library Requirements

Mission Statement: The Open Audio Library (OpenAL) is intended to provide an open, cross-platform audio capability suitable for professional game development purposes (it may well be applicable to many other application domains). It is a mid-level library primarily intended to sit on top of existing low-level sound APIs. Initial implementations will focus on sound output capabilities (sampled, MIDI and CD audio), but the architecture will be flexible enough to handle sound input as well.

OpenAL uses a C API for portability and cross-language capability.

OpenAL is thread safe on those platforms that support threads.

OpenAL calls native libraries when possible.

OpenAL uses sound format(s) native to the target platform. Possibly support for a single cross-platform format could be provided later.

OpenAL provides mixing of sampled audio. Maximum number of channels should be queryable.

OpenAL provides the following 2D capabilities for mixed sampled sounds:

  • Volume control
  • Panning
  • Looping
  • Priority

OpenAL provides the following 3D capabilities for mixed sampled sounds:

  • Absolute volume control
  • 3D position relative to listener
  • Velocity relative to listener (Doppler)
  • Looping
  • Priority

OpenAL supports MIDI and CD audio playback.

All outputs may be queried for current status information.

Open Audio API

This is a first cut at a possible 2D audio interface.

/* Types */

OA_ENGINE_STATE /* Struct containing state information for sound */
                /* engine. */
OA_INIT_INFO /* Struct containing initialization information. */
             /* In particular, it may provide/return information */
             /* about system latency/performance/outputs. */
OA_OUTPUT /* Struct containing all information pertaining to */
          /* a particular sound output. Examples of sound */
          /* outputs include hardware mixers, software mixers, */
          /* and MIDI playback devices. */
OA_INPUT /* Struct containing all information pertaining to */
         /* a particular sound input. Examples of sound inputs */
         /* include audio samples and MIDI streams. */
OA_SOUND /* Struct containing in-memory representation of */
         /* a sound */
         /* sample, as well as state information for that */
         /* sound. */

/* Initialize Open Audio system.
INT32 oaInitEngine(OA_ENGINE_STATE &state, OA_INIT_INFO &initInfo);

/* Open an audio output. Default behavior would be to get the "best"
output device (possibly user preference) capable of playing that type of
sound. Digital audio and MIDI would be initially supported.
outputType could be MIDI or SAMPLED.
Perhaps we need something like:
oaSetOutputPreference(&output, 16_BIT_32_VOICE_MIN);
to specify specific minimum requirements etc. Also, what are the issues
with multiple soundcards? Should we provide an enumeration function?
INT32 oaOpenOutput(OA_ENGINE_STATE &state, OA_OUTPUT &output, INT32 outputType);

/* Clean up and release all resources associated with this output.
INT32 oaCloseOutput(OA_OUTPUT &output);

/* Set overall output volume.
0 is minimum, 10000 is maximum.
INT32 oaOutputVolume(OA_OUTPUT &output, INT32 volume);

/* Set overall output pan.
-10000 is full left, 10000 is full right.
INT32 oaOutputPan(OA_OUTPUT &output, INT32 panLevel);

/* Open a sound independent of a specific output.
Flags include:
OA_CACHE - cache sound into memory if applicable
This should probably be reference counted, so it can't be destroyed while
sound instances are playing.
The final OA_OUTPUT handle
INT32 oaOpenInput(OA_INPUT &soundInput, char *soundPath, INT32 soundType, INT32 flags);

/* Hint that the sound input should be hardware accelerated if possible
on a particular output device.
INT32 oaOptimizeInput(OA_OUTPUT &output, OA_INPUT &input);

/* Close a sound input.
INT32 oaCloseInput(OA_INPUT &soundInput);

/* Create a sound instance, using a particular input and output.
INT32 oaCreateSound(OA_SOUND &sound, OA_OUTPUT &output, OA_INPUT &input);

/* Play a sound on the mixer.
Priorities range from 0 (highest) to 32 (lowest)
Flag bits include OA_LOOP, flag indicating that sound should be looped
until stopped.
INT32 oaPlaySound(OA_SOUND &sound);

/* Change the volume of this sound.
volume of 0 is silent, 10000 is maximum (linear scale).
INT32 oaSetVolume(OA_SOUND &sound, INT32 volume);

/* Pan the sound.
panLevel of -10000 is fully panned left, 10000 is fully right.
INT32 oaSetPan(OA_SOUND &sound, INT32 panLevel);

/* Stop a sound that's currently playing.
INT32 oaStopSound(OA_SOUND &sound);

/* Returns current volume of sound.
INT32 oaGetVolume(OA_SOUND &sound);

/* Returns current pan position of sound.
INT32 oaGetPan(OA_SOUND &sound);

/* Returns current mixer position in the sound in ms.
-1 if sound is not playing.
INT32 oaGetSoundPos(OA_SOUND &sound);

/* Returns length of the sound in ms.
INT32 oaGetSoundLen(OA_SOUND &sound);

/* Returns current sound priority.
INT32 oaGetSoundPriority(OA_SOUND &sound);

/* Check on sampled sound output status.
OA_SAMPLED_STATUS needs to be defined.
Some of the information returned should include:
Number of samples currently playing.
Number of total channels available.
What else?
INT32 oaSampledOutputStatus(OA_OUTPUT &output, OA_SAMPLED_STATUS &status);

/* Sound mixing engine.
Must be called with a certain frequency (as reported by oaInit())
to ensure that artifacts aren't heard, and maximum latency is
satisfied. Should be able to reside on separate thread from rest
of program, in multithreaded environments.
INT32 oaSoundEngine(OA_ENGINE_STATE &state);

Usage Example

INT32 channels[CHANNEL_COUNT] = { /* Rest of mixer channels */
3, 4, 2, 2 /* to floating pool. */
/* Channel 0 is floating pool, */
/* channel assignments are one based. */

int main(int argc, char *argv[]) {
OA_STATE state;
OA_INIT_INFO initInfo;
OA_OUTPUT mixer;
OA_INPUT dingFile;
OA_SOUND ding;
/* Somewhere during initialization... */
status = oaInit(&state, &initInfo);
status = oaOpenOutput(&state, &mixer, OA_WAVE_OUTPUT);
status = oaDefineChannels(&mixer, &channels, CHANNEL_COUNT);
status = oaOpenInput(&dingFile, "ding.wav", OA_WAVE_SOUND, OA_CACHE);
status = oaOptimizeInput(&dingFile, &mixer); /* Hardware mix if possible */
status = oaCreateSound(&ding, &mixer, &dingFile); /* Error if mismatch. */
/* Sets prio 16, */
/* channel floating pool */
/* by default. */
status = oaPriority(&ding, 24);
status = oaChannel(&ding, 3);
oaSetVolume(&ding, 7000);
status = oaPlaySound(&ding); /* prio 24, channel 3 */
/* Perhaps on another thread... */
status = oaSoundEngine(&state);

/* Play MIDI */
status = oaOpenOutput(&state, &midi, OA_MIDI_OUTPUT);
status = oaOpenInput(&jamFile, "jam.mid", OA_MIDI_SOUND, 0);
status = oaCreateSound(&jam, &midi, &jamFile);
oaSetVolume(&jam, 5000);
status = oaPlaySound(&jam);
return (0);

All trademarked things I mention here are TM by their respective owners. If you are one of those owners and want to be specifically mentioned, please, contact me and I'll include it.

Go back to the directory of
OpenAL pages
Go back to the directory of
Programming pages
Go back to the main directory of
JCAB's Rumblings
To contact JCAB:
Ronin Entertainment home page:
Last updated:
04 Apr 1999