PDA

View Full Version : OpenAL priority "Intelligent Source Manager"



JernejL
26-08-2006, 12:55 PM
Openal is stupid with its source number limit, you cannot have more than 16 sources... a possible solution is, to create a sound manager, which will automaticly create and destroy physical sound sources of a virtual sound sources list, depending on their priority (like distance to the listener).

i intend to write one, but i'm just asking here first if anybody has one already ;)

EDIT:

from page 2:


This is now improved version, i added full audio system pause (!) fixed sorting (also now uses bidirectional bubble sort, but something better should be used like quicksort? )

I added audio buffer loading and searching (no unloading but you can do it manually yourself)

The source-swaping works well, i just tested it in my game with 50 cars in same scene, and it performs as expected. distant sounds are swaped-out and near sounds are swaped-in to get smoothly around the openal 30 playing sounds limit.

Link:
https://github.com/JernejL/VirtualOpenAL

This source code is free for any use. i would especialy like to see someone add it to glscene, which currently only supports fmod and bass, which are both commercial products.
[/code]

JSoftware
26-08-2006, 04:27 PM
I've written something which could probably easily be extended to eliminate sources distant to the listener.

At it's current implementation state it is able to "reserve" sources and remove sources that has stopped.

JernejL
26-08-2006, 04:46 PM
I've written something which could probably easily be extended to eliminate sources distant to the listener.

At it's current implementation state it is able to "reserve" sources and remove sources that has stopped.

i've got something like that as well, but my additions to game scene management will require the new approach that i described, that's not just eliminating distant sources, but also recreating them for the virtual set of sound sources when they are needed.

JSoftware
26-08-2006, 04:58 PM
ah now i get it. To do that efficiently I would have to rewrite my system

JernejL
26-08-2006, 06:22 PM
ah now i get it. To do that efficiently I would have to rewrite my system

exactly same with my case, i have something very similar to your system, but needs a rewrite to do intelligent streaming, and i'm wondering if anyone already wrote something similar ;)

JernejL
30-08-2006, 11:30 AM
I am into writing this, but i can't figure this out, how do i know how much sources there are is there algetinteger constant i can use, or will i have to go for brute force mode?

JSoftware
30-08-2006, 11:51 AM
Yes i seem to remember a constant called something like AL_MAX_SOURCES

JernejL
30-08-2006, 12:39 PM
Yes i seem to remember a constant called something like AL_MAX_SOURCES

I can only find a constant for this:
AL_MAX_SOURCES = 32

Does this mean, that this is a hard coded limit?

I was looking around FMOD website and found a very nice description on what i am up to:


Virtual Channels
Virtual channels allow thousands of channels to play on limited hardware/software. Voices are swapped in and out according to 3d distance and priority.

JSoftware
30-08-2006, 12:46 PM
Which headers do you use?

I didn't find that in mine but I tried to query it with algetinteger, which returned 0. I guess it means that there a hardcoded limit

I haven't tried but what will algensources return when you reach a high number of sources?

JernejL
30-08-2006, 01:57 PM
Which headers do you use?

I didn't find that in mine but I tried to query it with algetinteger, which returned 0. I guess it means that there a hardcoded limit

I haven't tried but what will algensources return when you reach a high number of sources?

i'm using custom translated headers directly from C headers:

here it is if anyone is interested:

unit AL_Lib;

{$include compiler.inc}

interface

{
OpenAL cross platform audio library
Copyright (C) 1999-2000 by authors.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Or go to http://www.gnu.org/copyleft/lgpl.html
}

const

openal = 'OpenAL32.dll';

AL_MAX_CHANNELS = 4;
AL_MAX_SOURCES = 32;

// AL header

Type

{ 8-bit boolean }
ALboolean= boolean;
PALboolean= ^boolean;

{ character }
ALchar= char;
PALchar = Pchar;

