Home My Page Projects Code Snippets Project Openings 3D graphics for Standard ML
Summary Activity SCM

SCM Repository

[sml3d] View of /src/openal/al.sml
ViewVC logotype

View of /src/openal/al.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 141 - (download) (annotate)
Fri May 30 17:53:45 2008 UTC (11 years, 4 months ago) by jhr
File size: 13820 byte(s)
  Use ObjectIdFn functor to manage source IDs
(* al.sml
 *
 * COPYRIGHT (c) 2006 John Reppy (http://www.cs.uchicago.edu/~jhr)
 * All rights reserved.
 *)

structure AL :> AL =
  struct

  (* include common types *)
    open Types TypeUtil
    open ALConsts

  (* OpenAL types *)
    type source_id = word32
    type buffer_id = word32

  (*
   * Renderer State management.
   * NOTE: OpenAL 1.1 does not have any defined capabilities, so these functions
   * are not used.
   *)
(*
    val alEnable = _import "alEnable" stdcall : alenum -> unit;
    val alDisable = _import "alDisable" stdcall : alenum -> unit;
    val alIsEnabled = _import "alIsEnabled" stdcall : alenum -> bool;
*)

  (*
   * State retrieval
   *)
    local
      val alGetString = _import "alGetString" stdcall : glenum -> MLton.Pointer.t;
      fun get name = (case CString.toML(alGetString name)
	     of NONE => GLError.raiseError "alGetString: "
	      | SOME s => s
	    (* end case *))
    in
    fun getVendorString () = get AL_VENDOR
    fun getRendererString () = get AL_RENDERER
    fun getVersionString () = get AL_VERSION
    fun getExtensionsString () = get AL_EXTENSIONS
    fun getExtensions () = String.tokens Char.isSpace (getExtensionsString())
    end

    val alGetBoolean1 = _import "alGetBooleanv" stdcall : (glenum * bool ref) -> unit;
    val alGetBooleanv = _import "alGetBooleanv" stdcall : (glenum * bool array) -> unit;
AL_API void AL_APIENTRY alGetBooleanv( ALenum param, ALboolean* data );

AL_API void AL_APIENTRY alGetIntegerv( ALenum param, ALint* data );

AL_API void AL_APIENTRY alGetFloatv( ALenum param, ALfloat* data );

AL_API void AL_APIENTRY alGetDoublev( ALenum param, ALdouble* data );

AL_API ALboolean AL_APIENTRY alGetBoolean( ALenum param );

AL_API ALint AL_APIENTRY alGetInteger( ALenum param );

AL_API ALfloat AL_APIENTRY alGetFloat( ALenum param );

AL_API ALdouble AL_APIENTRY alGetDouble( ALenum param );


  (*
   * Error support.
   * Obtain the most recent error generated in the AL state machine.
   *)
    type error = alenum

    val NO_ERROR = AL_NO_ERROR
    val INVALID_NAME = AL_INVALID_NAME
    val ILLEGAL_ENUM = AL_ILLEGAL_ENUM
    val INVALID_ENUM = AL_INVALID_ENUM
    val INVALID_VALUE = AL_INVALID_VALUE
    val ILLEGAL_COMMAND = AL_ILLEGAL_COMMAND
    val INVALID_OPERATION = AL_INVALID_OPERATION
    val OUT_OF_MEMORY = AL_OUT_OF_MEMORY

    val getError = _import "alGetError" stdcall : unit -> error;


(* 
 * Extension support.
 * Query for the presence of an extension, and obtain any appropriate
 * function pointers and enum values.
 *)
(*
AL_API ALboolean AL_APIENTRY alIsExtensionPresent( const ALchar* extname );

AL_API void* AL_APIENTRY alGetProcAddress( const ALchar* fname );

AL_API ALenum AL_APIENTRY alGetEnumValue( const ALchar* ename );
*)


(*
 * LISTENER
 * Listener represents the location and orientation of the
 * 'user' in 3D-space.
 *
 * Properties include: -
 *
 * Gain         AL_GAIN         ALfloat
 * Position     AL_POSITION     ALfloat[3]
 * Velocity     AL_VELOCITY     ALfloat[3]
 * Orientation  AL_ORIENTATION  ALfloat[6] (Forward then Up vectors)
*)

(*
 * Set Listener parameters
 *)
AL_API void AL_APIENTRY alListenerf( ALenum param, ALfloat value );

AL_API void AL_APIENTRY alListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );

