1 Example: Playing sound from a raw buffer
2 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
3 Device and context management
open-device
close-device!
create-context
set-current-context
get-current-context
get-device-from-context
destroy-context!
get-last-error
4 Buffers
gen-buffers
delete-buffers!
buffer?
buffer-data
4.1 Buffer properties
4.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
4.1.2 Friendly buffer getters and setters
buffer-frequency
buffer-bits
buffer-channels
buffer-size
5 Sources
gen-sources
delete-sources!
play-source
pause-source
stop-source
rewind-source
5.1 Source properties
5.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
5.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
6 Listener properties
6.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
6.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
7 Streaming sound
source-queue-buffers!
source-unqueue-buffers!
stream-port-to-source
8 Distance models
set-distance-model!
set-doppler-factor!
set-speed-of-sound!
9 License

OpenAL: Bindings for the OpenAL sound library

gcr

 (require (planet gcr/openal:1:=5))
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 Constants

    3 Device and context management

    4 Buffers

      4.1 Buffer properties

        4.1.1 C-level buffer getters and setters

        4.1.2 Friendly buffer getters and setters

    5 Sources

      5.1 Source properties

        5.1.1 C-like source getters and setters

        5.1.2 Friendly source getters and setters

    6 Listener properties

      6.1 C-like listener getters and setters

      6.2 Friendly listener getters and setters

    7 Streaming sound

    8 Distance models

    9 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 (planet gcr/openal))
 
;; 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 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.

AL_BITS : exact-integer?
AL_BUFFER : exact-integer?
AL_BUFFERS_PROCESSED : exact-integer?
AL_BUFFERS_QUEUED : exact-integer?
AL_BYTE_OFFSET : exact-integer?
AL_CHANNELS : exact-integer?
AL_CONE_INNER_ANGLE : exact-integer?
AL_CONE_OUTER_ANGLE : exact-integer?
AL_CONE_OUTER_GAIN : exact-integer?
AL_DIRECTION : exact-integer?
AL_DISTANCE_MODEL : exact-integer?
AL_DOPPLER_FACTOR : exact-integer?
AL_DOPPLER_VELOCITY : exact-integer?
AL_EXPONENT_DISTANCE : exact-integer?
AL_EXPONENT_DISTANCE_CLAMPED : exact-integer?
AL_EXTENSIONS : exact-integer?
AL_FALSE : exact-integer?
AL_FORMAT_MONO16 : exact-integer?
AL_FORMAT_MONO8 : exact-integer?
AL_FORMAT_STEREO16 : exact-integer?
AL_FORMAT_STEREO8 : exact-integer?
AL_FREQUENCY : exact-integer?
AL_GAIN : exact-integer?
AL_ILLEGAL_COMMAND : exact-integer?
AL_ILLEGAL_ENUM : exact-integer?
AL_INITIAL : exact-integer?
AL_INVALID : exact-integer?
AL_INVALID_ENUM : exact-integer?
AL_INVALID_NAME : exact-integer?
AL_INVALID_OPERATION : exact-integer?
AL_INVALID_VALUE : exact-integer?
AL_INVERSE_DISTANCE : exact-integer?
AL_INVERSE_DISTANCE_CLAMPED : exact-integer?
AL_LINEAR_DISTANCE : exact-integer?
AL_LINEAR_DISTANCE_CLAMPED : exact-integer?
AL_LOOPING : exact-integer?
AL_MAX_DISTANCE : exact-integer?
AL_MAX_GAIN : exact-integer?
AL_MIN_GAIN : exact-integer?
AL_NO_ERROR : exact-integer?
AL_NONE : exact-integer?
AL_ORIENTATION : exact-integer?
AL_OUT_OF_MEMORY : exact-integer?
AL_PAUSED : exact-integer?
AL_PENDING : exact-integer?
AL_PITCH : exact-integer?
AL_PLAYING : exact-integer?
AL_POSITION : exact-integer?
AL_PROCESSED : exact-integer?
AL_REFERENCE_DISTANCE : exact-integer?
AL_RENDERER : exact-integer?
AL_ROLLOFF_FACTOR : exact-integer?
AL_SAMPLE_OFFSET : exact-integer?
AL_SEC_OFFSET : exact-integer?
AL_SIZE : exact-integer?
AL_SOURCE_RELATIVE : exact-integer?
AL_SOURCE_STATE : exact-integer?
AL_SOURCE_TYPE : exact-integer?
AL_SPEED_OF_SOUND : exact-integer?
AL_STATIC : exact-integer?
AL_STOPPED : exact-integer?
AL_STREAMING : exact-integer?
AL_TRUE : exact-integer?
AL_UNDETERMINED : exact-integer?
AL_UNUSED : exact-integer?
AL_VELOCITY : exact-integer?
AL_VENDOR : exact-integer?
AL_VERSION : exact-integer?