{ signed 8-bit 2's complement integer }
ALbyte= byte;
PALbyte= ^byte;

{ unsigned 8-bit integer }
ALubyte = byte;
PALubyte = ^byte;

{ signed 16-bit 2's complement integer }
ALshort= shortint;
PALshort= ^shortint;

{ unsigned 16-bit integer }
ALushort= word;
PALushort= ^word;

{ signed 32-bit 2's complement integer }
ALint= integer;
PALint= ^integer;

{ unsigned 32-bit integer }
ALuint= longword;
PALuint= ^longword;

{ non-negative 32-bit binary integer size }
ALsizei= integer;
PALsizei= ^integer;

{ enumerated 32-bit value }
ALenum= integer;
PALenum= ^integer;

{ 32-bit IEEE754 floating-point }
ALfloat= single;
PALfloat= ^single;

{ 64-bit IEEE754 floating-point }
ALdouble= double;
PALdouble= ^double;

{ void type (for opaque pointers only) }
ALvoid= pointer;
PALvoid= pointer;

const
{ Enumerant values begin at column 50. No tabs. }

{ bad value }
AL_INVALID = -1;

AL_NONE = 0;

{ Boolean False. }
AL_FALSE = 0;

{ Boolean True. }
AL_TRUE = 1;

{ Indicate Source has relative coordinates. }
AL_SOURCE_RELATIVE = $202;



{
Directional source, inner cone angle, in degrees.
Range: [0-360]
Default: 360
}
AL_CONE_INNER_ANGLE = $1001;

{
Directional source, outer cone angle, in degrees.
Range: [0-360]
Default: 360
}
AL_CONE_OUTER_ANGLE = $1002;

{
Specify the pitch to be applied, either at source,
or on mixer results, at listener.
Range: [0.5-2.0]
Default: 1.0
}
AL_PITCH = $1003;

{
Specify the current location in three dimensional space.
OpenAL, like OpenGL, uses a right handed coordinate system,
where in a frontal default view X (thumb) points right,
Y points up (index finger), and Z points towards the
viewer/camera (middle finger).
To switch from a left handed coordinate system, flip the
sign on the Z coordinate.
Listener position is always in the world coordinate system.
}
AL_POSITION = $1004;

{ Specify the current direction. }
AL_DIRECTION = $1005;

{ Specify the current velocity in three dimensional space. }
AL_VELOCITY = $1006;

{
Indicate whether source is looping.
Type: ALboolean?
Range: [AL_TRUE, AL_FALSE]
Default: FALSE.
}
AL_LOOPING = $1007;

{
Indicate the buffer to provide sound samples.
Type: ALuint.
Range: any valid Buffer id.
}
AL_BUFFER = $1009;

{
Indicate the gain (volume amplification) applied.
Type: ALfloat.
Range: ]0.0- ]
A value of 1.0 means un-attenuated/unchanged.
Each division by 2 equals an attenuation of -6dB.
Each multiplicaton with 2 equals an amplification of +6dB.
A value of 0.0 is meaningless with respect to a logarithmic
scale; it is interpreted as zero volume - the channel
is effectively disabled.
}
AL_GAIN = $100A;

{
Indicate minimum source attenuation
Type: ALfloat
Range: [0.0 - 1.0]

Logarthmic
}
AL_MIN_GAIN = $100D;

{
Indicate maximum source attenuation
Type: ALfloat
Range: [0.0 - 1.0]

Logarthmic
}
AL_MAX_GAIN = $100E;

{
Indicate listener orientation.

at/up
}
AL_ORIENTATION = $100F;

{
Specify the channel mask. (Creative)
Type: ALuint
Range: [0 - 255]
}
AL_CHANNEL_MASK = $3000;


{
Source state information.
}
AL_SOURCE_STATE = $1010;
AL_INITIAL = $1011;
AL_PLAYING = $1012;
AL_PAUSED = $1013;
AL_STOPPED = $1014;

{
Buffer Queue params
}
AL_BUFFERS_QUEUED = $1015;
AL_BUFFERS_PROCESSED = $1016;

{
Source buffer position information
}
AL_SEC_OFFSET = $1024;
AL_SAMPLE_OFFSET = $1025;
AL_BYTE_OFFSET = $1026;

{
Source type (Static, Streaming or undetermined)
Source is Static if a Buffer has been attached using AL_BUFFER
Source is Streaming if one or more Buffers have been attached using alSourceQueueBuffers
Source is undetermined when it has the NULL buffer attached
}
AL_SOURCE_TYPE = $1027;
AL_STATIC = $1028;
AL_STREAMING = $1029;
AL_UNDETERMINED = $1030;

{ Sound samples: format specifier. }
AL_FORMAT_MONO8 = $1100;
AL_FORMAT_MONO16 = $1101;
AL_FORMAT_STEREO8 = $1102;
AL_FORMAT_STEREO16 = $1103;

{
source specific reference distance
Type: ALfloat
Range: 0.0 - +inf

At 0.0, no distance attenuation occurs. Default is
1.0.
}
AL_REFERENCE_DISTANCE = $1020;

{
source specific rolloff factor
Type: ALfloat
Range: 0.0 - +inf

}
AL_ROLLOFF_FACTOR = $1021;

{
Directional source, outer cone gain.

Default: 0.0
Range: [0.0 - 1.0]
Logarithmic
}
AL_CONE_OUTER_GAIN = $1022;

{
Indicate distance above which sources are not
attenuated using the inverse clamped distance model.

Default: +inf
Type: ALfloat
Range: 0.0 - +inf
}
AL_MAX_DISTANCE = $1023;

{
Sound samples: frequency, in units of Hertz [Hz].
This is the number of samples per second. Half of the
sample frequency marks the maximum significant
frequency component.
}
AL_FREQUENCY = $2001;
AL_BITS = $2002;
AL_CHANNELS = $2003;
AL_SIZE = $2004;

{
Buffer state.

Not supported for public use (yet).
}
AL_UNUSED = $2010;
AL_PENDING = $2011;
AL_PROCESSED = $2012;


{ Errors: No Error. }
AL_NO_ERROR = AL_FALSE;

{
Invalid Name paramater passed to AL call.
}
AL_INVALID_NAME = $A001;

{
Invalid parameter passed to AL call.
}
AL_ILLEGAL_ENUM = $A002;
AL_INVALID_ENUM = $A002;

{
Invalid enum parameter value.
}
AL_INVALID_VALUE = $A003;

{
Illegal call.
}
AL_ILLEGAL_COMMAND = $A004;
AL_INVALID_OPERATION = $A004;


{
No mojo.
}
AL_OUT_OF_MEMORY = $A005;


{ Context strings: Vendor Name. }
AL_VENDOR = $B001;
AL_VERSION = $B002;
AL_RENDERER = $B003;
AL_EXTENSIONS = $B004;

{ Global tweakage. }

{
Doppler scale. Default 1.0
}
AL_DOPPLER_FACTOR = $C000;

{
Tweaks speed of propagation.
}
AL_DOPPLER_VELOCITY = $C001;

{
Speed of Sound in units per second
}
AL_SPEED_OF_SOUND = $C003;

{
Distance models

used in conjunction with DistanceModel

implicit: NONE, which disances distance attenuation.
}
AL_DISTANCE_MODEL = $D000;
AL_INVERSE_DISTANCE = $D001;
AL_INVERSE_DISTANCE_CLAMPED = $D002;
AL_LINEAR_DISTANCE = $D003;
AL_LINEAR_DISTANCE_CLAMPED = $D004;
AL_EXPONENT_DISTANCE = $D005;
AL_EXPONENT_DISTANCE_CLAMPED = $D006;


{
Renderer State management
}
Procedure alEnable( capability : ALenum ); cdecl; external openal;

Procedure alDisable( capability : ALenum ); cdecl; external openal;

Function alIsEnabled( capability : ALenum ): ALboolean; cdecl; external openal;


{
State retrieval
}
Function alGetString( param : ALenum ): PALchar; cdecl; external openal;

Procedure alGetBooleanv( param: ALenum ; data : PALboolean ); cdecl; external openal;

Procedure alGetIntegerv( param: ALenum ; data : PALint ); cdecl; external openal;

Procedure alGetFloatv( param: ALenum ; data : PALfloat ); cdecl; external openal;

Procedure alGetDoublev( param: ALenum ; data : PALdouble ); cdecl; external openal;

Function alGetBoolean( param : ALenum ): ALboolean; cdecl; external openal;

Function alGetInteger( param : ALenum ): ALint; cdecl; external openal;

Function alGetFloat( param : ALenum ): ALfloat; cdecl; external openal;

Function alGetDouble( param : ALenum ): ALdouble; cdecl; external openal;


{
Error support.
Obtain the most recent error generated in the AL state machine.
}

Function alGetError: ALenum; cdecl; external openal;

{
Extension support.
Query for the presence of an extension; and obtain any appropriate
function pointers and enum values.
}
Function alIsExtensionPresent( const PALcharextname ): ALboolean; cdecl; external openal;

Function alGetProcAddress( const name: PALchar ): ALvoid; cdecl; external openal;

Function alGetEnumValue( const PALcharename ): ALenum; cdecl; external openal;


{
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
}
Procedure alListenerf( param: ALenum ; value: ALfloat ); cdecl; external openal;

Procedure alListener3f( param: ALenum ; value1: ALfloat; value2: ALfloat; value3 : ALfloat); cdecl; external openal;

Procedure alListenerfv( param: ALenum ; const values : PALfloat); cdecl; external openal;

Procedure alListeneri( param: ALenum ; value : ALint); cdecl; external openal;

Procedure alListener3i( param: ALenum ; value1: ALint; value2: ALint; value3 : ALint); cdecl; external openal;

Procedure alListeneriv( param: ALenum ; const values : PALint); cdecl; external openal;

{
Get Listener parameters
}
Procedure alGetListenerf( param: ALenum ; value : PALfloat); cdecl; external openal;

Procedure alGetListener3f( param: ALenum ; value1: PALfloat; value2: PALfloat; value3 : PALfloat); cdecl; external openal;

Procedure alGetListenerfv( param: ALenum ; values : PALfloat); cdecl; external openal;

Procedure alGetListeneri( param: ALenum ; value : PALint); cdecl; external openal;

Procedure alGetListener3i( param: ALenum ; value1: PALint; value2: PALint; value3 : PALint); cdecl; external openal;

Procedure alGetListeneriv( param: ALenum ; values : PALint); cdecl; external openal;


{
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
}

{ Create Source objects }
Procedure alGenSources( n: ALsizei; sources : PALuint); cdecl; external openal;

{ Delete Source objects }
Procedure alDeleteSources( n: ALsizei; const sources : PALuint); cdecl; external openal;

{ Verify a handle is a valid Source }
Function alIsSource( sid : ALuint): ALboolean; cdecl; external openal;

{
Set Source parameters
}
Procedure alSourcef( sid: ALuint; param: ALenum ; value : ALfloat); cdecl; external openal;

Procedure alSource3f( sid: ALuint; param: ALenum ; value1: ALfloat; value2: ALfloat; value3 : ALfloat); cdecl; external openal;

Procedure alSourcefv( sid: ALuint; param: ALenum ; const values: PALfloat ); cdecl; external openal;

Procedure alSourcei( sid: ALuint; param: ALenum ; value : ALint); cdecl; external openal;

Procedure alSource3i( sid: ALuint; param: ALenum ; value1: ALint; value2: ALint; value3 : ALint); cdecl; external openal;

Procedure alSourceiv( sid: ALuint; param: ALenum ; const values : PALint); cdecl; external openal;

{
Get Source parameters
}
Procedure alGetSourcef( sid: ALuint; param: ALenum ; value : PALfloat); cdecl; external openal;

Procedure alGetSource3f( sid: ALuint; param: ALenum ; value1: PALfloat; value2: PALfloat; value3: PALfloat); cdecl; external openal;

Procedure alGetSourcefv( sid: ALuint; param: ALenum ; values : PALfloat); cdecl; external openal;

Procedure alGetSourcei( sid: ALuint; param: ALenum ; value : PALint); cdecl; external openal;

Procedure alGetSource3i( sid: ALuint; param: ALenum ; value1: PALint; value2: PALint; value3: PALint); cdecl; external openal;

Procedure alGetSourceiv( sid: ALuint; param: ALenum ; values : PALint); cdecl; external openal;


{
Source vector based playback calls
}

{ Play; replay; or resume (if paused) a list of Sources }
Procedure alSourcePlayv( ns: ALsizei; const sids : PALuint); cdecl; external openal;

{ Stop a list of Sources }
Procedure alSourceStopv( ns: ALsizei; const sids : PALuint); cdecl; external openal;

{ Rewind a list of Sources }
Procedure alSourceRewindv( ns: ALsizei; const sids : PALuint); cdecl; external openal;

{ Pause a list of Sources }
Procedure alSourcePausev( ns: ALsizei; const sids : PALuint); cdecl; external openal;

{
Source based playback calls
}

{ Play; replay; or resume a Source }
Procedure alSourcePlay( sid : ALuint); cdecl; external openal;

{ Stop a Source }
Procedure alSourceStop( sid : ALuint); cdecl; external openal;

{ Rewind a Source (set playback postiton to beginning) }
Procedure alSourceRewind( sid : ALuint); cdecl; external openal;

{ Pause a Source }
Procedure alSourcePause( sid : ALuint); cdecl; external openal;

{
Source Queuing
}
Procedure alSourceQueueBuffers( sid: ALuint; numEntries: ALsizei; const bids : PALuint); cdecl; external openal;

Procedure alSourceUnqueueBuffers( sid: ALuint; numEntries: ALsizei; bids : PALuint); cdecl; external openal;


{
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
}

{ Create Buffer objects }
Procedure alGenBuffers( n: ALsizei; buffers : PALuint); cdecl; external openal;

{ Delete Buffer objects }
Procedure alDeleteBuffers( n: ALsizei; const buffers : PALuint); cdecl; external openal;

{ Verify a handle is a valid Buffer }
Function alIsBuffer( bid : ALuint): ALboolean; cdecl; external openal;

{ Specify the data to be copied into a buffer }
Procedure alBufferData( bid: ALuint; format: ALenum ; data: PALvoid ; size: ALsizei ; freq : ALsizei); cdecl; external openal;


{
Set Buffer parameters
}

Procedure alBufferf( bid: ALuint; param : ALenum ; value : ALfloat); cdecl; external openal;

Procedure alBuffer3f( bid: ALuint; param: ALenum ; value1: ALfloat; value2: ALfloat; value3 : ALfloat); cdecl; external openal;

Procedure alBufferfv( bid: ALuint; param: ALenum ; const values : PALfloat ); cdecl; external openal;

Procedure alBufferi( bid: ALuint; param: ALenum ; value : ALint); cdecl; external openal;

Procedure alBuffer3i( bid: ALuint; param: ALenum ; value1: ALint; value2: ALint; value3 : ALint); cdecl; external openal;

Procedure alBufferiv( bid: ALuint; param: ALenum ; const values : PALint ); cdecl; external openal;

{
Get Buffer parameters
}
Procedure alGetBufferf( bid: ALuint; param: ALenum ; value : PALfloat); cdecl; external openal;

Procedure alGetBuffer3f( bid: ALuint; param: ALenum ; value1: PALfloat; value2: PALfloat; value3: PALfloat); cdecl; external openal;

Procedure alGetBufferfv( bid: ALuint; param: ALenum ; values : PALfloat); cdecl; external openal;

Procedure alGetBufferi( bid: ALuint; param: ALenum ; value : PALint); cdecl; external openal;

Procedure alGetBuffer3i( bid: ALuint; param: ALenum ; value1: PALint; value2: PALint; value3: PALint); cdecl; external openal;

Procedure alGetBufferiv( bid: ALuint; param: ALenum ; values : PALint); cdecl; external openal;


{
Global Parameters
}
Procedure alDopplerFactor( value : ALfloat); cdecl; external openal;

Procedure alDopplerVelocity( value : ALfloat); cdecl; external openal;

Procedure alSpeedOfSound( value : ALfloat); cdecl; external openal;

Procedure alDistanceModel( distanceModel : ALenum ); cdecl; external openal;

// // ALC header

Type

ALCdevice= pointer;
PALCdevice= ^pointer;

ALCcontext= pointer;
PALCcontext= ^pointer;

{ 8-bit boolean }
ALCboolean= boolean;
PALCboolean= ^boolean;

{ character }
ALCchar= char;
PALCchar = Pchar;

{ signed 8-bit 2's complement integer }
ALCbyte= byte;
PALCbyte= ^byte;

{ unsigned 8-bit integer }
ALCubyte = byte;
PALCubyte = ^byte;

{ signed 16-bit 2's complement integer }
ALCshort= shortint;
PALCshort= ^shortint;

{ unsigned 16-bit integer }
ALCushort= word;
PALCushort= ^word;

{ signed 32-bit 2's complement integer }
ALCint= integer;
PALCint= ^integer;

{ unsigned 32-bit integer }
ALCuint= longword;
PALCuint= ^longword;

{ non-negative 32-bit binary integer size }
ALCsizei= integer;
PALCsizei= ^integer;

{ enumerated 32-bit vALCue }
ALCenum= integer;
PALCenum= ^integer;

{ 32-bit IEEE754 floating-point }
ALCfloat= single;
PALCfloat= ^single;

{ 64-bit IEEE754 floating-point }
ALCdouble= double;
PALCdouble= ^double;

{ void type (for opaque pointers only) }
ALCvoid= pointer;
PALCvoid= ^pointer;

const
{ Enumerant values begin at column 50. No tabs. }

{ bad value }
ALC_INVALID = 0;

{ Boolean False. }
ALC_FALSE = 0;

{ Boolean True. }
ALC_TRUE = 1;

{
followed by <int> Hz
}
ALC_FREQUENCY = $1007;

{
followed by <int> Hz
}
ALC_REFRESH = $1008;

{
followed by AL_TRUE, AL_FALSE
}
ALC_SYNC = $1009;

{
followed by <int> Num of requested Mono (3D) Sources
}
ALC_MONO_SOURCES = $1010;

{
followed by <int> Num of requested Stereo Sources
}
ALC_STEREO_SOURCES = $1011;

{
errors
}

{
No error
}
ALC_NO_ERROR = ALC_FALSE;

{
No device
}
ALC_INVALID_DEVICE = $A001;

{
invalid context ID
}
ALC_INVALID_CONTEXT = $A002;

{
bad enum
}
ALC_INVALID_ENUM = $A003;

{
bad value
}
ALC_INVALID_VALUE = $A004;

{
Out of memory.
}
ALC_OUT_OF_MEMORY = $A005;


{
The Specifier string for default device
}
ALC_DEFAULT_DEVICE_SPECIFIER = $1004;
ALC_DEVICE_SPECIFIER = $1005;
ALC_EXTENSIONS = $1006;

ALC_MAJOR_VERSION = $1000;
ALC_MINOR_VERSION = $1001;

ALC_ATTRIBUTES_SIZE = $1002;
ALC_ALL_ATTRIBUTES = $1003;

{
Capture extension
}
ALC_CAPTURE_DEVICE_SPECIFIER = $310;
ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER = $311;
ALC_CAPTURE_SAMPLES = $312;

{
Context Management
}
Function alcCreateContext( device: PALCdevice; const attrlist: PALCint ): PALCcontext; cdecl; external openal;

Function alcMakeContextCurrent( context: PALCcontext ): ALCboolean; cdecl; external openal;

Procedure alcProcessContext( context: ALCcontext ); cdecl; external openal;

Procedure alcSuspendContext( context: ALCcontext ); cdecl; external openal;

Procedure alcDestroyContext( context: ALCcontext ); cdecl; external openal;

Function alcGetCurrentContext: ALCcontext; cdecl; external openal;

Function alcGetContextsDevice( context: PALCcontext ): ALCdevice; cdecl; external openal;


{
Device Management
}
Function alcOpenDevice( const devicename: PALCchar ): ALCdevice; cdecl; external openal;

Function alcCloseDevice( device: PALCdevice ): ALCboolean; cdecl; external openal;


{
Error support.
Obtain the most recent Context error
}
Function alcGetError( device: PALCdevice ): ALCenum; cdecl; external openal;


{
Extension support.
Query for the presence of an extension, and obtain any appropriate
function pointers and enum values. cdecl; external openal;
}
Function alcIsExtensionPresent( device: PALCdevice; const extname: PALCchar ): ALCboolean; cdecl; external openal;

Procedure alcGetProcAddress( device: PALCdevice; const funcname: PALCchar ); cdecl; external openal;

Function alcGetEnumValue( device: ALCdevice; const enumname: PALCchar ): ALCenum; cdecl; external openal;


{
Query functions
}
Function alcGetString( device: PALCdevice ; param: ALCenum ): ALCchar; cdecl; external openal;

Procedure alcGetIntegerv( device: PALCdevice; param: ALCenum; size: ALCsizei; data: PALCint ); cdecl; external openal;


{
Capture functions
}
Function alcCaptureOpenDevice( const devicename: PALCchar; frequency: ALCuint; format: ALCenum; buffersize: ALCsizei ): PALCdevice; cdecl; external openal;

Function alcCaptureCloseDevice( device: PALCdevice ): ALCboolean; cdecl; external openal;

Procedure alcCaptureStart( device: PALCdevice ); cdecl; external openal;

Procedure alcCaptureStop( device: PALCdevice ); cdecl; external openal;

Procedure alcCaptureSamples( device: PALCdevice ; buffer: PALCvoid ; samples: ALCsizei ); cdecl; external openal;

implementation

end.

JernejL
17-09-2006, 10:48 PM
alright, i have almost 100% success in my demo program, which swaps a single sound in and out of the "barrier", it works with loops as well - that means if you swap the sound at certain point and swap it back the stream position will get adjusted, so it will seem like the sound was still playing when outside of openal :)

i also noticed a slight error in the documentation, sometimes there are references to AL_MSEC_OFFSET, but there is only AL_SEC_OFFSET, which is float, it returns a float with 2 digits precision after the decimal separator.

i also noticed, that i can set AL_PITCH to anything between 0.01 to 4.5, according to documentation it says it should be from 0.5 to 2.0, interesting indeed.. can someone with hardware openal check how far this can go and if it differs on different implementations?

i think, if i get this wrapped into a decent sound manager package, it would make openal much more suitable for indie projects, than other packages like fmod, which are not free. also, when vista comes, the only hardware accelerated audio will be supported thru openal, directsound is no longer hardware accelerated in windows vista!!

JSoftware
18-09-2006, 06:37 AM
But.. doesn't OpenAL already wrap over Directsound?

Edit: Ah i got it. Just read the article on Openal.org

JernejL
18-09-2006, 11:27 AM
But.. doesn't OpenAL already wrap over Directsound?

Edit: Ah i got it. Just read the article on Openal.org

yeah, by default you can choose directsound, mmsystem, etc.. devices, but on nvidia (ac97) integrated audio and creative hardware you can use openal with hardware accelerator.

JernejL
20-09-2006, 06:46 PM
This is the first test version of the library, if i enforce it to use just 1 openal source it seems to do the job properly, i haven't tried it in real game environment yet, but it should be easy to integrate into any game, feel free to improve the code and use in any project you want, there is room for improvement, bateries not included.

https://github.com/JernejL/VirtualOpenAL

to compile it, replace sys_calc and accompanying vector math calls with your favorite vector library!

noeska
21-09-2006, 05:00 PM
Hello Delfi, we better join forces. Have a look at http://www.noeska.com/doal .

JernejL
21-09-2006, 05:26 PM
Hello Delfi, we better join forces. Have a look at http://www.noeska.com/doal .

i am familiar with your work, and it was the starting point for all my openal related works, but i didn't find anything like this on your website, this unit is not just a source manager, but a complete sound system, with sources management which automaticly turns on sources near listener and off sources away from listener, to compensate to get around the 30 sources limit.

it isn't complete yet, but when it is, i'd appreciate if you host a copy of it on your website :)

noeska
22-09-2006, 09:12 PM
Ok let me know.

JernejL
26-09-2006, 12:35 PM
This is now improved version, i added full audio system pause (!) fixed sorting (also now uses bidirectional bubble sort, but something better should be used like quicksort? )

I added audio buffer loading and searching (no unloading but you can do it manually yourself)

The source-swaping works well, i just tested it in my game with 50 cars in same scene, and it performs as expected. distant sounds are swaped-out and near sounds are swaped-in to get smoothly around the openal 30 playing sounds limit.

Link:
https://github.com/JernejL/VirtualOpenAL

This source code is free for any use. i would especialy like to see someone add it to glscene, which currently only supports fmod and bass, which are both commercial products.

JernejL
26-09-2006, 01:04 PM
I just found and updated a minor bug in deletion callback routines.

EDIT: updated - fixed 16 bit stereo wav file format calculation bug...

bigsofty
27-09-2006, 10:35 AM
I tried the test application for your lib, its says no audio devices found?

I have a SB Audigy 2 ?

Ian

JernejL
27-09-2006, 10:59 AM
you will need to install creative's openal lib, i packed wrong openal32.dll, the new one should work (re-uploaded):

but there's an offical installer for openal you can use:
http://developer.creative.com/articles/article.asp?cat=1&sbcat=31&top=38&aid=46

edit: i discovered that sometimes openal will not work unless initialized with VirtualOpenDevice('Generic Hardware');

JernejL
26-10-2006, 08:26 PM
I have fixed the last bug that prevented the lib from initializing properly sometimes, i also added a minimal vector library to the little demo app, and the whole thing works great now :)

download link:

http://www.gtatools.com/temp/virtual%20openal.rar

edit: lol, it took me a whole month to post this fix :oops:

edit 2: you can now set the MaxSourceDistance variable, it will cull out all sounds more distant than 10 units, very useful, since this is actually not just an ordinary openal wrapper, but a whole game sound manager!

WILL
26-10-2006, 08:46 PM
Hey nice work Delfi! :)