AL_API void AL_APIENTRY alListenerfv( ALenum param, const ALfloat* values ); 

AL_API void AL_APIENTRY alListeneri( ALenum param, ALint value );

AL_API void AL_APIENTRY alListener3i( ALenum param, ALint value1, ALint value2, ALint value3 );

AL_API void AL_APIENTRY alListeneriv( ALenum param, const ALint* values );

(*
 * Get Listener parameters
 *)
AL_API void AL_APIENTRY alGetListenerf( ALenum param, ALfloat* value );

AL_API void AL_APIENTRY alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );

AL_API void AL_APIENTRY alGetListenerfv( ALenum param, ALfloat* values );

AL_API void AL_APIENTRY alGetListeneri( ALenum param, ALint* value );

AL_API void AL_APIENTRY alGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 );

AL_API void AL_APIENTRY alGetListeneriv( ALenum param, ALint* values );


  (**
   * SOURCE
   * Sources represent individual sound objects in 3D-space.
   * Sources take the PCM data provided in the specified Buffer,
   * apply Source-specific modifications, and then
   * submit them to be mixed according to spatial arrangement etc.
   * 
   * Properties include: -
   *
   * Gain                              AL_GAIN                 ALfloat
   * Min Gain                          AL_MIN_GAIN             ALfloat
   * Max Gain                          AL_MAX_GAIN             ALfloat
   * Position                          AL_POSITION             ALfloat[3]
   * Velocity                          AL_VELOCITY             ALfloat[3]
   * Direction                         AL_DIRECTION            ALfloat[3]
   * Head Relative Mode                AL_SOURCE_RELATIVE      ALint (AL_TRUE or AL_FALSE)
   * Reference Distance                AL_REFERENCE_DISTANCE   ALfloat
   * Max Distance                      AL_MAX_DISTANCE         ALfloat
   * RollOff Factor                    AL_ROLLOFF_FACTOR       ALfloat
   * Inner Angle                       AL_CONE_INNER_ANGLE     ALint or ALfloat
   * Outer Angle                       AL_CONE_OUTER_ANGLE     ALint or ALfloat
   * Cone Outer Gain                   AL_CONE_OUTER_GAIN      ALint or ALfloat
   * Pitch                             AL_PITCH                ALfloat
   * Looping                           AL_LOOPING              ALint (AL_TRUE or AL_FALSE)
   * MS Offset                         AL_MSEC_OFFSET          ALint or ALfloat
   * Byte Offset                       AL_BYTE_OFFSET          ALint or ALfloat
   * Sample Offset                     AL_SAMPLE_OFFSET        ALint or ALfloat
   * Attached Buffer                   AL_BUFFER               ALint
   * State (Query only)                AL_SOURCE_STATE         ALint
   * Buffers Queued (Query only)       AL_BUFFERS_QUEUED       ALint
   * Buffers Processed (Query only)    AL_BUFFERS_PROCESSED    ALint
   *)
    local
      val alGenSource = _import "alGenSources" stdcall : (Int32.int* Word32.word ref) -> unit;
      val alGenSources = _import "alDeleteSources" stdcall : (Int32.int * Word32Array.array) -> unit;
      structure SourceId = ObjectIdFn (
	  type id = Word32.word
	  structure A = Word32Array.array
	  val dummy : Word32.word = 0w0
	  fun gen1 cell = alGenSource(1, cell)
	  val genn = _import "alGenSources" stdcall : (Int32.int * Word32Array.array) -> unit;
	  fun delete = _import "alDeleteSources" stdcall : (Int32.int * Word32Array.array) -> unit;
	)
    in
    type source_id = SourceId.object_id
    val getSourceId = SourceId.id
    val genSource = SourceId.gen
    val genSources = SourceId.genList
    val deleteSources = SourceId.deleteList
    end

