Open  AL:   Bindings for the Open  AL sound library
1 Example:   Playing sound from a raw buffer
2 Example:   Playing OGG Vorbis Files
3 Constants
AL_  BITS
AL_  BUFFER
AL_  BUFFERS_  PROCESSED
AL_  BUFFERS_  QUEUED
AL_  BYTE_  OFFSET
AL_  CHANNELS
AL_  CONE_  INNER_  ANGLE
AL_  CONE_  OUTER_  ANGLE
AL_  CONE_  OUTER_  GAIN
AL_  DIRECTION
AL_  DISTANCE_  MODEL
AL_  DOPPLER_  FACTOR
AL_  DOPPLER_  VELOCITY
AL_  EXPONENT_  DISTANCE
AL_  EXPONENT_  DISTANCE_  CLAMPED
AL_  EXTENSIONS
AL_  FALSE
AL_  FORMAT_  MONO16
AL_  FORMAT_  MONO8
AL_  FORMAT_  STEREO16
AL_  FORMAT_  STEREO8
AL_  FREQUENCY
AL_  GAIN
AL_  ILLEGAL_  COMMAND
AL_  ILLEGAL_  ENUM
AL_  INITIAL
AL_  INVALID
AL_  INVALID_  ENUM
AL_  INVALID_  NAME
AL_  INVALID_  OPERATION
AL_  INVALID_  VALUE
AL_  INVERSE_  DISTANCE
AL_  INVERSE_  DISTANCE_  CLAMPED
AL_  LINEAR_  DISTANCE
AL_  LINEAR_  DISTANCE_  CLAMPED
AL_  LOOPING
AL_  MAX_  DISTANCE
AL_  MAX_  GAIN
AL_  MIN_  GAIN
AL_  NO_  ERROR
AL_  NONE
AL_  ORIENTATION
AL_  OUT_  OF_  MEMORY
AL_  PAUSED
AL_  PENDING
AL_  PITCH
AL_  PLAYING
AL_  POSITION
AL_  PROCESSED
AL_  REFERENCE_  DISTANCE
AL_  RENDERER
AL_  ROLLOFF_  FACTOR
AL_  SAMPLE_  OFFSET
AL_  SEC_  OFFSET
AL_  SIZE
AL_  SOURCE_  RELATIVE
AL_  SOURCE_  STATE
AL_  SOURCE_  TYPE
AL_  SPEED_  OF_  SOUND
AL_  STATIC
AL_  STOPPED
AL_  STREAMING
AL_  TRUE
AL_  UNDETERMINED
AL_  UNUSED
AL_  VELOCITY
AL_  VENDOR
AL_  VERSION
4 Device and context management
open-device
open-capture-device
close-device!
close-capture-device!
create-context
set-current-context
get-current-context
get-device-from-context
destroy-context!
get-last-error
start-capture
stop-capture
capture-samples
5 Buffers
gen-buffers
delete-buffers!
buffer?
buffer-data
5.1 Buffer properties
5.1.1 C-level buffer getters and setters
al  Bufferf
al  Buffer3f
al  Bufferfv
al  Bufferi
al  Buffer3i
al  Bufferiv
al  Get  Bufferf
al  Get  Buffer3f
al  Get  Bufferfv
al  Get  Bufferi
al  Get  Buffer3i
al  Get  Bufferiv
5.1.2 Friendly buffer getters and setters
buffer-frequency
buffer-bits
buffer-channels
buffer-size
6 Sources
gen-sources
delete-sources!
play-source
pause-source
stop-source
rewind-source
6.1 Source properties
6.1.1 C-like source getters and setters
al  Sourcef
al  Source3f
al  Sourcefv
al  Sourcei
al  Source3i
al  Sourceiv
al  Get  Sourcef
al  Get  Source3f
al  Get  Sourcefv
al  Get  Sourcei
al  Get  Source3i
al  Get  Sourceiv
6.1.2 Friendly source getters and setters
set-source-pitch!
source-pitch
set-source-gain!
source-gain
set-source-rolloff-factor!
source-rolloff-factor
set-source-reference-distance!
source-reference-distance
set-source-min-gain!
source-min-gain
set-source-max-gain!
source-max-gain
set-source-max-distance!
source-max-distance
set-source-cone-outer-gain!
source-cone-outer-gain
set-source-cone-inner-angle!
source-cone-inner-angle
set-source-cone-outer-angle!
source-cone-outer-angle
set-source-position!
source-position
set-source-direction!
source-direction
set-source-velocity!
source-velocity
set-source-source-relative!
source-source-relative
source-source-type
set-source-looping!
source-looping
set-source-buffer!
source-buffer
source-source-state
source-buffers-queued
source-buffers-processed
source-sec-offset
source-sample-offset
source-byte-offset
7 Listener properties
7.1 C-like listener getters and setters
al  Listenerf
al  Listener3f
al  Listenerfv
al  Listeneri
al  Listener3i
al  Listeneriv
al  Get  Listenerf
al  Get  Listener3f
al  Get  Listenerfv
al  Get  Listeneri
al  Get  Listener3i
al  Get  Listeneriv
7.2 Friendly listener getters and setters
set-listener-gain!
listener-gain
set-listener-position!
listener-position
set-listener-velocity!
listener-velocity
set-listener-orientation!
listener-orientation
8 Streaming sound
source-queue-buffers!
source-unqueue-buffers!
stream-port-to-source
9 Distance models
set-distance-model!
set-doppler-factor!
set-speed-of-sound!
10 License
6.12