I may look into this for a few of my titles. Just to clairify though, the packaged openal32.dll now is in fact the creative one?

I'm unsure of which one I have been using here, but I know it works with Noeska's wrappers.

JernejL
26-10-2006, 09:19 PM
Hey nice work Delfi! :)

I may look into this for a few of my titles. Just to clairify though, the packaged openal32.dll now is in fact the creative one?

I'm unsure of which one I have been using here, but I know it works with Noeska's wrappers.

yes, it is creative's actual d3d/dsound/mmsystem openal implementation lib, and not the wrapper which loads actual nvopenal and other hardware al libs.

but the lib should work with any openal dll.

Rojekti
16-04-2007, 04:24 PM
Hmm, very interesting..!

Since my programmingskills arent so high, I didn't really get the point of this engine. But, I did get it working, played sounds, etc. It's gooo-ood. Plays them just well :)

But.. so.. emm. This code, which was found in the example;



VirtualOpenDevice&#40;nil&#41;;
VirtualInitialize;

setlength&#40;WaveBuffers, length&#40;WaveBuffers&#41; +1&#41;;
with WaveBuffers&#91;high&#40;WaveBuffers&#41;&#93; do begin
ID&#58;= indexx;
XALLoadWave&#40;buffer, pchar&#40;sound&#41;&#41;;
end;