(*
 * Set Source parameters
 *)
AL_API void AL_APIENTRY alSourcef( ALuint sid, ALenum param, ALfloat value ); 

AL_API void AL_APIENTRY alSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );

AL_API void AL_APIENTRY alSourcefv( ALuint sid, ALenum param, const ALfloat* values ); 

AL_API void AL_APIENTRY alSourcei( ALuint sid, ALenum param, ALint value ); 

AL_API void AL_APIENTRY alSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );

AL_API void AL_APIENTRY alSourceiv( ALuint sid, ALenum param, const ALint* values );

(*
 * Get Source parameters
 *)
AL_API void AL_APIENTRY alGetSourcef( ALuint sid, ALenum param, ALfloat* value );

AL_API void AL_APIENTRY alGetSource3f( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);

AL_API void AL_APIENTRY alGetSourcefv( ALuint sid, ALenum param, ALfloat* values );

AL_API void AL_APIENTRY alGetSourcei( ALuint sid,  ALenum param, ALint* value );

AL_API void AL_APIENTRY alGetSource3i( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);

AL_API void AL_APIENTRY alGetSourceiv( ALuint sid,  ALenum param, ALint* values );


(*
 * Source vector based playback calls
 *)

(* Play, replay, or resume (if paused) a list of Sources *)
AL_API void AL_APIENTRY alSourcePlayv( ALsizei ns, const ALuint *sids );

(* Stop a list of Sources *)
AL_API void AL_APIENTRY alSourceStopv( ALsizei ns, const ALuint *sids );

(* Rewind a list of Sources *)
AL_API void AL_APIENTRY alSourceRewindv( ALsizei ns, const ALuint *sids );

(* Pause a list of Sources *)
AL_API void AL_APIENTRY alSourcePausev( ALsizei ns, const ALuint *sids );

(*
 * Source based playback calls
 *)

(* Play, replay, or resume a Source *)
AL_API void AL_APIENTRY alSourcePlay( ALuint sid );

(* Stop a Source *)
AL_API void AL_APIENTRY alSourceStop( ALuint sid );

(* Rewind a Source (set playback postiton to beginning) *)
AL_API void AL_APIENTRY alSourceRewind( ALuint sid );

(* Pause a Source *)
AL_API void AL_APIENTRY alSourcePause( ALuint sid );

(*
 * Source Queuing 
 *)
    local
      val alSourceQueueBuffers =
	    _import "alSourceQueueBuffers" stdcall : (source_id * Word32.word * Word32Array.array) -> unit;
      val alSourceUnqueueBuffers =
	    _import "alSourceUnqueueBuffers" stdcall : (source_id * Word32.word * Word32Array.array) -> unit;
    in
    end

  (**
   * BUFFER
   * Buffer objects are storage space for sample data.
   * Buffers are referred to by Sources. One Buffer can be used
   * by multiple Sources.
   *
   * Properties include: -
   *
   * Frequency (Query only)    AL_FREQUENCY      ALint
   * Size (Query only)         AL_SIZE           ALint
   * Bits (Query only)         AL_BITS           ALint
   * Channels (Query only)     AL_CHANNELS       ALint
   *)

    local
      val alGenBuffers = _import "alGenBuffers" stdcall : (int * buffer_id array) -> unit;
      fun gen n = let
	    val arr = Array.array(n, 0w0)
	    in
	      alGenBuffers (n, arr);
	      arr
	    end
      val alDeleteBuffers = _import "alDeleteBuffers" stdcall : (int * buffer_id vector) -> unit;
    in
    fun genBuffer () = Array.sub(gen 1, 0)
    fun genBuffers n = if (n < 0)
	  then raise Size
	  else let val arr = gen n
	    in
	      List.tabulate (n, fn i => Array.sub(arr, i))
	    end
    fun deleteBuffers [] = ()
      | deleteBuffers l = let
	  val v = Vector.fromList l
	  in
	    alDeleteBuffers (Vector.length v, v)
	  end
    end