3 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.

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

(close-device! device)  bool?
  device : any/c
Closes an OpenAL device.

(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.

(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.

Returns the current device context.

(get-device-from-context context)  any/c
  context : any/c
Returns the device that the given context applies to.

(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.

4 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.

(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.

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

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

(buffer-data bufid format data frequency)  any/c
  bufid : exact-integer?
  format : 
(one-of/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.

4.1 Buffer properties

4.1.1 C-level buffer getters and setters

(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.
(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.
(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.
(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.
(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.
(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.

(alGetBufferf buffer param)  real?
  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.
(alGetBuffer3f buffer param)  (list/c real? real? real?)
  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.
(alGetBufferfv buffer param)  (listof real?)
  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.
(alGetBufferi buffer param)  exact-integer?
  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.
(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.
(alGetBufferiv buffer param)  (listof exact-integer?)
  buffer : exact-integer?
  param : exact-integer?
Gets the given param of the given buffer.

4.1.2 Friendly buffer getters and setters

(buffer-frequency buffer)  exact-integer?
  buffer : exact-integer?
Retrieves the given buffer’s frequency, in Hz.
(buffer-bits buffer)  exact-integer?
  buffer : exact-integer?
Retrieves the given buffer’s bit depth.
(buffer-channels buffer)  exact-integer?
  buffer : exact-integer?
Retrieves the number of channels in buffer – 1 for mono, 2 for stereo.
(buffer-size buffer)  exact-integer?
  buffer : exact-integer?
Retrieves the size of the buffer in bytes.

5 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).

(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!

(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.

(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.

(pause-source source)  any/c
  source : exact-integer?
Stops playing the source.
(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.
(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.

5.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.

5.1.1 C-like source getters and setters

(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.
(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.
(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.
(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.
(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.
(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.

(alGetSourcef source param)  real?
  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.
(alGetSource3f source param)  (list/c real? real? real?)
  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.
(alGetSourcefv source param)  (listof real?)
  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.
(alGetSourcei source param)  exact-integer?
  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.
(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.
(alGetSourceiv source param)  (listof exact-integer?)
  source : exact-integer?
  param : exact-integer?
Gets the given param of the given source.

5.1.2 Friendly source getters and setters

(set-source-pitch! source value)  any/c
  source : exact-integer?
  value : real?
(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.
(set-source-gain! source value)  any/c
  source : exact-integer?
  value : real?
(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! }

(set-source-rolloff-factor! source value)  any/c
  source : exact-integer?
  value : real?
(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.
(set-source-reference-distance! source    
  value)  any/c
  source : exact-integer?
  value : real?
(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.
(set-source-min-gain! source value)  any/c
  source : exact-integer?
  value : real?
(source-min-gain source)  real?
  source : exact-integer?
(set-source-max-gain! source value)  any/c
  source : exact-integer?
  value : real?
(source-max-gain source)  real?
  source : exact-integer?
(set-source-max-distance! source value)  any/c
  source : exact-integer?
  value : real?
(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.

(set-source-cone-outer-gain! source value)  any/c
  source : exact-integer?
  value : real?
(source-cone-outer-gain source)  real?
  source : exact-integer?
(set-source-cone-inner-angle! source value)  any/c
  source : exact-integer?
  value : real?
(source-cone-inner-angle source)  real?
  source : exact-integer?
(set-source-cone-outer-angle! source value)  any/c
  source : exact-integer?
  value : real?
(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

(set-source-position! source x y z)  any/c
  source : exact-integer?
  x : real?
  y : real?
  z : real?
(source-position source)  (list/c real? real? real?)
  source : exact-integer?
(set-source-direction! source x y z)  any/c
  source : exact-integer?
  x : real?
  y : real?
  z : real?
(source-direction source)  (list/c real? real? real?)
  source : exact-integer?
(set-source-velocity! source x y z)  any/c
  source : exact-integer?
  x : real?
  y : real?
  z : real?
(source-velocity source)  (list/c real? real? real?)
  source : exact-integer?
Gets or sets the source’s position, velocity, and direction in 3D space.

(set-source-source-relative! source value)  any/c
  source : exact-integer?
  value : (one-of/c 0 1)
(source-source-relative source)  (one-of/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.

(set-source-looping! source value)  any/c
  source : exact-integer?
  value : (one-of/c 0 1)
(source-looping source)  (one-of/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.
(set-source-buffer! source buffer)  any/c
  source : exact-integer?
  buffer : exact-integer?
(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).

Returns the state of a source. Use play-source, stop-source, pause-source to change.
For streaming sources, returns how many buffers are in the source’s buffer queue. Includes both processed and yet-to-be-processed buffers.
For streaming sources, returns how many buffers in the source’s buffer queue were processed.
(source-sec-offset source)  real?
  source : exact-integer?
Returns how many seconds the source is in its buffer.
(source-sample-offset source)  exact-integer?
  source : exact-integer?
Returns how many samples the source is in its buffer.
(source-byte-offset source)  exact-integer?
  source : exact-integer?
Returns how many bytes the source is in its buffer.

6 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.

6.1 C-like listener getters and setters

(alListenerf param value)  any/c
  param : exact-integer?
  value : real?
Sets the given param of the listener to the given value.
(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.
(alListenerfv param values)  any/c
  param : exact-integer?
  values : (listof real?)
Sets the given param of the listener to the given values.
(alListeneri param value)  any/c
  param : exact-integer?
  value : exact-integer?
Sets the given param of the listener to the given value.
(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.
(alListeneriv param values)  any/c
  param : exact-integer?
  values : (listof exact-integer?)
Sets the given param of the listener to the given values.

(alGetListenerf param)  real?
  param : exact-integer?
Gets the given param of the listener.
(alGetListener3f param)  (list/c real? real? real?)
  param : exact-integer?
Gets the given param of the listener.
(alGetListenerfv param)  (listof real?)
  param : exact-integer?
Gets the given param of the listener.
(alGetListeneri param)  exact-integer?
  param : exact-integer?
Gets the given param of the listener.
Gets the given param of the listener.
(alGetListeneriv param)  (listof exact-integer?)
  param : exact-integer?
Gets the given param of the listener.

6.2 Friendly listener getters and setters

(set-listener-gain! value)  any/c
  value : real?
(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.

(set-listener-position! x y z)  any/c
  x : real?
  y : real?
  z : real?
(listener-position)  (list/c real? real? real?)
(set-listener-velocity! x y z)  any/c
  x : real?
  y : real?
  z : real?
(listener-velocity)  (list/c real? real? real?)
(set-listener-orientation! x y z)  any/c
  x : real?
  y : real?
  z : real?
(listener-orientation)  (list/c real? real? real?)
Sets the listener’s position, velocity, and orientation in 3D space.

7 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.

(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.

(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.

(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 : 
(one-of/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.

8 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.

(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.
(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.

9 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.