VirtualModifyListener&#40;makevector&#40;0.0, 0.0, 0.0&#41;, makevector&#40;0.0, 0.0, 0.0&#41;, virtualopenal.ListenerOrientationarray&#41;;
SourceCreate&#40;WaveBuffers&#91;FindBuffer&#40;indexx&#41;&#93;.buffe r, makevector&#40;0, 0, 0&#41;, true , nil , nil&#41;;

VirtualSwapInSwapOut;

dofunstuff&#58;= true;



..what it exactly does? Did I got it right: it creates a source of a sound? So, it wont just play a single sound, but it kinda creates a trigger which plays some sound, from a certain position? I should tell it where it is and where the listener is -> it calculates the volyme of sound..? Or am I dump? :D

Seems very good, I'm really looking forward to get this working properly..!

JernejL
16-04-2007, 05:24 PM
Hmm, very interesting..!

Since my programmingskills arent so high, I didn't really get the point of this engine. But, I did get it working, played sounds, etc. It's gooo-ood. Plays them just well :)

But.. so.. emm. This code, which was found in the example;




// this initializes sound
VirtualOpenDevice&#40;nil&#41;;
VirtualInitialize;

// this loads a SINGLE wave file into a wave buffer, you can load many sounds and have them shared by the sources &#40;one loaded wav file can be played back several times at the same time&#41;
setlength&#40;WaveBuffers, length&#40;WaveBuffers&#41; +1&#41;;
with WaveBuffers&#91;high&#40;WaveBuffers&#41;&#93; do begin
ID&#58;= indexx;
XALLoadWave&#40;buffer, pchar&#40;sound&#41;&#41;;
end;