(* Specify the data to be copied into a buffer *)
    val alBufferData8 = _import "alBufferData" stdcall : (buffer_id * alenum * Word8Vector.vector * word32 * word32) -> unit;
    val alBufferData16 = _import "alBufferData" stdcall : (buffer_id * alenum * Int16Vector.vector * word32 * word32) -> unit;

    fun bufferData8ubv {id, mono, data, freq} =
	  alBufferData8 (id, if mono then AL_FORMAT_MONO8 else AL_FORMAT_STEREO8, data,
	    Word32.fromInt(Word8Vector.length data), freq)

    fun bufferData16ubv {id, mono, data, freq} =
	  alBufferData8 (id, if mono then AL_FORMAT_MONO16 else AL_FORMAT_STEREO16, data,
	    Word32.fromInt(Word8Vector.length data), freq)

    fun bufferData16sv {id, mono, data, freq} =
	  alBufferData16 (id, if mono then AL_FORMAT_MONO16 else AL_FORMAT_STEREO16, data,
	    2*Word32.fromInt(Int16Vector.length data), freq)

  (*
   * Set Buffer parameters
   * NOTE: these are not used in OpenAL 1.1
   *)
(*
  AL_API void AL_APIENTRY alBufferf( ALuint bid, ALenum param, ALfloat value );
  
  AL_API void AL_APIENTRY alBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
  
  AL_API void AL_APIENTRY alBufferfv( ALuint bid, ALenum param, const ALfloat* values );
  
  AL_API void AL_APIENTRY alBufferi( ALuint bid, ALenum param, ALint value );
  
  AL_API void AL_APIENTRY alBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
  
  AL_API void AL_APIENTRY alBufferiv( ALuint bid, ALenum param, const ALint* values );
*)

  (*
   * Get Buffer parameters
   * NOTE: most of these are not used in OpenAL 1.1
   *)
(*
  AL_API void AL_APIENTRY alGetBufferf( ALuint bid, ALenum param, ALfloat* value );
  
  AL_API void AL_APIENTRY alGetBuffer3f( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
  
  AL_API void AL_APIENTRY alGetBufferfv( ALuint bid, ALenum param, ALfloat* values );
  
  AL_API void AL_APIENTRY alGetBufferi( ALuint bid, ALenum param, ALint* value );
  
  AL_API void AL_APIENTRY alGetBuffer3i( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
  
  AL_API void AL_APIENTRY alGetBufferiv( ALuint bid, ALenum param, ALint* values );
*)
    local
      val alGetBufferi = _import "alGetBufferi" stdcall : (buffer_id * alenum * Word32.word ref) -> unit;
      fun get prop id = let
	    val cell = ref 0w0
	    in
	      alGetBufferi (id, prop, cell);
	      !cell
	    end
    in
    val getBufferFrequency	= get AL_FREQUENCY
    val getBufferBits		= get AL_BITS
    val getBufferChannels	= get AL_CHANNELS
    val getBufferSize		= get AL_SIZE
    end

  (*
   * Global Parameters
   *)
    val dopplerFactor = _import "alDopplerFactor" stdcall : float -> unit;
    val dopplerVelocity = _import "alDopplerVelocity" stdcall : float -> unit;
    val speedOfSound = _import "alSpeedOfSound" stdcall : float -> unit;

  (* distance model *)
    type distance_model = glenum
    val INVERSE_DISTANCE = AL_INVERSE_DISTANCE
    val INVERSE_DISTANCE_CLAMPED = AL_INVERSE_DISTANCE_CLAMPED
    val LINEAR_DISTANCE = AL_LINEAR_DISTANCE
    val LINEAR_DISTANCE_CLAMPED = AL_LINEAR_DISTANCE_CLAMPED
    val EXPONENT_DISTANCE = AL_EXPONENT_DISTANCE
    val EXPONENT_DISTANCE_CLAMPED = AL_EXPONENT_DISTANCE_CLAMPED
    val alDistanceModel = _import "alDistanceModel" stdcall : alenum -> unit;
    fun distanceModel NONE = alDistanceModel AL_NONE
      | distanceModel (SOME m) = alDistanceModel m

  end


root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0