OpenAL: Bindings for the OpenAL sound library

gcr

libopenal-racket is a fork of (planet gcr/openal). This library provides low-level bindings for the OpenAL sound library. Because these bindings are low-level, you may want to look at the OpenAL Programmer’s Guide to get a sense of how it works.

    1 Example: Playing sound from a raw buffer

    2 Example: Playing OGG Vorbis Files

    3 Constants

    4 Device and context management

    5 Buffers

      5.1 Buffer properties

        5.1.1 C-level buffer getters and setters

        5.1.2 Friendly buffer getters and setters

    6 Sources

      6.1 Source properties

        6.1.1 C-like source getters and setters

        6.1.2 Friendly source getters and setters

    7 Listener properties

      7.1 C-like listener getters and setters

      7.2 Friendly listener getters and setters

    8 Streaming sound

    9 Distance models

    10 License

1 Example: Playing sound from a raw buffer

In this example, we play an 8-bit sine wave generated from a bytestring.

#lang racket
(require libopenal/racket)
 
;; Our sound data
(define sinewave
  (list->bytes
   (for/list ([i (in-range 0 (* 2 pi) 0.07)])
     (inexact->exact
       (floor
         (+ 128
            (* (sin i) 64)))))))

First, we must open the sound device and create a context for it:

;; Initialize OpenAL (see the OpenAL guide)
(define device (open-device #f))
(define context (create-context device))
(set-current-context context)

Once we have a device context, we must create a buffer to hold our sound data.

;; Make our OpenAL buffer
(define buffer (car (gen-buffers 1)))
;; Copy the bytes to this buffer
(buffer-data buffer
             AL_FORMAT_MONO8
             sinewave
             44100)

In this example, each unsigned byte of sinewave is a separate 8-bit sound sample. Realistically, a real-world application would want to use 16-bit samples, but this grainy, ugly example is fine for us.

Once our data is safe in an OpenAL buffer, we make a source and play it. Note that OpenAL internally copies that data – we are free to mutate it however we like after the call to buffer-data.

;; Make our OpenAL source
(define source (car (gen-sources 1)))
 
;; Bind our buffer to the source -- 8-bit mono
(set-source-buffer! source buffer)

OpenAL allows us to define several simultaneously playing sources. Though a single source can only have one buffer, note that a buffer can be bound to several sources at the same time to save space.

Now that we have a source and a sound buffer to play, we can set our source to play the data from the sound buffer.

;; Loop forever (without this, the source will play just once and then stop)
(set-source-looping! source AL_TRUE)
 
;; Start playing
(play-source source)

OpenAL uses a separate OS-level thread to play sounds. The play-source call will exit instantly and our sound will continue to play in the background until we choose to stop it.

;; Wait until we're fisished playing
(sleep 5)
 
;; Clean up
(delete-sources! (list source))
(delete-buffers! (list buffer))
(set-current-context #f)
(destroy-context! context)
(close-device! device)

2 Example: Playing OGG Vorbis Files

OpenAL works great with the (planet gcr/libvorbisfile) package, and this is no accident. This example shows you how to stream a vorbis file straight to an OpenAL source without loading it into a buffer like we did above.

First, we must dig out the spellbook and incant the OpenAL Summoning Mantra:

#lang racket
(require libopenal-racket
         (planet gcr/libvorbisfile))
 
;; Initialize OpenAL (see the docs for libopenal-racket)
(define device (open-device #f))
(define context (create-context device))
(set-current-context context)

From here, it’s not rocket science to open a vorbis file and query basic information about it.

(define filename "/home/gcr/Music/Lights/Siberia/11 Flux and Flow.ogg")
(printf "Playing file ~a\n" filename)
 
(define m (open-vorbis-file filename))

To read the sound data, we use libvorbisfile’s make-vorbis-input-port function to create a port that decodes the sound data into binary bytes on-demand.

;; To read the PCM  samples, we make a port that supplies us with
;; the binary decompressed data.
(define vorbis-binary (make-vorbis-input-port m 0 2 1))
;; OpenAL expects:
;; 0 (Little-endian)
;; 2 (Word size; 16 bits)
;; 1 (Signed)

Now that we have a port that gives us raw sample data, we can stream it straight to an OpenAL source. This avoids reading the entire file into memory – each block of sound is decoded right as it’s needed.

;; Make our OpenAL source
(define source (car (gen-sources 1)))
 
;; Start streaming
(define stream-thread
  (stream-port-to-source vorbis-binary
                         source
                         AL_FORMAT_STEREO16
                         (vorbis-frequency m)))
 
;; Start playing
(play-source source)
 
;; OpenAL's stream-port-to-source returns a thread, so wait until we're
;; finished playing
(thread-wait stream-thread)

Once we’re done, we should clean up our OpenAL mess:

(set-current-context #f)
(destroy-context! context)
(close-device! device)

You should probably close the vorbis file when you’re finished.

(close-vorbis-file! m)

3 Constants

All constants defined in al.h and alc.h are re-exported under their usual names. See the OpenAL Programmer’s Guide for information about what each constant means.

value

AL_BITS : exact-integer?

value

AL_BUFFER : exact-integer?

value

AL_BUFFERS_PROCESSED : exact-integer?

value

AL_BUFFERS_QUEUED : exact-integer?

value

AL_BYTE_OFFSET : exact-integer?

value

AL_CHANNELS : exact-integer?

value

AL_CONE_INNER_ANGLE : exact-integer?

value

AL_CONE_OUTER_ANGLE : exact-integer?

value

AL_CONE_OUTER_GAIN : exact-integer?

value

AL_DIRECTION : exact-integer?

value

AL_DISTANCE_MODEL : exact-integer?

value

AL_DOPPLER_FACTOR : exact-integer?

value

AL_DOPPLER_VELOCITY : exact-integer?

value

AL_EXPONENT_DISTANCE : exact-integer?

value

AL_EXPONENT_DISTANCE_CLAMPED : exact-integer?

value

AL_EXTENSIONS : exact-integer?

value

AL_FALSE : exact-integer?

value

AL_FORMAT_MONO16 : exact-integer?

value

AL_FORMAT_MONO8 : exact-integer?

value

AL_FORMAT_STEREO16 : exact-integer?

value

AL_FORMAT_STEREO8 : exact-integer?

value

AL_FREQUENCY : exact-integer?

value

AL_GAIN : exact-integer?

value

AL_ILLEGAL_COMMAND : exact-integer?

value

AL_ILLEGAL_ENUM : exact-integer?

value

AL_INITIAL : exact-integer?

value

AL_INVALID : exact-integer?

value

AL_INVALID_ENUM : exact-integer?

value

AL_INVALID_NAME : exact-integer?

value

AL_INVALID_OPERATION : exact-integer?

value

AL_INVALID_VALUE : exact-integer?

value

AL_INVERSE_DISTANCE : exact-integer?

value

AL_INVERSE_DISTANCE_CLAMPED : exact-integer?

value

AL_LINEAR_DISTANCE : exact-integer?

value

AL_LINEAR_DISTANCE_CLAMPED : exact-integer?

value

AL_LOOPING : exact-integer?

value

AL_MAX_DISTANCE : exact-integer?

value

AL_MAX_GAIN : exact-integer?

value

AL_MIN_GAIN : exact-integer?

value

AL_NO_ERROR : exact-integer?

value

AL_NONE : exact-integer?

value

AL_ORIENTATION : exact-integer?

value

AL_OUT_OF_MEMORY : exact-integer?

value

AL_PAUSED : exact-integer?

value

AL_PENDING : exact-integer?

value

AL_PITCH : exact-integer?

value

AL_PLAYING : exact-integer?

value

AL_POSITION : exact-integer?

value

AL_PROCESSED : exact-integer?

value

AL_REFERENCE_DISTANCE : exact-integer?

value

AL_RENDERER : exact-integer?

value

AL_ROLLOFF_FACTOR : exact-integer?

value

AL_SAMPLE_OFFSET : exact-integer?

value

AL_SEC_OFFSET : exact-integer?

value

AL_SIZE : exact-integer?

value

AL_SOURCE_RELATIVE : exact-integer?

value

AL_SOURCE_STATE : exact-integer?

value

AL_SOURCE_TYPE : exact-integer?

value

AL_SPEED_OF_SOUND : exact-integer?

value

AL_STATIC : exact-integer?

value

AL_STOPPED : exact-integer?

value

AL_STREAMING : exact-integer?

value

AL_TRUE : exact-integer?

value

AL_UNDETERMINED : exact-integer?

value

AL_UNUSED : exact-integer?

value

AL_VELOCITY : exact-integer?

value

AL_VENDOR : exact-integer?

value

AL_VERSION : exact-integer?

4 Device and context management

With OpenAL, we must manage our own devices and our device contexts. It’s good practice to close all devices at the end of your program – some platforms may get confused.

procedure

(open-device devicename)  any/c

  devicename : (or/c string? #f)
Opens an OpenAL device. Pass #f to just use the default device.

procedure

(open-capture-device devicename    
  frequency    
  format    
  buffersize)  any/c
  devicename : (or/c string? #f)
  frequency : integer?
  format : 
(or/c AL_FORMAT_MONO8
      AL_FORMAT_MONO16
      AL_FORMAT_STEREO8
      AL_FORMAT_STEREO16)
  buffersize : integer?
Opens an OpenAL capture device. Pass #f to just use the default device.

frequency is the frequency at which the device should record, usually 44100.

format is the requested capture buffer format.

buffersize is the size of the capture buffer.

procedure

(close-device! device)  boolean?

  device : any/c
Closes an OpenAL device.

procedure

(close-capture-device! device)  boolean?

  device : any/c
Closes an OpenAL capture device.

procedure

(create-context device)  any/c

  device : any/c
Creates an OpenAL device context using a device. You must use set-current-context to make it active.

procedure

(set-current-context context)  any/c

  context : any/c
Sets the context to be the current context for the device. You must do this before you can play any sound.

procedure

(get-current-context)  any/c

Returns the current device context.

procedure

(get-device-from-context context)  any/c

  context : any/c
Returns the device that the given context applies to.

procedure

(destroy-context! context)  any/c

  context : any/c
Removes context from the device. Do not play any sounds after using this without reinstating another device context.

Returns (and clears) OpenAL’s last error. Will be 0 if there are no errors.

procedure

(start-capture device)  void?

  device : any/c
Begin a capture operation using device.

procedure

(stop-capture device)  void?

  device : any/c
Stop a capture operation on device.

procedure

(capture-samples device buffer samples)  void?

  device : any/c
  buffer : bytes?
  samples : integer?
Complete a capture operation, this does not block.

5 Buffers

OpenAL buffers hold sound data. They are kept in completely separate memory outside Racket’s garbage collection pool, so you must free buffers yourself when you’re finished with them to avoid memory leaks.

procedure

(gen-buffers num)  (listof exact-integer?)

  num : exact-integer?
Generates num buffers, and returns a list of the buffer IDs.

Once you have a buffer, you must load data with buffer-data, bind it to a source with set-source-buffer!, and then play the source with play-source. See the Example: Playing sound from a raw buffer section.

procedure

(delete-buffers! buffers)  any/c

  buffers : (listof exact-integer?)
Deletes the given buffers. Do not attempt to modify them after calling this function.

procedure

(buffer? buffer)  boolean?

  buffer : exact-integer?
Returns whether buffer is an OpenAL buffer.

procedure

(buffer-data bufid format data frequency)  any/c

  bufid : exact-integer?
  format : 
(or/c AL_FORMAT_MONO8
      AL_FORMAT_MONO16
      AL_FORMAT_STEREO8
      AL_FORMAT_STEREO16)
  data : bytes?
  frequency : exact-integer?
Loads the data in data to the given buffer with ID bufid.

Format should be an OpenAL constant signifying the format of the samples in data. For 8-bit formats, a value of 128 means no DC offset, with 0 and 255 being the extreme DC offsets. For 16-bit formats, samples are signed little-endian 16-bit integers. Stereo formats include interleaved samples, left first.

The frequency of the data is how many samples per second the source should play, usually 44100.

Note that data is automatically copied, not referenced – you can reuse or mutate data however you like after this call.

5.1 Buffer properties

5.1.1 C-level buffer getters and setters

procedure

(alBufferf buffer param value)  any/c

  buffer : exact-integer?
  param : exact-integer?
  value : real?
Sets the given param of the given buffer to the given value.

procedure

(alBuffer3f buffer param value1 value2 value3)  any/c

  buffer : exact-integer?
  param : exact-integer?
  value1 : real?
  value2 : real?
  value3 : real?
Sets the given param of the given buffer to the given values.

procedure

(alBufferfv buffer param values)  any/c

  buffer : exact-integer?
  param : exact-integer?
  values : (listof real?)
Sets the given param of the given buffer to the given values.

procedure

(alBufferi buffer param value)  any/c

  buffer : exact-integer?
  param : exact-integer?
  value : exact-integer?
Sets the given param of the given buffer to the given value.

procedure

(alBuffer3i buffer param value1 value2 value3)  any/c

  buffer : exact-integer?
  param : exact-integer?
  value1 : exact-integer?
  value2 : exact-integer?
  value3 : exact-integer?
Sets the given param of the given buffer to the given values.

procedure

(alBufferiv buffer param values)  any/c

  buffer : exact-integer?
  param : exact-integer?
  values : (listof exact-integer?)
Sets the given param of the given buffer to the given values.

procedure

(alGetBufferf buffer param)  real?

  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.

procedure

(alGetBuffer3f buffer param)  (list/c real? real? real?)

  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.

procedure

(alGetBufferfv buffer param)  (listof real?)

  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.

procedure

(alGetBufferi buffer param)  exact-integer?

  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.

procedure

(alGetBuffer3i buffer param)

  (list/c exact-integer? exact-integer? exact-integer?)
  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.

procedure

(alGetBufferiv buffer param)  (listof exact-integer?)

  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.

5.1.2 Friendly buffer getters and setters

procedure

(buffer-frequency buffer)  exact-integer?

  buffer : exact-integer?
Retrieves the given buffer’s frequency, in Hz.

procedure

(buffer-bits buffer)  exact-integer?

  buffer : exact-integer?
Retrieves the given buffer’s bit depth.

procedure

(buffer-channels buffer)  exact-integer?

  buffer : exact-integer?
Retrieves the number of channels in buffer – 1 for mono, 2 for stereo.

procedure

(buffer-size buffer)  exact-integer?

  buffer : exact-integer?
Retrieves the size of the buffer in bytes.

6 Sources

Sources are actual playing sounds in the world. Each source can either be bound to a single buffer or can contain a buffer queue that continuously streams sound data.

Sources have a 3D position and velocity in space. This means that OpenAL can optionally apply certain effects such as attenuation (softening far-away sounds) and pitch shifting (the doppler effect).

procedure

(gen-sources num-sources)  (listof exact-integer?)

  num-sources : exact-integer?
Generates a list of num-sources. Note that these will not be garbage-collected; you are responsible for freeing them yourself with delete-sources!

procedure

(delete-sources! sources)  any/c

  sources : (listof exact-integer?)
Stops and removes the listed sources. Do not attempt to use them after calling this function.

procedure

(play-source source)  any/c

  source : exact-integer?
Begins playing the source. Note that this function does not block – playback occurs in a separate OS-level thread. Use source-source-state to see whether a source is finished playing.

procedure

(pause-source source)  any/c

  source : exact-integer?
Stops playing the source.

procedure

(stop-source source)  any/c

  source : exact-integer?
Stops the source. Like pause-source, but this function rewinds it back to the beginning of its buffer.

procedure

(rewind-source source)  any/c

  source : exact-integer?
Like stop-source, but additionally sets the source’s state to AL_INITIAL. Your program can use this property to distinguish between sources that played and ended normally versus sources that stopped because of this function.

6.1 Source properties

These bindings define two “levels” of functions that set and retrieve properties. First, there are the low-level “C-like” functions like alSourcef that allow you to get and set individual properties of sources defined by an OpenAL constant. Alternatively, there are the friendlier functions like set-source-looping! that offer a simpler interface for setting the same properties.

6.1.1 C-like source getters and setters

procedure

(alSourcef source param value)  any/c

  source : exact-integer?
  param : exact-integer?
  value : real?
Sets the given param of the given source to the given value.

procedure

(alSource3f source param value1 value2 value3)  any/c

  source : exact-integer?
  param : exact-integer?
  value1 : real?
  value2 : real?
  value3 : real?
Sets the given param of the given source to the given values.

procedure

(alSourcefv source param values)  any/c

  source : exact-integer?
  param : exact-integer?
  values : (listof real?)
Sets the given param of the given source to the given values.

procedure

(alSourcei source param value)  any/c

  source : exact-integer?
  param : exact-integer?
  value : exact-integer?
Sets the given param of the given source to the given value.

procedure

(alSource3i source param value1 value2 value3)  any/c

  source : exact-integer?
  param : exact-integer?
  value1 : exact-integer?
  value2 : exact-integer?
  value3 : exact-integer?
Sets the given param of the given source to the given values.

procedure

(alSourceiv source param values)  any/c

  source : exact-integer?
  param : exact-integer?
  values : (listof exact-integer?)
Sets the given param of the given source to the given values.

procedure

(alGetSourcef source param)  real?

  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.

procedure

(alGetSource3f source param)  (list/c real? real? real?)

  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.

procedure

(alGetSourcefv source param)  (listof real?)

  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.

procedure

(alGetSourcei source param)  exact-integer?

  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.

procedure

(alGetSource3i source param)

  (list/c exact-integer? exact-integer? exact-integer?)
  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.

procedure

(alGetSourceiv source param)  (listof exact-integer?)

  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.

6.1.2 Friendly source getters and setters

procedure

(set-source-pitch! source value)  any/c

  source : exact-integer?
  value : real?

procedure

(source-pitch source)  real?

  source : exact-integer?
Gets or sets the source’s pitch, a number greater than 0. The default is 1.0. A value of 2.0 will make the sound play twice as fast and one octave higher; a value of 0.5 will make the sound go twice as slow and one octave lower.

procedure

(set-source-gain! source value)  any/c

  source : exact-integer?
  value : real?

procedure

(source-gain source)  real?

  source : exact-integer?
Gets or sets the source’s gain (volume), a number greater than 0. The default is 1.0. Note that values higher than 1 may cause clipping. Gain can also be set globally with set-listener-gain! }

procedure

(set-source-rolloff-factor! source value)  any/c

  source : exact-integer?
  value : real?

procedure

(source-rolloff-factor source)  real?

  source : exact-integer?
Gets or sets the rolloff rate of the source. See the Distance models section for more details.

procedure

(set-source-reference-distance! source    
  value)  any/c
  source : exact-integer?
  value : real?

procedure

(source-reference-distance source)  real?

  source : exact-integer?
Gets or sets the source’s reference distance, used for calculating the gain. See the Distance models section for more details.

procedure

(set-source-min-gain! source value)  any/c

  source : exact-integer?
  value : real?

procedure

(source-min-gain source)  real?

  source : exact-integer?

procedure

(set-source-max-gain! source value)  any/c

  source : exact-integer?
  value : real?

procedure

(source-max-gain source)  real?

  source : exact-integer?

procedure

(set-source-max-distance! source value)  any/c

  source : exact-integer?
  value : real?

procedure

(source-max-distance source)  real?

  source : exact-integer?
Gets or sets the source’s minimum and maximum gain and distance. See the Distance models section for more details.

procedure

(set-source-cone-outer-gain! source value)  any/c

  source : exact-integer?
  value : real?

procedure

(source-cone-outer-gain source)  real?

  source : exact-integer?

procedure

(set-source-cone-inner-angle! source value)  any/c

  source : exact-integer?
  value : real?

procedure

(source-cone-inner-angle source)  real?

  source : exact-integer?

procedure

(set-source-cone-outer-angle! source value)  any/c

  source : exact-integer?
  value : real?

procedure

(source-cone-outer-angle source)  real?

  source : exact-integer?
Gets or sets the parameters of an oriented sound cone around the source. See the OpenAL Programmer’s Guide

procedure

(set-source-position! source x y z)  any/c

  source : exact-integer?
  x : real?
  y : real?
  z : real?

procedure

(source-position source)  (list/c real? real? real?)

  source : exact-integer?

procedure

(set-source-direction! source x y z)  any/c

  source : exact-integer?
  x : real?
  y : real?
  z : real?

procedure

(source-direction source)  (list/c real? real? real?)

  source : exact-integer?

procedure

(set-source-velocity! source x y z)  any/c

  source : exact-integer?
  x : real?
  y : real?
  z : real?

procedure

(source-velocity source)  (list/c real? real? real?)

  source : exact-integer?
Gets or sets the source’s position, velocity, and direction in 3D space.

procedure

(set-source-source-relative! source value)  any/c

  source : exact-integer?
  value : (or/c 0 1)

procedure

(source-source-relative source)  (or/c 0 1)

  source : exact-integer?
Sets whether the source’s position is relative to the listener or an absolute position.

Returns the source’s type – AL_STATIC for buffered sources, AL_STREAMING for sources with buffer queues, and AL_UNDETERMINED for sources with unknown type.

procedure

(set-source-looping! source value)  any/c

  source : exact-integer?
  value : (or/c 0 1)

procedure

(source-looping source)  (or/c 0 1)

  source : exact-integer?
Gets or sets whether buffered sources should loop back to the beginning of the buffer upon completion. May misbehave on streaming sources.

procedure

(set-source-buffer! source buffer)  any/c

  source : exact-integer?
  buffer : exact-integer?

procedure

(source-buffer source)  exact-integer

  source : exact-integer?
Binds a source to a given buffer. This does not begin to play the source yet – use play-source to start.

If you want to build a streaming buffer, don’t use set-source-buffer! or else it may misbehave. You can, however, clear any queued buffers by running (set-source-buffer! source 0).

procedure

(source-source-state source)  
(or/c
 AL_STOPPED
 AL_PLAYING
 AL_PAUSED)
  source : exact-integer?
Returns the state of a source. Use play-source, stop-source, pause-source to change.

procedure

(source-buffers-queued source)  exact-integer?

  source : exact-integer?
For streaming sources, returns how many buffers are in the source’s buffer queue. Includes both processed and yet-to-be-processed buffers.

procedure

(source-buffers-processed source)  exact-integer?

  source : exact-integer?
For streaming sources, returns how many buffers in the source’s buffer queue were processed.

procedure

(source-sec-offset source)  real?

  source : exact-integer?
Returns how many seconds the source is in its buffer.

procedure

(source-sample-offset source)  exact-integer?

  source : exact-integer?
Returns how many samples the source is in its buffer.

procedure

(source-byte-offset source)  exact-integer?

  source : exact-integer?
Returns how many bytes the source is in its buffer.

7 Listener properties

The listener is the single entity in the world that listens for sound from all the sources. When the listener “hears” a source, it sends the output to the current sound device. The volume is adjusted based on the distance between the source and listener, and the sound’s pitch is adjusted based on the velocity and orientation thanks to the doppler effect.

7.1 C-like listener getters and setters

procedure

(alListenerf param value)  any/c

  param : exact-integer?
  value : real?
Sets the given param of the listener to the given value.

procedure

(alListener3f param value1 value2 value3)  any/c

  param : exact-integer?
  value1 : real?
  value2 : real?
  value3 : real?
Sets the given param of the listener to the given values.

procedure

(alListenerfv param values)  any/c

  param : exact-integer?
  values : (listof real?)
Sets the given param of the listener to the given values.

procedure

(alListeneri param value)  any/c

  param : exact-integer?
  value : exact-integer?
Sets the given param of the listener to the given value.

procedure

(alListener3i param value1 value2 value3)  any/c

  param : exact-integer?
  value1 : exact-integer?
  value2 : exact-integer?
  value3 : exact-integer?
Sets the given param of the listener to the given values.

procedure

(alListeneriv param values)  any/c

  param : exact-integer?
  values : (listof exact-integer?)
Sets the given param of the listener to the given values.

procedure

(alGetListenerf param)  real?

  param : exact-integer?
Gets the given param of the listener.

procedure

(alGetListener3f param)  (list/c real? real? real?)

  param : exact-integer?
Gets the given param of the listener.

procedure

(alGetListenerfv param)  (listof real?)

  param : exact-integer?
Gets the given param of the listener.

procedure

(alGetListeneri param)  exact-integer?

  param : exact-integer?
Gets the given param of the listener.

Gets the given param of the listener.

procedure

(alGetListeneriv param)  (listof exact-integer?)

  param : exact-integer?
Gets the given param of the listener.

7.2 Friendly listener getters and setters

procedure

(set-listener-gain! value)  any/c

  value : real?

procedure

(listener-gain)  real?

Gets and sets the global gain (master volume). Note that value should be a number greater than 0, with 1.0 being the default, 0.5 being half as loud, and so forth. Beware – numbers greater than 1 may cause clipping.

procedure

(set-listener-position! x y z)  any/c

  x : real?
  y : real?
  z : real?

procedure

(listener-position)  (list/c real? real? real?)

procedure

(set-listener-velocity! x y z)  any/c

  x : real?
  y : real?
  z : real?

procedure

(listener-velocity)  (list/c real? real? real?)

procedure

(set-listener-orientation! x y z)  any/c

  x : real?
  y : real?
  z : real?

procedure

(listener-orientation)  (list/c real? real? real?)

Sets the listener’s position, velocity, and orientation in 3D space.

8 Streaming sound

Each source usually has one buffer attached to it. If this were the only possible way of playing your sound, you would have to either load the entire sound into memory (imagine loading 90 minutes of raw sample data) or manage buffers yourselves, suffering through the inevitable clicks and hisses when OpenAL drains the buffer just before you can replace it.

Thankfully, OpenAL allows you to assign several buffers to a source using a queue of buffer objects. The sound will continue to play as long as there is a buffer left to play from. From time to time, your program should un-queue old buffers, refill them, and queue them at the end of the source’s queue.

You can either manage each source’s low-level buffer queue yourself or use the higher-level port streaming facilities to stream sounds straight from a Racket binary port.

procedure

(source-queue-buffers! source buffers)  any/c

  source : exact-integer?
  buffers : (listof/c exact-integer?)
Adds the given buffers to the end of the source’s buffer queue. You can check how many buffers are on the queue with source-buffers-queued and find how many buffers finished playing with source-buffers-processed.

If you intend to build a streaming source with a buffer queue, don’t call set-source-buffer!. Likewise, don’t use this function if you only want an ordinary source backed by a single buffer.

procedure

(source-unqueue-buffers! source buffers)  any/c

  source : exact-integer?
  buffers : (listof/c exact-integer?)
Removes the given buffers from source’s buffer queue. You can check how many buffers are on the queue with source-buffers-queued, and you can see how many buffers finished playing with source-buffers-processed.

procedure

(stream-port-to-source port    
  source    
  format    
  frequency    
  [at-end-of-loop    
  num-buffers    
  buffer-size    
  poll-interval    
  cleanup])  thread?
  port : port?
  source : exact-integer?
  format : 
(or/c AL_FORMAT_MONO8
      AL_FORMAT_MONO16
      AL_FORMAT_STEREO8
      AL_FORMAT_STEREO16)
  frequency : exact-integer?
  at-end-of-loop : (-> boolean?) = (λ() #f)
  num-buffers : exact-integer? = 5
  buffer-size : exact-integer? = (* 4096 8)
  poll-interval : real? = 0.1
  cleanup : (-> any/c) = (λ()(void))
Begins a background thread that streams the binary bytes from port to the given OpenAL source. This function does not block.

Every poll-interval seconds, the background thread will ensure that the source has num-buffers unprocessed buffers of at most buffer-size bytes each, and the thread will refill processed buffers as necessary to ensure gapless playback.

The port should yield bytes suitable for OpenAL playback, with the given format, and sample rate of frequency (typically 44100).

Just after the last buffer is queued, the thread will run the at-end-of-loop procedure which returns #t if the thread should continue or #f if it should stop once the last buffer finishes. You might use the at-end-of-loop function to seek the port back to the beginning of the file to seamlessly start playing back at the beginning of the file when reaching the end.

The thread will run the cleanup function just before exiting. Use this function to delete the allocated source, close the port, or perhaps to transition to a different screen in your application. Note that this may run up to poll-interval seconds after the sound actually finishes.

If you want to terminate the thread early, just run kill-thread on it. Cleanup will be run automatically.

9 Distance models

OpenAL defines several models that select how sound is attenuated (softened) over distance.

Sets the OpenAL distance model.

According to the OpenAL Programmer’s Guide, the inverse distance model works with this formula:

gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE +

          AL_ROLLOFF_FACTOR *

          (distance – AL_REFERENCE_DISTANCE));

Similarly, the Inverse Clamped Distance model works with this formula:

distance = max(distance,AL_REFERENCE_DISTANCE);

distance = min(distance,AL_MAX_DISTANCE);

gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE +

       AL_ROLLOFF_FACTOR *

       (distance – AL_REFERENCE_DISTANCE));

By contrast, the Linear Distance Model works according to the following formula:

distance = min(distance, AL_MAX_DISTANCE) // avoid negative gain

gain = (1 – AL_ROLLOFF_FACTOR * (distance –

       AL_REFERENCE_DISTANCE) /

       (AL_MAX_DISTANCE – AL_REFERENCE_DISTANCE))

And the Clamped Linear Distance Model works according to this formula:

distance = max(distance, AL_REFERENCE_DISTANCE)

distance = min(distance, AL_MAX_DISTANCE)

gain = (1 – AL_ROLLOFF_FACTOR * (distance –

        AL_REFERENCE_DISTANCE) /

        (AL_MAX_DISTANCE – AL_REFERENCE_DISTANCE))

The Exponential Distance Model works like this:

gain = (distance / AL_REFERENCE_DISTANCE) ^

                   (- AL_ROLLOFF_FACTOR)

The Clamped Exponential Distance model works like this:

distance = max(distance, AL_REFERENCE_DISTANCE)

distance = min(distance, AL_MAX_DISTANCE)

gain = (distance / AL_REFERENCE_DISTANCE) ^

                   (- AL_ROLLOFF_FACTOR)

Without any distance model, the gain remains fixed at 1.

procedure

(set-doppler-factor! value)  any/c

  value : real?
Sets the doppler factor. The default is 1.0. Use this to accentuate or reduce the doppler effect.

procedure

(set-speed-of-sound! value)  any/c

  value : real?
Sets the speed of sound for doppler effect calculations. The default is 343.3, which is good for units of meters and air as the propagation medium. Note that this does not delay sounds, OpenAL only uses this to calculate the doppler effect.

10 License

The code in this package and this documentation is under the zlib license, reproduced below. Keep in mind that OpenAL itself has many different implementations – some of which are proprietary to Creative Labs and some of which LGPL-licensed.

Copyright (c) 2012 gcr

 

This software is provided 'as-is', without any express or implied

warranty. In no event will the authors be held liable for any damages

arising from the use of this software.

 

Permission is granted to anyone to use this software for any purpose,

including commercial applications, and to alter it and redistribute it

freely, subject to the following restrictions:

 

   1. The origin of this software must not be misrepresented; you must not

   claim that you wrote the original software. If you use this software

   in a product, an acknowledgment in the product documentation would be

   appreciated but is not required.

 

   2. Altered source versions must be plainly marked as such, and must not be

   misrepresented as being the original software.

 

   3. This notice may not be removed or altered from any source

   distribution.