// this sets up the listener's position &#40;the player's location in the world&#41;
VirtualModifyListener&#40;makevector&#40;0.0, 0.0, 0.0&#41;, makevector&#40;0.0, 0.0, 0.0&#41;, virtualopenal.ListenerOrientationarray&#41;;

// this creates a single source
SourceCreate&#40;WaveBuffers&#91;FindBuffer&#40;indexx&#41;&#93;.buffe r, makevector&#40;0, 0, 0&#41;, true , nil , nil&#41;;

// this handles swapping sources in and out if there are too small amout of them in hardware to use all at the same time
VirtualSwapInSwapOut;

dofunstuff&#58;= true; // fun variable &#58;&#41;


i commented what the pieces of code do ^^^^

[quote]
..what it exactly does? Did I got it right: it creates a source of a sound? So, it wont just play a single sound, but it kinda creates a trigger which plays some sound, from a certain position? I should tell it where it is and where the listener is -> it calculates the volyme of sound..? Or am I dump? :D


well yeah, you load wav files into buffers, and you can pick a buffer and play it back in many places and many times, you can also set volume, pitch, velocity (doppler effect) and so on...

Rojekti
16-04-2007, 05:59 PM
Yarr, great. So I could load first all sounds to the engine and then play them via their index.. well this is great! Great job, Delfi ^^

Can this be used freely in a shareware game? Name to credits.. \o.

JernejL
16-04-2007, 07:04 PM
Yarr, great. So I could load first all sounds to the engine and then play them via their index.. well this is great! Great job, Delfi ^^

Can this be used freely in a shareware game? Name to credits.. \o.

yeah, but please do give credit, ok? and a free copy of the game would be nice :D

Rojekti
16-04-2007, 07:42 PM
Of course you get credit! And a free copy too ;> Right now the game isn't in english but it'll be translated, language packs will be avaivable etc.

Thanks! This is great system. Excellenttttt.

Firlefanz
09-05-2007, 06:41 AM
Hi!

Does OpenAL support Ogg files and more than just stereospeakers?

Thanks,
Firle

PS: I found this site from an other topic.
It seems both OGG and EAX are supported, I'll have a look at the tuts there. :)

JernejL
09-05-2007, 11:10 AM
openal supports any sound stream, so if you use it with ogg/vorbis, such as with vorbisfile.dll it should work just fine. however my wrapper doesn't yet have any ogg / streaming support, but i'm planning one.

Firlefanz
09-05-2007, 12:08 PM
Will the wrapper also get EAX support?

OpenAl itself looks a bit difficult to use for a game (I have one music and lots of SFX (in a list) loaded always).

Firle

JSoftware
09-05-2007, 12:51 PM
OpenAl itself looks a bit difficult to use for a game (I have one music and lots of SFX (in a list) loaded always).

What do you mean? You don't have to use streams in OpenAL. You can keep a list of sounds and then create sources where a specific sound will play

WILL
09-05-2007, 01:40 PM
I believe the Creative SDK (http://developer.creative.com/landing.asp?cat=1&sbcat=31&top=38) DLLs will give you EAX hardware support. As for the setting call, I'm not sure what you'd have to set, but I'm almost sure that their libs will have the support.

See you're getting 3D sound either way, it's just enabling/disabling the hardware that will give you the EAX acceleration option in your games.

At least this is my best interpretation of how EAX & OpenAL works.

Of course you can always read more about it in one of Noeska's tutorials. Lesson 12 EAX Enviroment (http://www.noeska.com/doal/lesson12.aspx) You can probably tell but he has done extensive work with OpenAL already.

JernejL
09-05-2007, 02:49 PM
Will the wrapper also get EAX support?

OpenAl itself looks a bit difficult to use for a game (I have one music and lots of SFX (in a list) loaded always).

Firle

you can implement that easily with openal extensions, it's not depending on the wrapper at all. and the wrapper works with any openal dll.

JernejL
20-02-2011, 03:31 PM
Updated / fixed download link.

Is anyone still interested in this or uses it? i added some improvements and fixes to it since the last update here.

chronozphere
20-02-2011, 03:45 PM
Yes I'm intersted. I use openAL in my engine and would like to add a bit more intelligence to it, if that can be achieved easily. :)

What kind of license do you use? I might want to use (some of) your code in my engine in the future.

JernejL
20-02-2011, 03:52 PM
No license.. kinda like BSD but more like do as you please

chronozphere
20-02-2011, 04:01 PM
Great! Thank you.

If I use it, I will probably refactor it so that it fits my object-oriented style of coding. I'm planning on releasing my engine under LGPL as soon as it's worth releasing. :)

JernejL
20-02-2011, 04:43 PM
The main thing of intelligent source manager is to swap-in and swap-out sources while simulating as if the source was still playing during the time it wasn't in the active sources pool, you can easily reuse this logic from my code which is the most important part and use a object oriented design of your own. I plan to do the same and port this code out of the procedural world, but it simply isn't high on priority currently.

klanpaia
05-05-2011, 03:43 PM
Here says:

Invalid Floating Point Operation :(

What do I do?

Break here :
// calculate how much time would whole sound take to play at current pitch.
one_frame_ms := buffsize / bits / freq; // 44100 <----------------------------------
one_frame_ms := one_frame_ms / VirtualSource.Pitch;

0.o

code_glitch
07-05-2011, 10:31 PM
what type is one_frame_ms? Integer? You'd need to either:
one_frame_ms := buffsize div bits div freq
or you could
one_framce_ms := trunc(buffsize / bits / freq)

and you might want to consider using brackets just to be extra sure you don't cause a bug that may be marginally annoying ;)

JernejL
21-05-2018, 07:13 AM
Update: i put the project on github and edited links: https://github.com/JernejL/VirtualOpenAL