mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-28 19:30:52 +02:00
OpenAL is enabled, EAX fixes and removed DirectSound completely.
This commit is contained in:
Binary file not shown.
@@ -13,7 +13,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>dbghelp.lib;dinput8.lib;dsound.lib;dxguid.lib;eaxguid.lib;glu32.lib;iphlpapi.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dbghelp.lib;dinput8.lib;dxguid.lib;glu32.lib;iphlpapi.lib;odbc32.lib;odbccp32.lib;winmm.lib;wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x64;openal\lib;sys\win32\dongle;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<OutputFile>$(OutDir)DOOM3.exe</OutputFile>
|
||||
<AdditionalManifestDependencies>%(AdditionalManifestDependencies)</AdditionalManifestDependencies>
|
||||
@@ -23,4 +23,4 @@
|
||||
<LargeAddressAware>true</LargeAddressAware>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -117,14 +117,6 @@ If you have questions concerning this license or the applicable additional terms
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ID_OPENAL
|
||||
# if ( defined(_WIN32) || defined(MACOS_X) ) && !defined( ID_DEDICATED )
|
||||
# define ID_OPENAL 1
|
||||
# else
|
||||
# define ID_OPENAL 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ID_ALLOW_D3XP
|
||||
# if defined( MACOS_X )
|
||||
# define ID_ALLOW_D3XP 0
|
||||
@@ -137,4 +129,4 @@ If you have questions concerning this license or the applicable additional terms
|
||||
#ifdef PREY
|
||||
#define DEATHWALK_AUTOLOAD 1 // Append deathwalk map to all maps loaded
|
||||
#endif
|
||||
// jmarshall end
|
||||
// jmarshall end
|
||||
|
||||
@@ -2892,6 +2892,254 @@ void Com_FinishBuild_f( const idCmdArgs &args ) {
|
||||
globalImages->FinishBuild( ( args.Argc() > 1 ) );
|
||||
}
|
||||
|
||||
#ifdef ID_ALLOW_TOOLS
|
||||
/*
|
||||
=================
|
||||
Com_RemoveBloodDecalBrushes_f
|
||||
=================
|
||||
*/
|
||||
static bool Com_IsMapBlockBloodDecal( const char *blockStart, const char *blockEnd ) {
|
||||
const char *scan = blockStart;
|
||||
|
||||
while ( scan < blockEnd ) {
|
||||
int materialOffset = idStr::FindText( scan, "\"textures/decals/", false );
|
||||
if ( materialOffset < 0 ) {
|
||||
break;
|
||||
}
|
||||
const char *materialStart = scan + materialOffset;
|
||||
if ( materialStart >= blockEnd ) {
|
||||
break;
|
||||
}
|
||||
|
||||
const char *materialEnd = strchr( materialStart + 1, '"' );
|
||||
if ( !materialEnd || materialEnd > blockEnd ) {
|
||||
break;
|
||||
}
|
||||
|
||||
idStr materialName( materialStart + 1, 0, materialEnd - materialStart - 1 );
|
||||
const idMaterial *material = declManager->FindMaterial( materialName, false );
|
||||
if ( material && ( material->GetContentFlags() & CONTENTS_BLOOD ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( idStr::FindText( materialName, "blood", false ) >= 0 ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
scan = materialEnd + 1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static const char *Com_FindMapBlockEnd( const char *blockStart ) {
|
||||
bool inString = false;
|
||||
bool inLineComment = false;
|
||||
bool inBlockComment = false;
|
||||
int depth = 0;
|
||||
|
||||
for ( const char *scan = blockStart; *scan; scan++ ) {
|
||||
if ( inLineComment ) {
|
||||
if ( *scan == '\n' ) {
|
||||
inLineComment = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( inBlockComment ) {
|
||||
if ( scan[0] == '*' && scan[1] == '/' ) {
|
||||
inBlockComment = false;
|
||||
scan++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( inString ) {
|
||||
if ( *scan == '\\' && scan[1] ) {
|
||||
scan++;
|
||||
} else if ( *scan == '"' ) {
|
||||
inString = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( scan[0] == '/' && scan[1] == '/' ) {
|
||||
inLineComment = true;
|
||||
scan++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( scan[0] == '/' && scan[1] == '*' ) {
|
||||
inBlockComment = true;
|
||||
scan++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( *scan == '"' ) {
|
||||
inString = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( *scan == '{' ) {
|
||||
depth++;
|
||||
} else if ( *scan == '}' ) {
|
||||
depth--;
|
||||
if ( depth == 0 ) {
|
||||
return scan + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool Com_IsMapWhitespace( char c ) {
|
||||
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
|
||||
}
|
||||
|
||||
static const char *Com_FindPrimitiveCommentStart( const char *bufferStart, const char *blockStart ) {
|
||||
const char *lineStart = blockStart;
|
||||
|
||||
while ( lineStart > bufferStart && lineStart[-1] != '\n' && lineStart[-1] != '\r' ) {
|
||||
lineStart--;
|
||||
}
|
||||
|
||||
while ( lineStart > bufferStart ) {
|
||||
const char *prevLineEnd = lineStart;
|
||||
while ( prevLineEnd > bufferStart && ( prevLineEnd[-1] == '\n' || prevLineEnd[-1] == '\r' ) ) {
|
||||
prevLineEnd--;
|
||||
}
|
||||
|
||||
const char *prevLineStart = prevLineEnd;
|
||||
while ( prevLineStart > bufferStart && prevLineStart[-1] != '\n' && prevLineStart[-1] != '\r' ) {
|
||||
prevLineStart--;
|
||||
}
|
||||
|
||||
const char *trimmedLineStart = prevLineStart;
|
||||
while ( trimmedLineStart < prevLineEnd && Com_IsMapWhitespace( *trimmedLineStart ) ) {
|
||||
trimmedLineStart++;
|
||||
}
|
||||
|
||||
const char *trimmedLineEnd = prevLineEnd;
|
||||
while ( trimmedLineEnd > trimmedLineStart && Com_IsMapWhitespace( trimmedLineEnd[-1] ) ) {
|
||||
trimmedLineEnd--;
|
||||
}
|
||||
|
||||
if ( idStr::Icmpn( trimmedLineStart, "// primitive", 12 ) == 0 ) {
|
||||
return prevLineStart;
|
||||
}
|
||||
|
||||
if ( trimmedLineStart != trimmedLineEnd ) {
|
||||
break;
|
||||
}
|
||||
|
||||
lineStart = prevLineStart;
|
||||
}
|
||||
|
||||
return blockStart;
|
||||
}
|
||||
|
||||
void Com_RemoveBloodDecalBrushes_f( const idCmdArgs &args ) {
|
||||
if ( args.Argc() < 2 || args.Argc() > 3 ) {
|
||||
common->Printf( "Usage: removeBloodDecalBrushes <map> [outputMap]\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
idStr inputMap = args.Argv( 1 );
|
||||
idStr outputMap = ( args.Argc() > 2 ) ? args.Argv( 2 ) : args.Argv( 1 );
|
||||
inputMap.SetFileExtension( ".map" );
|
||||
outputMap.SetFileExtension( ".map" );
|
||||
|
||||
char *buffer = NULL;
|
||||
int bufferLength = fileSystem->ReadFile( inputMap, (void **)&buffer );
|
||||
if ( bufferLength <= 0 || !buffer ) {
|
||||
common->Printf( "removeBloodDecalBrushes: failed to load '%s'\n", inputMap.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
idStr out;
|
||||
|
||||
const char *bufferStart = buffer;
|
||||
const char *bufferEnd = buffer + bufferLength;
|
||||
const char *worldStart = strchr( bufferStart, '{' );
|
||||
if ( !worldStart ) {
|
||||
fileSystem->FreeFile( buffer );
|
||||
common->Printf( "removeBloodDecalBrushes: '%s' has no worldspawn entity\n", inputMap.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
const char *worldEnd = Com_FindMapBlockEnd( worldStart );
|
||||
if ( !worldEnd ) {
|
||||
fileSystem->FreeFile( buffer );
|
||||
common->Printf( "removeBloodDecalBrushes: '%s' has an unterminated worldspawn entity\n", inputMap.c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
const char *copyStart = bufferStart;
|
||||
const char *scan = worldStart;
|
||||
int removed = 0;
|
||||
|
||||
while ( scan < worldEnd ) {
|
||||
int brushDefOffset = idStr::FindText( scan, "brushDef", false );
|
||||
int patchDefOffset = idStr::FindText( scan, "patchDef", false );
|
||||
if ( brushDefOffset < 0 && patchDefOffset < 0 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
int primitiveDefOffset;
|
||||
if ( brushDefOffset < 0 ) {
|
||||
primitiveDefOffset = patchDefOffset;
|
||||
} else if ( patchDefOffset < 0 ) {
|
||||
primitiveDefOffset = brushDefOffset;
|
||||
} else {
|
||||
primitiveDefOffset = ( brushDefOffset < patchDefOffset ) ? brushDefOffset : patchDefOffset;
|
||||
}
|
||||
|
||||
const char *primitiveDef = scan + primitiveDefOffset;
|
||||
if ( primitiveDef >= worldEnd ) {
|
||||
break;
|
||||
}
|
||||
|
||||
const char *blockStart = primitiveDef;
|
||||
while ( blockStart > bufferStart && *blockStart != '{' ) {
|
||||
blockStart--;
|
||||
}
|
||||
|
||||
if ( *blockStart != '{' ) {
|
||||
scan = primitiveDef + 8;
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *blockEnd = Com_FindMapBlockEnd( blockStart );
|
||||
if ( !blockEnd ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( Com_IsMapBlockBloodDecal( blockStart, blockEnd ) ) {
|
||||
const char *removeStart = Com_FindPrimitiveCommentStart( bufferStart, blockStart );
|
||||
out.Append( copyStart, removeStart - copyStart );
|
||||
copyStart = blockEnd;
|
||||
removed++;
|
||||
}
|
||||
|
||||
scan = blockEnd;
|
||||
}
|
||||
|
||||
out.Append( copyStart, bufferEnd - copyStart );
|
||||
fileSystem->FreeFile( buffer );
|
||||
|
||||
idFile *outFile = fileSystem->OpenFileWrite( outputMap, "fs_devpath" );
|
||||
if ( !outFile ) {
|
||||
common->Printf( "removeBloodDecalBrushes: failed to save '%s'\n", outputMap.c_str() );
|
||||
return;
|
||||
}
|
||||
outFile->Write( out.c_str(), out.Length() );
|
||||
fileSystem->CloseFile( outFile );
|
||||
|
||||
common->Printf( "removeBloodDecalBrushes: %d surfaces removed\n", removed );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
==============
|
||||
Com_Help_f
|
||||
@@ -2954,6 +3202,7 @@ void idCommonLocal::InitCommands( void ) {
|
||||
|
||||
#ifdef ID_ALLOW_TOOLS
|
||||
cmdSystem->AddCommand("nnbuildmat", nnbuildmat_f, CMD_FL_TOOL, "confidential");
|
||||
cmdSystem->AddCommand( "removeBloodDecalBrushes", Com_RemoveBloodDecalBrushes_f, CMD_FL_TOOL, "removes blood decal brushes from a map", idCmdSystem::ArgCompletion_MapName );
|
||||
|
||||
// editors
|
||||
cmdSystem->AddCommand( "editor", Com_Editor_f, CMD_FL_TOOL, "launches the level editor Radiant" );
|
||||
|
||||
@@ -912,8 +912,6 @@ void idSessionLocal::HandleMainMenuCommands( const char *menuCommand ) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// also turn off OpenAL so we fully go back to legacy mixer
|
||||
cvarSystem->SetCVarBool( "s_useOpenAL", false );
|
||||
// when you restart
|
||||
MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_04137" ), common->GetLanguageDict()->GetString( "#str_07231" ), true );
|
||||
}
|
||||
|
||||
@@ -93,9 +93,7 @@ const float MAX_BOUND_SIZE = 65536.0f;
|
||||
#include <mmreg.h>
|
||||
|
||||
#define DIRECTINPUT_VERSION 0x0800 // was 0x0700 with the old mssdk
|
||||
#define DIRECTSOUND_VERSION 0x0800
|
||||
|
||||
#include <dsound.h>
|
||||
// #include <dinput.h>
|
||||
#include "../opengl/DirectInputShim.h"
|
||||
|
||||
|
||||
@@ -1,345 +0,0 @@
|
||||
/******************************************************************
|
||||
*
|
||||
* EAX.H - DirectSound3D Environmental Audio Extensions version 2.0
|
||||
* Updated July 8, 1999
|
||||
*
|
||||
*******************************************************************
|
||||
*/
|
||||
|
||||
#ifndef EAX20_H_INCLUDED
|
||||
#define EAX20_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
/*
|
||||
* EAX 2.0 listener property set {0306A6A8-B224-11d2-99E5-0000E8D8C722}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX20_ListenerProperties,
|
||||
0x306a6a8,
|
||||
0xb224,
|
||||
0x11d2,
|
||||
0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAX20LISTENER_NONE,
|
||||
DSPROPERTY_EAX20LISTENER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAX20LISTENER_ROOM,
|
||||
DSPROPERTY_EAX20LISTENER_ROOMHF,
|
||||
DSPROPERTY_EAX20LISTENER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAX20LISTENER_DECAYTIME,
|
||||
DSPROPERTY_EAX20LISTENER_DECAYHFRATIO,
|
||||
DSPROPERTY_EAX20LISTENER_REFLECTIONS,
|
||||
DSPROPERTY_EAX20LISTENER_REFLECTIONSDELAY,
|
||||
DSPROPERTY_EAX20LISTENER_REVERB,
|
||||
DSPROPERTY_EAX20LISTENER_REVERBDELAY,
|
||||
DSPROPERTY_EAX20LISTENER_ENVIRONMENT,
|
||||
DSPROPERTY_EAX20LISTENER_ENVIRONMENTSIZE,
|
||||
DSPROPERTY_EAX20LISTENER_ENVIRONMENTDIFFUSION,
|
||||
DSPROPERTY_EAX20LISTENER_AIRABSORPTIONHF,
|
||||
DSPROPERTY_EAX20LISTENER_FLAGS
|
||||
} DSPROPERTY_EAX20_LISTENERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAX20LISTENER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAX20LISTENER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAX20LISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAX20LISTENER_NONE | \
|
||||
DSPROPERTY_EAX20LISTENER_IMMEDIATE)
|
||||
|
||||
// Use this structure for DSPROPERTY_EAX20LISTENER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
// - all times are in seconds
|
||||
// - the reference for high frequency controls is 5 kHz
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myListener.lRoom = -1000;
|
||||
// myListener.lRoomHF = -100;
|
||||
// ...
|
||||
// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myListener = { -1000, -100, ... , 0x00000009 };
|
||||
// If you want to save and load presets in binary form, you
|
||||
// should define your own structure to insure future compatibility.
|
||||
//
|
||||
typedef struct _EAX20LISTENERPROPERTIES
|
||||
{
|
||||
long lRoom; // room effect level at low frequencies
|
||||
long lRoomHF; // room effect high-frequency level re. low frequency level
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
float flDecayTime; // reverberation decay time at low frequencies
|
||||
float flDecayHFRatio; // high-frequency to low-frequency decay time ratio
|
||||
long lReflections; // early reflections level relative to room effect
|
||||
float flReflectionsDelay; // initial reflection delay time
|
||||
long lReverb; // late reverberation level relative to room effect
|
||||
float flReverbDelay; // late reverberation delay time relative to initial reflection
|
||||
unsigned long dwEnvironment; // sets all listener properties
|
||||
float flEnvironmentSize; // environment size in meters
|
||||
float flEnvironmentDiffusion; // environment diffusion
|
||||
float flAirAbsorptionHF; // change in level per meter at 5 kHz
|
||||
unsigned long dwFlags; // modifies the behavior of properties
|
||||
} EAX20LISTENERPROPERTIES, *LPEAX20LISTENERPROPERTIES;
|
||||
|
||||
// used by DSPROPERTY_EAX20LISTENER_ENVIRONMENT
|
||||
enum
|
||||
{
|
||||
EAX20_ENVIRONMENT_GENERIC,
|
||||
EAX20_ENVIRONMENT_PADDEDCELL,
|
||||
EAX20_ENVIRONMENT_ROOM,
|
||||
EAX20_ENVIRONMENT_BATHROOM,
|
||||
EAX20_ENVIRONMENT_LIVINGROOM,
|
||||
EAX20_ENVIRONMENT_STONEROOM,
|
||||
EAX20_ENVIRONMENT_AUDITORIUM,
|
||||
EAX20_ENVIRONMENT_CONCERTHALL,
|
||||
EAX20_ENVIRONMENT_CAVE,
|
||||
EAX20_ENVIRONMENT_ARENA,
|
||||
EAX20_ENVIRONMENT_HANGAR,
|
||||
EAX20_ENVIRONMENT_CARPETEDHALLWAY,
|
||||
EAX20_ENVIRONMENT_HALLWAY,
|
||||
EAX20_ENVIRONMENT_STONECORRIDOR,
|
||||
EAX20_ENVIRONMENT_ALLEY,
|
||||
EAX20_ENVIRONMENT_FOREST,
|
||||
EAX20_ENVIRONMENT_CITY,
|
||||
EAX20_ENVIRONMENT_MOUNTAINS,
|
||||
EAX20_ENVIRONMENT_QUARRY,
|
||||
EAX20_ENVIRONMENT_PLAIN,
|
||||
EAX20_ENVIRONMENT_PARKINGLOT,
|
||||
EAX20_ENVIRONMENT_SEWERPIPE,
|
||||
EAX20_ENVIRONMENT_UNDERWATER,
|
||||
EAX20_ENVIRONMENT_DRUGGED,
|
||||
EAX20_ENVIRONMENT_DIZZY,
|
||||
EAX20_ENVIRONMENT_PSYCHOTIC,
|
||||
|
||||
EAX20_ENVIRONMENT_COUNT
|
||||
};
|
||||
|
||||
// Used by DS20PROPERTY_EAXLISTENER_FLAGS
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// It is recommended to use the flag defines as follows:
|
||||
// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE;
|
||||
// instead of:
|
||||
// myFlags = 0x00000009;
|
||||
//
|
||||
// These flags determine what properties are affected by environment size.
|
||||
#define EAX20LISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time
|
||||
#define EAX20LISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level
|
||||
#define EAX20LISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time
|
||||
#define EAX20LISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level
|
||||
#define EAX20LISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time
|
||||
|
||||
// This flag limits high-frequency decay time according to air absorption.
|
||||
#define EAX20LISTENERFLAGS_DECAYHFLIMIT 0x00000020
|
||||
|
||||
#define EAX20LISTENERFLAGS_RESERVED 0xFFFFFFC0 // reserved future use
|
||||
|
||||
// property ranges and defaults:
|
||||
|
||||
#define EAX20LISTENER_MINROOM (-10000)
|
||||
#define EAX20LISTENER_MAXROOM 0
|
||||
#define EAX20LISTENER_DEFAULTROOM (-1000)
|
||||
|
||||
#define EAX20LISTENER_MINROOMHF (-10000)
|
||||
#define EAX20LISTENER_MAXROOMHF 0
|
||||
#define EAX20LISTENER_DEFAULTROOMHF (-100)
|
||||
|
||||
#define EAX20LISTENER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAX20LISTENER_MAXROOMROLLOFFFACTOR 10.0f
|
||||
#define EAX20LISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAX20LISTENER_MINDECAYTIME 0.1f
|
||||
#define EAX20LISTENER_MAXDECAYTIME 20.0f
|
||||
#define EAX20LISTENER_DEFAULTDECAYTIME 1.49f
|
||||
|
||||
#define EAX20LISTENER_MINDECAYHFRATIO 0.1f
|
||||
#define EAX20LISTENER_MAXDECAYHFRATIO 2.0f
|
||||
#define EAX20LISTENER_DEFAULTDECAYHFRATIO 0.83f
|
||||
|
||||
#define EAX20LISTENER_MINREFLECTIONS (-10000)
|
||||
#define EAX20LISTENER_MAXREFLECTIONS 1000
|
||||
#define EAX20LISTENER_DEFAULTREFLECTIONS (-2602)
|
||||
|
||||
#define EAX20LISTENER_MINREFLECTIONSDELAY 0.0f
|
||||
#define EAX20LISTENER_MAXREFLECTIONSDELAY 0.3f
|
||||
#define EAX20LISTENER_DEFAULTREFLECTIONSDELAY 0.007f
|
||||
|
||||
#define EAX20LISTENER_MINREVERB (-10000)
|
||||
#define EAX20LISTENER_MAXREVERB 2000
|
||||
#define EAX20LISTENER_DEFAULTREVERB 200
|
||||
|
||||
#define EAX20LISTENER_MINREVERBDELAY 0.0f
|
||||
#define EAX20LISTENER_MAXREVERBDELAY 0.1f
|
||||
#define EAX20LISTENER_DEFAULTREVERBDELAY 0.011f
|
||||
|
||||
#define EAX20LISTENER_MINENVIRONMENT 0
|
||||
#define EAX20LISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1)
|
||||
#define EAX20LISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC
|
||||
|
||||
#define EAX20LISTENER_MINENVIRONMENTSIZE 1.0f
|
||||
#define EAX20LISTENER_MAXENVIRONMENTSIZE 100.0f
|
||||
#define EAX20LISTENER_DEFAULTENVIRONMENTSIZE 7.5f
|
||||
|
||||
#define EAX20LISTENER_MINENVIRONMENTDIFFUSION 0.0f
|
||||
#define EAX20LISTENER_MAXENVIRONMENTDIFFUSION 1.0f
|
||||
#define EAX20LISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f
|
||||
|
||||
#define EAX20LISTENER_MINAIRABSORPTIONHF (-100.0f)
|
||||
#define EAX20LISTENER_MAXAIRABSORPTIONHF 0.0f
|
||||
#define EAX20LISTENER_DEFAULTAIRABSORPTIONHF (-5.0f)
|
||||
|
||||
#define EAX20LISTENER_DEFAULTFLAGS (EAX20LISTENERFLAGS_DECAYTIMESCALE | \
|
||||
EAX20LISTENERFLAGS_REFLECTIONSSCALE | \
|
||||
EAX20LISTENERFLAGS_REFLECTIONSDELAYSCALE | \
|
||||
EAX20LISTENERFLAGS_REVERBSCALE | \
|
||||
EAX20LISTENERFLAGS_REVERBDELAYSCALE | \
|
||||
EAX20LISTENERFLAGS_DECAYHFLIMIT)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EAX 2.0 buffer property set {0306A6A7-B224-11d2-99E5-0000E8D8C722}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX20_BufferProperties,
|
||||
0x306a6a7,
|
||||
0xb224,
|
||||
0x11d2,
|
||||
0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX20_BufferProperties DSPROPSETID_EAX20_BufferProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAX20BUFFER_NONE,
|
||||
DSPROPERTY_EAX20BUFFER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAX20BUFFER_DIRECT,
|
||||
DSPROPERTY_EAX20BUFFER_DIRECTHF,
|
||||
DSPROPERTY_EAX20BUFFER_ROOM,
|
||||
DSPROPERTY_EAX20BUFFER_ROOMHF,
|
||||
DSPROPERTY_EAX20BUFFER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAX20BUFFER_OBSTRUCTION,
|
||||
DSPROPERTY_EAX20BUFFER_OBSTRUCTIONLFRATIO,
|
||||
DSPROPERTY_EAX20BUFFER_OCCLUSION,
|
||||
DSPROPERTY_EAX20BUFFER_OCCLUSIONLFRATIO,
|
||||
DSPROPERTY_EAX20BUFFER_OCCLUSIONROOMRATIO,
|
||||
DSPROPERTY_EAX20BUFFER_OUTSIDEVOLUMEHF,
|
||||
DSPROPERTY_EAX20BUFFER_AIRABSORPTIONFACTOR,
|
||||
DSPROPERTY_EAX20BUFFER_FLAGS
|
||||
} DSPROPERTY_EAX20_BUFFERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAX20BUFFER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAX20BUFFER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAX20BUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAX20BUFFER_NONE | \
|
||||
DSPROPERTY_EAX20BUFFER_IMMEDIATE)
|
||||
|
||||
// Use this structure for DSPROPERTY_EAX20BUFFER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myBuffer.lDirect = 0;
|
||||
// myBuffer.lDirectHF = -200;
|
||||
// ...
|
||||
// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myBuffer = { 0, -200, ... , 0x00000003 };
|
||||
//
|
||||
typedef struct _EAX20BUFFERPROPERTIES
|
||||
{
|
||||
long lDirect; // direct path level
|
||||
long lDirectHF; // direct path level at high frequencies
|
||||
long lRoom; // room effect level
|
||||
long lRoomHF; // room effect level at high frequencies
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
long lObstruction; // main obstruction control (attenuation at high frequencies)
|
||||
float flObstructionLFRatio; // obstruction low-frequency level re. main control
|
||||
long lOcclusion; // main occlusion control (attenuation at high frequencies)
|
||||
float flOcclusionLFRatio; // occlusion low-frequency level re. main control
|
||||
float flOcclusionRoomRatio; // occlusion room effect level re. main control
|
||||
long lOutsideVolumeHF; // outside sound cone level at high frequencies
|
||||
float flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF
|
||||
unsigned long dwFlags; // modifies the behavior of properties
|
||||
} EAX20BUFFERPROPERTIES, *LPEAX20BUFFERPROPERTIES;
|
||||
|
||||
// Used by DSPROPERTY_EAX20BUFFER_FLAGS
|
||||
// TRUE: value is computed automatically - property is an offset
|
||||
// FALSE: value is used directly
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// To insure future compatibility, use flag defines as follows:
|
||||
// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO;
|
||||
// instead of:
|
||||
// myFlags = 0x00000003;
|
||||
//
|
||||
#define EAX20BUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF
|
||||
#define EAX20BUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM
|
||||
#define EAX20BUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF
|
||||
|
||||
#define EAX20BUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use
|
||||
|
||||
// property ranges and defaults:
|
||||
|
||||
#define EAX20BUFFER_MINDIRECT (-10000)
|
||||
#define EAX20BUFFER_MAXDIRECT 1000
|
||||
#define EAX20BUFFER_DEFAULTDIRECT 0
|
||||
|
||||
#define EAX20BUFFER_MINDIRECTHF (-10000)
|
||||
#define EAX20BUFFER_MAXDIRECTHF 0
|
||||
#define EAX20BUFFER_DEFAULTDIRECTHF 0
|
||||
|
||||
#define EAX20BUFFER_MINROOM (-10000)
|
||||
#define EAX20BUFFER_MAXROOM 1000
|
||||
#define EAX20BUFFER_DEFAULTROOM 0
|
||||
|
||||
#define EAX20BUFFER_MINROOMHF (-10000)
|
||||
#define EAX20BUFFER_MAXROOMHF 0
|
||||
#define EAX20BUFFER_DEFAULTROOMHF 0
|
||||
|
||||
#define EAX20BUFFER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAX20BUFFER_MAXROOMROLLOFFFACTOR 10.f
|
||||
#define EAX20BUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAX20BUFFER_MINOBSTRUCTION (-10000)
|
||||
#define EAX20BUFFER_MAXOBSTRUCTION 0
|
||||
#define EAX20BUFFER_DEFAULTOBSTRUCTION 0
|
||||
|
||||
#define EAX20BUFFER_MINOBSTRUCTIONLFRATIO 0.0f
|
||||
#define EAX20BUFFER_MAXOBSTRUCTIONLFRATIO 1.0f
|
||||
#define EAX20BUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f
|
||||
|
||||
#define EAX20BUFFER_MINOCCLUSION (-10000)
|
||||
#define EAX20BUFFER_MAXOCCLUSION 0
|
||||
#define EAX20BUFFER_DEFAULTOCCLUSION 0
|
||||
|
||||
#define EAX20BUFFER_MINOCCLUSIONLFRATIO 0.0f
|
||||
#define EAX20BUFFER_MAXOCCLUSIONLFRATIO 1.0f
|
||||
#define EAX20BUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f
|
||||
|
||||
#define EAX20BUFFER_MINOCCLUSIONROOMRATIO 0.0f
|
||||
#define EAX20BUFFER_MAXOCCLUSIONROOMRATIO 10.0f
|
||||
#define EAX20BUFFER_DEFAULTOCCLUSIONROOMRATIO 0.5f
|
||||
|
||||
#define EAX20BUFFER_MINOUTSIDEVOLUMEHF (-10000)
|
||||
#define EAX20BUFFER_MAXOUTSIDEVOLUMEHF 0
|
||||
#define EAX20BUFFER_DEFAULTOUTSIDEVOLUMEHF 0
|
||||
|
||||
#define EAX20BUFFER_MINAIRABSORPTIONFACTOR 0.0f
|
||||
#define EAX20BUFFER_MAXAIRABSORPTIONFACTOR 10.0f
|
||||
#define EAX20BUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f
|
||||
|
||||
#define EAX20BUFFER_DEFAULTFLAGS (EAX20BUFFERFLAGS_DIRECTHFAUTO | \
|
||||
EAX20BUFFERFLAGS_ROOMAUTO | \
|
||||
EAX20BUFFERFLAGS_ROOMHFAUTO)
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -1,547 +0,0 @@
|
||||
/*******************************************************************\
|
||||
* *
|
||||
* EAX.H - Environmental Audio Extensions version 3.0 *
|
||||
* for OpenAL and DirectSound3D *
|
||||
* *
|
||||
********************************************************************/
|
||||
|
||||
#ifndef EAX30_H_INCLUDED
|
||||
#define EAX30_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef OPENAL
|
||||
#include <dsound.h>
|
||||
|
||||
/*
|
||||
* EAX Wrapper Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound,
|
||||
0x4ff53b81,
|
||||
0x1ce0,
|
||||
0x11d3,
|
||||
0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5);
|
||||
|
||||
/*
|
||||
* EAX Wrapper Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound8,
|
||||
0xca503b60,
|
||||
0xb176,
|
||||
0x11d4,
|
||||
0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc);
|
||||
|
||||
|
||||
|
||||
#ifdef DIRECTSOUND_VERSION
|
||||
#if DIRECTSOUND_VERSION == 0x0800
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND8*, IUnknown FAR*);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*);
|
||||
|
||||
#else // OPENAL
|
||||
//#include <al.h>
|
||||
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
typedef struct _GUID
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[8];
|
||||
} GUID;
|
||||
#endif // !GUID_DEFINED
|
||||
|
||||
#ifndef DEFINE_GUID
|
||||
#ifndef INITGUID
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID /*FAR*/ name
|
||||
#else
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
#endif // INITGUID
|
||||
#endif // DEFINE_GUID
|
||||
|
||||
|
||||
/*
|
||||
* EAX OpenAL Extension
|
||||
*/
|
||||
typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALboolean (*EAXSetBufferMode)(ALsizei,ALuint*,ALint);
|
||||
typedef ALenum (*EAXGetBufferMode)(ALuint,ALint*);
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
/*
|
||||
* EAX 3.0 listener property set {A8FA6880-B476-11d3-BDB9-00C0F02DDF87}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX30_ListenerProperties,
|
||||
0xa8fa6882,
|
||||
0xb476,
|
||||
0x11d3,
|
||||
0xbd, 0xb9, 0x00, 0xc0, 0xf0, 0x2d, 0xdf, 0x87);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX_ListenerProperties DSPROPSETID_EAX30_ListenerProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXLISTENER_NONE,
|
||||
DSPROPERTY_EAXLISTENER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENT,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION,
|
||||
DSPROPERTY_EAXLISTENER_ROOM,
|
||||
DSPROPERTY_EAXLISTENER_ROOMHF,
|
||||
DSPROPERTY_EAXLISTENER_ROOMLF,
|
||||
DSPROPERTY_EAXLISTENER_DECAYTIME,
|
||||
DSPROPERTY_EAXLISTENER_DECAYHFRATIO,
|
||||
DSPROPERTY_EAXLISTENER_DECAYLFRATIO,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONS,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONSPAN,
|
||||
DSPROPERTY_EAXLISTENER_REVERB,
|
||||
DSPROPERTY_EAXLISTENER_REVERBDELAY,
|
||||
DSPROPERTY_EAXLISTENER_REVERBPAN,
|
||||
DSPROPERTY_EAXLISTENER_ECHOTIME,
|
||||
DSPROPERTY_EAXLISTENER_ECHODEPTH,
|
||||
DSPROPERTY_EAXLISTENER_MODULATIONTIME,
|
||||
DSPROPERTY_EAXLISTENER_MODULATIONDEPTH,
|
||||
DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF,
|
||||
DSPROPERTY_EAXLISTENER_HFREFERENCE,
|
||||
DSPROPERTY_EAXLISTENER_LFREFERENCE,
|
||||
DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXLISTENER_FLAGS
|
||||
} DSPROPERTY_EAX_LISTENERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAXLISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXLISTENER_NONE | \
|
||||
DSPROPERTY_EAXLISTENER_IMMEDIATE)
|
||||
#ifndef EAXVECTOR_DEFINED
|
||||
#define EAXVECTOR_DEFINED
|
||||
typedef struct _EAXVECTOR {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} EAXVECTOR;
|
||||
#endif
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXLISTENER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
// - all times and delays are in seconds
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myListener.lRoom = -1000;
|
||||
// myListener.lRoomHF = -100;
|
||||
// ...
|
||||
// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myListener = { -1000, -100, ... , 0x00000009 };
|
||||
// If you want to save and load presets in binary form, you
|
||||
// should define your own structure to insure future compatibility.
|
||||
//
|
||||
typedef struct _EAXLISTENERPROPERTIES
|
||||
{
|
||||
unsigned long ulEnvironment; // sets all listener properties
|
||||
float flEnvironmentSize; // environment size in meters
|
||||
float flEnvironmentDiffusion; // environment diffusion
|
||||
long lRoom; // room effect level (at mid frequencies)
|
||||
long lRoomHF; // relative room effect level at high frequencies
|
||||
long lRoomLF; // relative room effect level at low frequencies
|
||||
float flDecayTime; // reverberation decay time at mid frequencies
|
||||
float flDecayHFRatio; // high-frequency to mid-frequency decay time ratio
|
||||
float flDecayLFRatio; // low-frequency to mid-frequency decay time ratio
|
||||
long lReflections; // early reflections level relative to room effect
|
||||
float flReflectionsDelay; // initial reflection delay time
|
||||
EAXVECTOR vReflectionsPan; // early reflections panning vector
|
||||
long lReverb; // late reverberation level relative to room effect
|
||||
float flReverbDelay; // late reverberation delay time relative to initial reflection
|
||||
EAXVECTOR vReverbPan; // late reverberation panning vector
|
||||
float flEchoTime; // echo time
|
||||
float flEchoDepth; // echo depth
|
||||
float flModulationTime; // modulation time
|
||||
float flModulationDepth; // modulation depth
|
||||
float flAirAbsorptionHF; // change in level per meter at high frequencies
|
||||
float flHFReference; // reference high frequency
|
||||
float flLFReference; // reference low frequency
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
unsigned long ulFlags; // modifies the behavior of properties
|
||||
} EAXLISTENERPROPERTIES, *LPEAXLISTENERPROPERTIES;
|
||||
|
||||
// used by DSPROPERTY_EAXLISTENER_ENVIRONMENT
|
||||
#ifndef EAX_ENVIRONMENTS_DEFINED
|
||||
#define EAX_ENVIRONMENTS_DEFINED
|
||||
enum
|
||||
{
|
||||
EAX_ENVIRONMENT_GENERIC,
|
||||
EAX_ENVIRONMENT_PADDEDCELL,
|
||||
EAX_ENVIRONMENT_ROOM,
|
||||
EAX_ENVIRONMENT_BATHROOM,
|
||||
EAX_ENVIRONMENT_LIVINGROOM,
|
||||
EAX_ENVIRONMENT_STONEROOM,
|
||||
EAX_ENVIRONMENT_AUDITORIUM,
|
||||
EAX_ENVIRONMENT_CONCERTHALL,
|
||||
EAX_ENVIRONMENT_CAVE,
|
||||
EAX_ENVIRONMENT_ARENA,
|
||||
EAX_ENVIRONMENT_HANGAR,
|
||||
EAX_ENVIRONMENT_CARPETEDHALLWAY,
|
||||
EAX_ENVIRONMENT_HALLWAY,
|
||||
EAX_ENVIRONMENT_STONECORRIDOR,
|
||||
EAX_ENVIRONMENT_ALLEY,
|
||||
EAX_ENVIRONMENT_FOREST,
|
||||
EAX_ENVIRONMENT_CITY,
|
||||
EAX_ENVIRONMENT_MOUNTAINS,
|
||||
EAX_ENVIRONMENT_QUARRY,
|
||||
EAX_ENVIRONMENT_PLAIN,
|
||||
EAX_ENVIRONMENT_PARKINGLOT,
|
||||
EAX_ENVIRONMENT_SEWERPIPE,
|
||||
EAX_ENVIRONMENT_UNDERWATER,
|
||||
EAX_ENVIRONMENT_DRUGGED,
|
||||
EAX_ENVIRONMENT_DIZZY,
|
||||
EAX_ENVIRONMENT_PSYCHOTIC,
|
||||
|
||||
EAX_ENVIRONMENT_UNDEFINED,
|
||||
|
||||
EAX_ENVIRONMENT_COUNT
|
||||
};
|
||||
#endif
|
||||
|
||||
// Used by DSPROPERTY_EAXLISTENER_FLAGS
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// It is recommended to use the flag defines as follows:
|
||||
// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE;
|
||||
// instead of:
|
||||
// myFlags = 0x00000009;
|
||||
//
|
||||
// These flags determine what properties are affected by environment size.
|
||||
#define EAXLISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time
|
||||
#define EAXLISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level
|
||||
#define EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time
|
||||
#define EAXLISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level
|
||||
#define EAXLISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time
|
||||
#define EAXLISTENERFLAGS_ECHOTIMESCALE 0x00000040 // echo time
|
||||
#define EAXLISTENERFLAGS_MODULATIONTIMESCALE 0x00000080 // modulation time
|
||||
|
||||
// This flag limits high-frequency decay time according to air absorption.
|
||||
#define EAXLISTENERFLAGS_DECAYHFLIMIT 0x00000020
|
||||
|
||||
#define EAXLISTENERFLAGS_RESERVED 0xFFFFFF00 // reserved future use
|
||||
|
||||
// Property ranges and defaults:
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENT 0
|
||||
#define EAXLISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1)
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENTSIZE 1.0f
|
||||
#define EAXLISTENER_MAXENVIRONMENTSIZE 100.0f
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENTSIZE 7.5f
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENTDIFFUSION 0.0f
|
||||
#define EAXLISTENER_MAXENVIRONMENTDIFFUSION 1.0f
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f
|
||||
|
||||
#define EAXLISTENER_MINROOM (-10000)
|
||||
#define EAXLISTENER_MAXROOM 0
|
||||
#define EAXLISTENER_DEFAULTROOM (-1000)
|
||||
|
||||
#define EAXLISTENER_MINROOMHF (-10000)
|
||||
#define EAXLISTENER_MAXROOMHF 0
|
||||
#define EAXLISTENER_DEFAULTROOMHF (-100)
|
||||
|
||||
#define EAXLISTENER_MINROOMLF (-10000)
|
||||
#define EAXLISTENER_MAXROOMLF 0
|
||||
#define EAXLISTENER_DEFAULTROOMLF 0
|
||||
|
||||
#define EAXLISTENER_MINDECAYTIME 0.1f
|
||||
#define EAXLISTENER_MAXDECAYTIME 20.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYTIME 1.49f
|
||||
|
||||
#define EAXLISTENER_MINDECAYHFRATIO 0.1f
|
||||
#define EAXLISTENER_MAXDECAYHFRATIO 2.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYHFRATIO 0.83f
|
||||
|
||||
#define EAXLISTENER_MINDECAYLFRATIO 0.1f
|
||||
#define EAXLISTENER_MAXDECAYLFRATIO 2.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYLFRATIO 1.00f
|
||||
|
||||
#define EAXLISTENER_MINREFLECTIONS (-10000)
|
||||
#define EAXLISTENER_MAXREFLECTIONS 1000
|
||||
#define EAXLISTENER_DEFAULTREFLECTIONS (-2602)
|
||||
|
||||
#define EAXLISTENER_MINREFLECTIONSDELAY 0.0f
|
||||
#define EAXLISTENER_MAXREFLECTIONSDELAY 0.3f
|
||||
#define EAXLISTENER_DEFAULTREFLECTIONSDELAY 0.007f
|
||||
|
||||
#define EAXLISTENER_MINREVERB (-10000)
|
||||
#define EAXLISTENER_MAXREVERB 2000
|
||||
#define EAXLISTENER_DEFAULTREVERB 200
|
||||
|
||||
#define EAXLISTENER_MINREVERBDELAY 0.0f
|
||||
#define EAXLISTENER_MAXREVERBDELAY 0.1f
|
||||
#define EAXLISTENER_DEFAULTREVERBDELAY 0.011f
|
||||
|
||||
#define EAXLISTENER_MINECHOTIME 0.075f
|
||||
#define EAXLISTENER_MAXECHOTIME 0.25f
|
||||
#define EAXLISTENER_DEFAULTECHOTIME 0.25f
|
||||
|
||||
#define EAXLISTENER_MINECHODEPTH 0.0f
|
||||
#define EAXLISTENER_MAXECHODEPTH 1.0f
|
||||
#define EAXLISTENER_DEFAULTECHODEPTH 0.0f
|
||||
|
||||
#define EAXLISTENER_MINMODULATIONTIME 0.04f
|
||||
#define EAXLISTENER_MAXMODULATIONTIME 4.0f
|
||||
#define EAXLISTENER_DEFAULTMODULATIONTIME 0.25f
|
||||
|
||||
#define EAXLISTENER_MINMODULATIONDEPTH 0.0f
|
||||
#define EAXLISTENER_MAXMODULATIONDEPTH 1.0f
|
||||
#define EAXLISTENER_DEFAULTMODULATIONDEPTH 0.0f
|
||||
|
||||
#define EAXLISTENER_MINAIRABSORPTIONHF (-100.0f)
|
||||
#define EAXLISTENER_MAXAIRABSORPTIONHF 0.0f
|
||||
#define EAXLISTENER_DEFAULTAIRABSORPTIONHF (-5.0f)
|
||||
|
||||
#define EAXLISTENER_MINHFREFERENCE 1000.0f
|
||||
#define EAXLISTENER_MAXHFREFERENCE 20000.0f
|
||||
#define EAXLISTENER_DEFAULTHFREFERENCE 5000.0f
|
||||
|
||||
#define EAXLISTENER_MINLFREFERENCE 20.0f
|
||||
#define EAXLISTENER_MAXLFREFERENCE 1000.0f
|
||||
#define EAXLISTENER_DEFAULTLFREFERENCE 250.0f
|
||||
|
||||
#define EAXLISTENER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAXLISTENER_MAXROOMROLLOFFFACTOR 10.0f
|
||||
#define EAXLISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXLISTENER_DEFAULTFLAGS (EAXLISTENERFLAGS_DECAYTIMESCALE | \
|
||||
EAXLISTENERFLAGS_REFLECTIONSSCALE | \
|
||||
EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE | \
|
||||
EAXLISTENERFLAGS_REVERBSCALE | \
|
||||
EAXLISTENERFLAGS_REVERBDELAYSCALE | \
|
||||
EAXLISTENERFLAGS_DECAYHFLIMIT)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EAX 3.0 buffer property set {A8FA6881-B476-11d3-BDB9-00C0F02DDF87}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX30_BufferProperties,
|
||||
0xa8fa6881,
|
||||
0xb476,
|
||||
0x11d3,
|
||||
0xbd, 0xb9, 0x0, 0xc0, 0xf0, 0x2d, 0xdf, 0x87);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX_BufferProperties DSPROPSETID_EAX30_BufferProperties
|
||||
#define DSPROPSETID_EAX_SourceProperties DSPROPSETID_EAX30_BufferProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXBUFFER_NONE,
|
||||
DSPROPERTY_EAXBUFFER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_DIRECT,
|
||||
DSPROPERTY_EAXBUFFER_DIRECTHF,
|
||||
DSPROPERTY_EAXBUFFER_ROOM,
|
||||
DSPROPERTY_EAXBUFFER_ROOMHF,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTION,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSION,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONDIRECTRATIO,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSION,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF,
|
||||
DSPROPERTY_EAXBUFFER_DOPPLERFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_ROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_FLAGS
|
||||
} DSPROPERTY_EAX_BUFFERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAXBUFFER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXBUFFER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAXBUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXBUFFER_NONE | \
|
||||
DSPROPERTY_EAXBUFFER_IMMEDIATE)
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
// - all delays are in seconds
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myBuffer.lDirect = 0;
|
||||
// myBuffer.lDirectHF = -200;
|
||||
// ...
|
||||
// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myBuffer = { 0, -200, ... , 0x00000003 };
|
||||
//
|
||||
typedef struct _EAXBUFFERPROPERTIES
|
||||
{
|
||||
long lDirect; // direct path level (at low and mid frequencies)
|
||||
long lDirectHF; // relative direct path level at high frequencies
|
||||
long lRoom; // room effect level (at low and mid frequencies)
|
||||
long lRoomHF; // relative room effect level at high frequencies
|
||||
long lObstruction; // main obstruction control (attenuation at high frequencies)
|
||||
float flObstructionLFRatio; // obstruction low-frequency level re. main control
|
||||
long lOcclusion; // main occlusion control (attenuation at high frequencies)
|
||||
float flOcclusionLFRatio; // occlusion low-frequency level re. main control
|
||||
float flOcclusionRoomRatio; // relative occlusion control for room effect
|
||||
float flOcclusionDirectRatio; // relative occlusion control for direct path
|
||||
long lExclusion; // main exlusion control (attenuation at high frequencies)
|
||||
float flExclusionLFRatio; // exclusion low-frequency level re. main control
|
||||
long lOutsideVolumeHF; // outside sound cone level at high frequencies
|
||||
float flDopplerFactor; // like DS3D flDopplerFactor but per source
|
||||
float flRolloffFactor; // like DS3D flRolloffFactor but per source
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
float flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF
|
||||
unsigned long ulFlags; // modifies the behavior of properties
|
||||
} EAXBUFFERPROPERTIES, *LPEAXBUFFERPROPERTIES;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_OBSTRUCTION,
|
||||
#ifndef EAX_OBSTRUCTIONPROPERTIES_DEFINED
|
||||
#define EAX_OBSTRUCTIONPROPERTIES_DEFINED
|
||||
typedef struct _EAXOBSTRUCTIONPROPERTIES
|
||||
{
|
||||
long lObstruction;
|
||||
float flObstructionLFRatio;
|
||||
} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES;
|
||||
#endif
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_OCCLUSION
|
||||
#ifndef EAX_OCCLUSIONPROPERTIES_DEFINED
|
||||
#define EAX_OCCLUSIONPROPERTIES_DEFINED
|
||||
typedef struct _EAXOCCLUSIONPROPERTIES
|
||||
{
|
||||
long lOcclusion;
|
||||
float flOcclusionLFRatio;
|
||||
float flOcclusionRoomRatio;
|
||||
float flOcclusionDirectRatio;
|
||||
} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES;
|
||||
#endif
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_EXCLUSION
|
||||
#ifndef EAX_EXCLUSIONPROPERTIES_DEFINED
|
||||
#define EAX_EXCLUSIONPROPERTIES_DEFINED
|
||||
typedef struct _EAXEXCLUSIONPROPERTIES
|
||||
{
|
||||
long lExclusion;
|
||||
float flExclusionLFRatio;
|
||||
} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES;
|
||||
#endif
|
||||
|
||||
// Used by DSPROPERTY_EAXBUFFER_FLAGS
|
||||
// TRUE: value is computed automatically - property is an offset
|
||||
// FALSE: value is used directly
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// To insure future compatibility, use flag defines as follows:
|
||||
// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO;
|
||||
// instead of:
|
||||
// myFlags = 0x00000003;
|
||||
//
|
||||
#define EAXBUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF
|
||||
#define EAXBUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM
|
||||
#define EAXBUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF
|
||||
|
||||
#define EAXBUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use
|
||||
|
||||
// Property ranges and defaults:
|
||||
|
||||
#define EAXBUFFER_MINDIRECT (-10000)
|
||||
#define EAXBUFFER_MAXDIRECT 1000
|
||||
#define EAXBUFFER_DEFAULTDIRECT 0
|
||||
|
||||
#define EAXBUFFER_MINDIRECTHF (-10000)
|
||||
#define EAXBUFFER_MAXDIRECTHF 0
|
||||
#define EAXBUFFER_DEFAULTDIRECTHF 0
|
||||
|
||||
#define EAXBUFFER_MINROOM (-10000)
|
||||
#define EAXBUFFER_MAXROOM 1000
|
||||
#define EAXBUFFER_DEFAULTROOM 0
|
||||
|
||||
#define EAXBUFFER_MINROOMHF (-10000)
|
||||
#define EAXBUFFER_MAXROOMHF 0
|
||||
#define EAXBUFFER_DEFAULTROOMHF 0
|
||||
|
||||
#define EAXBUFFER_MINOBSTRUCTION (-10000)
|
||||
#define EAXBUFFER_MAXOBSTRUCTION 0
|
||||
#define EAXBUFFER_DEFAULTOBSTRUCTION 0
|
||||
|
||||
#define EAXBUFFER_MINOBSTRUCTIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOBSTRUCTIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSION (-10000)
|
||||
#define EAXBUFFER_MAXOCCLUSION 0
|
||||
#define EAXBUFFER_DEFAULTOCCLUSION 0
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONROOMRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONROOMRATIO 10.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO 1.5f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONDIRECTRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONDIRECTRATIO 10.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONDIRECTRATIO 1.0f
|
||||
|
||||
#define EAXBUFFER_MINEXCLUSION (-10000)
|
||||
#define EAXBUFFER_MAXEXCLUSION 0
|
||||
#define EAXBUFFER_DEFAULTEXCLUSION 0
|
||||
|
||||
#define EAXBUFFER_MINEXCLUSIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXEXCLUSIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTEXCLUSIONLFRATIO 1.0f
|
||||
|
||||
#define EAXBUFFER_MINOUTSIDEVOLUMEHF (-10000)
|
||||
#define EAXBUFFER_MAXOUTSIDEVOLUMEHF 0
|
||||
#define EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF 0
|
||||
|
||||
#define EAXBUFFER_MINDOPPLERFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXDOPPLERFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTDOPPLERFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINROLLOFFFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXROLLOFFFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXROOMROLLOFFFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINAIRABSORPTIONFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXAIRABSORPTIONFACTOR 10.0f
|
||||
#define EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f
|
||||
|
||||
#define EAXBUFFER_DEFAULTFLAGS (EAXBUFFERFLAGS_DIRECTHFAUTO | \
|
||||
EAXBUFFERFLAGS_ROOMAUTO | \
|
||||
EAXBUFFERFLAGS_ROOMHFAUTO )
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
/*******************************************************************\
|
||||
* *
|
||||
* EAX.H - Environmental Audio Extensions version 4.0 *
|
||||
* for OpenAL and DirectSound3D *
|
||||
* for OpenAL *
|
||||
* *
|
||||
* File revision 1.0.0 (GDC Beta SDK Release) *
|
||||
* *
|
||||
@@ -14,71 +14,34 @@
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef OPENAL
|
||||
#include <dsound.h>
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
typedef struct _GUID
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[8];
|
||||
} GUID;
|
||||
#endif // GUID_DEFINED
|
||||
|
||||
/*
|
||||
* EAX Unified Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound,
|
||||
0x4ff53b81,
|
||||
0x1ce0,
|
||||
0x11d3,
|
||||
0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5);
|
||||
|
||||
/*
|
||||
* EAX Unified Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound8,
|
||||
0xca503b60,
|
||||
0xb176,
|
||||
0x11d4,
|
||||
0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc);
|
||||
#ifndef DEFINE_GUID
|
||||
#ifndef INITGUID
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID /*FAR*/ name
|
||||
#else
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
#endif // INITGUID
|
||||
#endif // DEFINE_GUID
|
||||
|
||||
|
||||
|
||||
#ifdef DIRECTSOUND_VERSION
|
||||
#if DIRECTSOUND_VERSION >= 0x0800
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND8*, IUnknown FAR*);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*);
|
||||
|
||||
#else // OPENAL
|
||||
// #include <al.h>
|
||||
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
typedef struct _GUID
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[8];
|
||||
} GUID;
|
||||
#endif // GUID_DEFINED
|
||||
|
||||
#ifndef DEFINE_GUID
|
||||
#ifndef INITGUID
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID /*FAR*/ name
|
||||
#else
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
#endif // INITGUID
|
||||
#endif // DEFINE_GUID
|
||||
|
||||
/*
|
||||
* EAX OpenAL Extensions
|
||||
*/
|
||||
typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALboolean (*EAXSetBufferMode)(ALsizei, ALuint*, ALint);
|
||||
typedef ALenum (*EAXGetBufferMode)(ALuint, ALint*);
|
||||
#endif
|
||||
/*
|
||||
* EAX OpenAL Extensions
|
||||
*/
|
||||
typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALboolean (*EAXSetBufferMode)(ALsizei, ALuint*, ALint);
|
||||
typedef ALenum (*EAXGetBufferMode)(ALuint, ALint*);
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
*/
|
||||
#ifndef __EAXMANH
|
||||
#define __EAXMANH
|
||||
|
||||
#define COM_NO_WINDOWS_H
|
||||
#include <objbase.h>
|
||||
#include "eax3.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
//#define CLSID_EAXMANAGER CLSID_EAX20_Manager
|
||||
//#define IID_IEaxManager IID_EAX20_Manager
|
||||
#define EM_MAX_NAME 32
|
||||
|
||||
#define EMFLAG_IDDEFAULT (-1)
|
||||
#define EMFLAG_IDNONE (-2)
|
||||
#define EMFLAG_LOCKPOSITION 1
|
||||
#define EMFLAG_LOADFROMMEMORY 2
|
||||
#define EMFLAG_NODIFFRACTION 4
|
||||
|
||||
typedef struct _EMPOINT {
|
||||
float fX;
|
||||
float fY;
|
||||
float fZ;
|
||||
} EMPOINT;
|
||||
typedef EMPOINT FAR *LPEMPOINT;
|
||||
|
||||
typedef struct _LISTENERATTRIBUTES {
|
||||
float fDistanceFactor;
|
||||
float fRolloffFactor;
|
||||
float fDopplerFactor;
|
||||
} LISTENERATTRIBUTES;
|
||||
typedef LISTENERATTRIBUTES FAR *LPLISTENERATTRIBUTES;
|
||||
|
||||
typedef struct _SOURCEATTRIBUTES {
|
||||
EAXBUFFERPROPERTIES eaxAttributes;
|
||||
unsigned long ulInsideConeAngle;
|
||||
unsigned long ulOutsideConeAngle;
|
||||
long lConeOutsideVolume;
|
||||
float fConeXdir;
|
||||
float fConeYdir;
|
||||
float fConeZdir;
|
||||
float fMinDistance;
|
||||
float fMaxDistance;
|
||||
long lDupCount;
|
||||
long lPriority;
|
||||
} SOURCEATTRIBUTES;
|
||||
typedef SOURCEATTRIBUTES FAR *LPSOURCEATTRIBUTES;
|
||||
|
||||
typedef struct _MATERIALATTRIBUTES {
|
||||
long lLevel;
|
||||
float fLFRatio;
|
||||
float fRoomRatio;
|
||||
DWORD dwFlags;
|
||||
} MATERIALATTRIBUTES;
|
||||
typedef MATERIALATTRIBUTES FAR *LPMATERIALATTRIBUTES;
|
||||
|
||||
#define EMMATERIAL_OBSTRUCTS 1
|
||||
#define EMMATERIAL_OCCLUDES 3
|
||||
|
||||
typedef struct _DIFFRACTIONBOX {
|
||||
long lSubspaceID;
|
||||
EMPOINT empMin;
|
||||
EMPOINT empMax;
|
||||
} DIFFRACTIONBOX;
|
||||
typedef DIFFRACTIONBOX FAR *LPDIFFRACTIONBOX;
|
||||
|
||||
// {7CE4D6E6-562F-11d3-8812-005004062F83}
|
||||
DEFINE_GUID(CLSID_EAXMANAGER, 0x60b721a1, 0xf7c8, 0x11d2, 0xa0, 0x2e, 0x0, 0x50, 0x4, 0x6, 0x18, 0xb8);
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct IEaxManager;
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef struct IEaxManager *LPEAXMANAGER;
|
||||
|
||||
// {7CE4D6E8-562F-11d3-8812-005004062F83}
|
||||
DEFINE_GUID(IID_IEaxManager, 0x60b721a2, 0xf7c8, 0x11d2, 0xa0, 0x2e, 0x0, 0x50, 0x4, 0x6, 0x18, 0xb8);
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IEaxManager
|
||||
|
||||
extern HRESULT __stdcall EaxManagerCreate(LPEAXMANAGER*);
|
||||
typedef HRESULT (__stdcall *LPEAXMANAGERCREATE)(LPEAXMANAGER*);
|
||||
|
||||
DECLARE_INTERFACE_(IEaxManager, IUnknown)
|
||||
{
|
||||
// IUnknown methods
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
|
||||
STDMETHOD(GetDataSetSize) (THIS_ unsigned long*, DWORD) PURE;
|
||||
STDMETHOD(LoadDataSet) (THIS_ char*, DWORD) PURE;
|
||||
STDMETHOD(FreeDataSet) (THIS_ DWORD) PURE;
|
||||
STDMETHOD(GetListenerAttributes) (THIS_ LPLISTENERATTRIBUTES) PURE;
|
||||
STDMETHOD(GetSourceID) (THIS_ char*, long*) PURE;
|
||||
STDMETHOD(GetSourceAttributes) (THIS_ long, LPSOURCEATTRIBUTES) PURE;
|
||||
STDMETHOD(GetSourceNumInstances) (THIS_ long, long*) PURE;
|
||||
STDMETHOD(GetSourceInstancePos) (THIS_ long, long, LPEMPOINT) PURE;
|
||||
STDMETHOD(GetEnvironmentID) (THIS_ char*, long*) PURE;
|
||||
STDMETHOD(GetEnvironmentAttributes) (THIS_ long, LPEAXLISTENERPROPERTIES) PURE;
|
||||
STDMETHOD(GetMaterialID) (THIS_ char*, long*) PURE;
|
||||
STDMETHOD(GetMaterialAttributes) (THIS_ long, LPMATERIALATTRIBUTES) PURE;
|
||||
STDMETHOD(GetGeometrySetID) (THIS_ char*, long*) PURE;
|
||||
STDMETHOD(GetListenerDynamicAttributes) (THIS_ long, LPEMPOINT, long*, DWORD) PURE;
|
||||
STDMETHOD(GetSourceDynamicAttributes) (THIS_ long, LPEMPOINT, long*, float*, long*, float*, float*, LPEMPOINT, DWORD) PURE;
|
||||
// STDMETHOD(GetSubSpaceID) (THIS_ long, LPEMPOINT, long *) PURE;
|
||||
STDMETHOD(GetEnvironmentName) (THIS_ long, char *szString, long lStrlen) PURE;
|
||||
};
|
||||
|
||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||
#define IEaxManager_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
|
||||
#define IEaxManager_AddRef(p) (p)->lpVtbl->AddRef(p)
|
||||
#define IEaxManager_Release(p) (p)->lpVtbl->Release(p)
|
||||
#define IEaxManager_GetDataSetSize(p,a,b) (p)->lpVtbl->GetDataSetSize(p,a,b)
|
||||
#define IEaxManager_LoadDataSet(p,a,b) (p)->lpVtbl->LoadDataSet(p,a,b)
|
||||
#define IEaxManager_FreeDataSet(p,a) (p)->lpVtbl->FreeDataSet(p,a)
|
||||
#define IEaxManager_GetListenerAttributes(p,a) (p)->lpVtbl->GetListenerAttributes(p,a)
|
||||
#define IEaxManager_GetSourceID(p,a,b) (p)->lpVtbl->GetSourceID(p,a,b)
|
||||
#define IEaxManager_GetSourceAttributes(p,a,b) (p)->lpVtbl->GetSourceAttributes(p,a,b)
|
||||
#define IEaxManager_GetSourceNumInstances(p,a,b) (p)->lpVtbl->GetSourceNumInstances(p,a,b)
|
||||
#define IEaxManager_GetSourceInstancePos(p,a,b,c) (p)->lpVtbl->GetSourceInstancePos(p,a,b,c)
|
||||
#define IEaxManager_GetEnvironmentID(p,a,b) (p)->lpVtbl->GetEnvironmentID(p,a,b)
|
||||
#define IEaxManager_GetEnvironmentAttributes(p,a,b) (p)->lpVtbl->GetEnvironmentAttributes(p,a,b)
|
||||
#define IEaxManager_GetMaterialID(p,a,b) (p)->lpVtbl->GetMaterialID(p,a,b)
|
||||
#define IEaxManager_GetMaterialAttributes(p,a,b) (p)->lpVtbl->GetMaterialAttributes(p,a,b)
|
||||
#define IEaxManager_GetGeometrySetID(p,a,b) (p)->lpVtbl->GetGeometrySetID(p,a,b)
|
||||
#define IEaxManager_GetListenerDynamicAttributes(p,a,b,c,d) (p)->lpVtbl->GetListenerDynamicAttributes(p,a,b,c,d)
|
||||
#define IEaxManager_GetSourceDynamicAttributes(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->GetSourceDynamicAttributes(p,a,b,c,d,e,f,g,h,i)
|
||||
//#define IEaxManager_GetSubSpaceID(p,a,b,c) (p)->lpVtbl->GetSubSpaceID(p,a,b,c)
|
||||
#define IEaxManager_GetEnvironmentName(p,a,b,c) (p)->lpVtbl->GetEnvironmentName(p,a,b,c)
|
||||
#else
|
||||
#define IEaxManager_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
|
||||
#define IEaxManager_AddRef(p) (p)->AddRef()
|
||||
#define IEaxManager_Release(p) (p)->Release()
|
||||
#define IEaxManager_GetDataSetSize(p,a,b) (p)->GetDataSetSize(a,b)
|
||||
#define IEaxManager_LoadDataSet(p,a,b) (p)->LoadDataSet(a,b)
|
||||
#define IEaxManager_FreeDataSet(p,a) (p)->FreeDataSet(a)
|
||||
#define IEaxManager_GetListenerAttributes(p,a) (p)->GetListenerAttributes(a)
|
||||
#define IEaxManager_GetSourceID(p,a,b) (p)->GetSourceID(a,b)
|
||||
#define IEaxManager_GetSourceAttributes(p,a,b) (p)->GetSourceAttributes(a,b)
|
||||
#define IEaxManager_GetSourceNumInstances(p,a,b) (p)->GetSourceNumInstances(a,b)
|
||||
#define IEaxManager_GetSourceInstancePos(p,a,b,c) (p)->GetSourceInstancePos(a,b,c)
|
||||
#define IEaxManager_GetEnvironmentID(p,a,b) (p)->GetEnvironmentID(a,b)
|
||||
#define IEaxManager_GetEnvironmentAttributes(p,a,b) (p)->GetEnvironmentAttributes(a,b)
|
||||
#define IEaxManager_GetMaterialID(p,a,b) (p)->GetMaterialID(a,b)
|
||||
#define IEaxManager_GetMaterialAttributes(p,a,b) (p)->GetMaterialAttributes(a,b)
|
||||
#define IEaxManager_GetGeometrySetID(p,a,b) (p)->GetGeometrySetID(a,b)
|
||||
#define IEaxManager_GetListenerDynamicAttributes(p,a,b,c,d) (p)->GetListenerDynamicAttributes(a,b,c,d)
|
||||
#define IEaxManager_GetSourceDynamicAttributes(p,a,b,c,d,e,f,g,h,i) (p)->GetSourceDynamicAttributes(a,b,c,d,e,f,g,h,i)
|
||||
//#define IEaxManager_GetSubSpaceID(p,a,b,c) (p)->GetSubSpaceID(a,b,c)
|
||||
#define IEaxManager_GetEnvironmentName(p,a,b,c) (p)->GetEnvironmentName(a,b,c)
|
||||
#endif
|
||||
|
||||
#define EM_OK 0
|
||||
#define EM_INVALIDID MAKE_HRESULT(1, FACILITY_ITF, 1)
|
||||
#define EM_IDNOTFOUND MAKE_HRESULT(1, FACILITY_ITF, 2)
|
||||
#define EM_FILENOTFOUND MAKE_HRESULT(1, FACILITY_ITF, 3)
|
||||
#define EM_FILEINVALID MAKE_HRESULT(1, FACILITY_ITF, 4)
|
||||
#define EM_VERSIONINVALID MAKE_HRESULT(1, FACILITY_ITF, 5)
|
||||
#define EM_INSTANCENOTFOUND MAKE_HRESULT(1, FACILITY_ITF, 6)
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -355,20 +355,18 @@ void idSoundSample::MakeDefault( void ) {
|
||||
ncd[i*2+1] = sample;
|
||||
}
|
||||
|
||||
if ( idSoundSystemLocal::useOpenAL ) {
|
||||
alGetError();
|
||||
alGenBuffers( 1, &openalBuffer );
|
||||
if ( alGetError() != AL_NO_ERROR ) {
|
||||
common->Error( "idSoundCache: error generating OpenAL hardware buffer" );
|
||||
}
|
||||
|
||||
alGetError();
|
||||
alBufferData( openalBuffer, objectInfo.nChannels==1?AL_FORMAT_MONO16:AL_FORMAT_STEREO16, nonCacheData, objectMemSize, objectInfo.nSamplesPerSec );
|
||||
if ( alGetError() != AL_NO_ERROR ) {
|
||||
common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" );
|
||||
} else {
|
||||
hardwareBuffer = true;
|
||||
}
|
||||
alGetError();
|
||||
alGenBuffers( 1, &openalBuffer );
|
||||
if ( alGetError() != AL_NO_ERROR ) {
|
||||
common->Error( "idSoundCache: error generating OpenAL hardware buffer" );
|
||||
}
|
||||
|
||||
alGetError();
|
||||
alBufferData( openalBuffer, objectInfo.nChannels==1?AL_FORMAT_MONO16:AL_FORMAT_STEREO16, nonCacheData, objectMemSize, objectInfo.nSamplesPerSec );
|
||||
if ( alGetError() != AL_NO_ERROR ) {
|
||||
common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" );
|
||||
} else {
|
||||
hardwareBuffer = true;
|
||||
}
|
||||
|
||||
defaultSound = true;
|
||||
@@ -486,9 +484,8 @@ void idSoundSample::Load( void ) {
|
||||
CheckForDownSample();
|
||||
|
||||
// create hardware audio buffers
|
||||
if ( idSoundSystemLocal::useOpenAL ) {
|
||||
// PCM loads directly
|
||||
if ( objectInfo.wFormatTag == WAVE_FORMAT_TAG_PCM ) {
|
||||
// PCM loads directly
|
||||
if ( objectInfo.wFormatTag == WAVE_FORMAT_TAG_PCM ) {
|
||||
alGetError();
|
||||
alGenBuffers( 1, &openalBuffer );
|
||||
if ( alGetError() != AL_NO_ERROR )
|
||||
@@ -526,8 +523,8 @@ void idSoundSample::Load( void ) {
|
||||
}
|
||||
}
|
||||
|
||||
// OGG decompressed at load time (when smaller than s_decompressionLimit seconds, 6 seconds by default)
|
||||
if ( objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) {
|
||||
// OGG decompressed at load time (when smaller than s_decompressionLimit seconds, 6 seconds by default)
|
||||
if ( objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) {
|
||||
#if defined(MACOS_X)
|
||||
if ( ( objectSize < ( ( int ) objectInfo.nSamplesPerSec * idSoundSystemLocal::s_decompressionLimit.GetInteger() ) ) ) {
|
||||
#else
|
||||
@@ -610,11 +607,10 @@ void idSoundSample::Load( void ) {
|
||||
}
|
||||
}
|
||||
|
||||
// Free memory if sample was loaded into hardware
|
||||
if ( hardwareBuffer ) {
|
||||
soundCacheAllocator.Free( nonCacheData );
|
||||
nonCacheData = NULL;
|
||||
}
|
||||
// Free memory if sample was loaded into hardware
|
||||
if ( hardwareBuffer ) {
|
||||
soundCacheAllocator.Free( nonCacheData );
|
||||
nonCacheData = NULL;
|
||||
}
|
||||
|
||||
fh.Close();
|
||||
@@ -628,7 +624,7 @@ idSoundSample::PurgeSoundSample
|
||||
void idSoundSample::PurgeSoundSample() {
|
||||
purged = true;
|
||||
|
||||
if ( hardwareBuffer && idSoundSystemLocal::useOpenAL ) {
|
||||
if ( hardwareBuffer ) {
|
||||
alGetError();
|
||||
alDeleteBuffers( 1, &openalBuffer );
|
||||
if ( alGetError() != AL_NO_ERROR ) {
|
||||
|
||||
@@ -88,6 +88,29 @@ bool idEFXFile::ReadEffect( idLexer &src, idSoundEffect *effect ) {
|
||||
if ( token == "reverb" ) {
|
||||
EAXREVERBPROPERTIES *reverb = ( EAXREVERBPROPERTIES * )Mem_Alloc( sizeof( EAXREVERBPROPERTIES ) );
|
||||
if ( reverb ) {
|
||||
memset( reverb, 0, sizeof( EAXREVERBPROPERTIES ) );
|
||||
reverb->ulEnvironment = EAXREVERB_DEFAULTENVIRONMENT;
|
||||
reverb->flEnvironmentSize = EAXREVERB_DEFAULTENVIRONMENTSIZE;
|
||||
reverb->flEnvironmentDiffusion = EAXREVERB_DEFAULTENVIRONMENTDIFFUSION;
|
||||
reverb->lRoom = EAXREVERB_DEFAULTROOM;
|
||||
reverb->lRoomHF = EAXREVERB_DEFAULTROOMHF;
|
||||
reverb->lRoomLF = EAXREVERB_DEFAULTROOMLF;
|
||||
reverb->flDecayTime = EAXREVERB_DEFAULTDECAYTIME;
|
||||
reverb->flDecayHFRatio = EAXREVERB_DEFAULTDECAYHFRATIO;
|
||||
reverb->flDecayLFRatio = EAXREVERB_DEFAULTDECAYLFRATIO;
|
||||
reverb->lReflections = EAXREVERB_DEFAULTREFLECTIONS;
|
||||
reverb->flReflectionsDelay = EAXREVERB_DEFAULTREFLECTIONSDELAY;
|
||||
reverb->lReverb = EAXREVERB_DEFAULTREVERB;
|
||||
reverb->flReverbDelay = EAXREVERB_DEFAULTREVERBDELAY;
|
||||
reverb->flEchoTime = EAXREVERB_DEFAULTECHOTIME;
|
||||
reverb->flEchoDepth = EAXREVERB_DEFAULTECHODEPTH;
|
||||
reverb->flModulationTime = EAXREVERB_DEFAULTMODULATIONTIME;
|
||||
reverb->flModulationDepth = EAXREVERB_DEFAULTMODULATIONDEPTH;
|
||||
reverb->flAirAbsorptionHF = EAXREVERB_DEFAULTAIRABSORPTIONHF;
|
||||
reverb->flHFReference = EAXREVERB_DEFAULTHFREFERENCE;
|
||||
reverb->flLFReference = EAXREVERB_DEFAULTLFREFERENCE;
|
||||
reverb->flRoomRolloffFactor = EAXREVERB_DEFAULTROOMROLLOFFFACTOR;
|
||||
reverb->ulFlags = EAXREVERB_DEFAULTFLAGS;
|
||||
src.ReadTokenOnLine( &token );
|
||||
name = token;
|
||||
|
||||
|
||||
@@ -222,28 +222,25 @@ idSoundChannel::ALStop
|
||||
===================
|
||||
*/
|
||||
void idSoundChannel::ALStop( void ) {
|
||||
if ( idSoundSystemLocal::useOpenAL ) {
|
||||
if ( alIsSource( openalSource ) ) {
|
||||
alSourceStop( openalSource );
|
||||
alSourcei( openalSource, AL_BUFFER, 0 );
|
||||
soundSystemLocal.FreeOpenALSource( openalSource );
|
||||
}
|
||||
|
||||
if ( alIsSource( openalSource ) ) {
|
||||
alSourceStop( openalSource );
|
||||
alSourcei( openalSource, AL_BUFFER, 0 );
|
||||
soundSystemLocal.FreeOpenALSource( openalSource );
|
||||
if ( openalStreamingBuffer[0] && openalStreamingBuffer[1] && openalStreamingBuffer[2] ) {
|
||||
alGetError();
|
||||
alDeleteBuffers( 3, &openalStreamingBuffer[0] );
|
||||
if ( alGetError() == AL_NO_ERROR ) {
|
||||
openalStreamingBuffer[0] = openalStreamingBuffer[1] = openalStreamingBuffer[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( openalStreamingBuffer[0] && openalStreamingBuffer[1] && openalStreamingBuffer[2] ) {
|
||||
alGetError();
|
||||
alDeleteBuffers( 3, &openalStreamingBuffer[0] );
|
||||
if ( alGetError() == AL_NO_ERROR ) {
|
||||
openalStreamingBuffer[0] = openalStreamingBuffer[1] = openalStreamingBuffer[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( lastopenalStreamingBuffer[0] && lastopenalStreamingBuffer[1] && lastopenalStreamingBuffer[2] ) {
|
||||
alGetError();
|
||||
alDeleteBuffers( 3, &lastopenalStreamingBuffer[0] );
|
||||
if ( alGetError() == AL_NO_ERROR ) {
|
||||
lastopenalStreamingBuffer[0] = lastopenalStreamingBuffer[1] = lastopenalStreamingBuffer[2] = 0;
|
||||
}
|
||||
if ( lastopenalStreamingBuffer[0] && lastopenalStreamingBuffer[1] && lastopenalStreamingBuffer[2] ) {
|
||||
alGetError();
|
||||
alDeleteBuffers( 3, &lastopenalStreamingBuffer[0] );
|
||||
if ( alGetError() == AL_NO_ERROR ) {
|
||||
lastopenalStreamingBuffer[0] = lastopenalStreamingBuffer[1] = lastopenalStreamingBuffer[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,7 +449,7 @@ void idSoundEmitterLocal::CheckForCompletion( int current44kHzTime ) {
|
||||
if ( !( chan->parms.soundShaderFlags & SSF_LOOPING ) ) {
|
||||
ALint state = AL_PLAYING;
|
||||
|
||||
if ( idSoundSystemLocal::useOpenAL && alIsSource( chan->openalSource ) ) {
|
||||
if ( alIsSource( chan->openalSource ) ) {
|
||||
alGetSourcei( chan->openalSource, AL_SOURCE_STATE, &state );
|
||||
}
|
||||
idSlowChannel slow = GetSlowChannel( chan );
|
||||
|
||||
@@ -45,8 +45,79 @@ If you have questions concerning this license or the applicable additional terms
|
||||
#include <AL/alc.h>
|
||||
#define ID_ALCHAR
|
||||
#endif
|
||||
#ifndef OPENAL
|
||||
#define OPENAL
|
||||
#endif
|
||||
#include "../openal/include/efxlib.h"
|
||||
|
||||
#ifndef AL_EFFECT_TYPE
|
||||
#define AL_EFFECT_TYPE 0x8001
|
||||
#define AL_EFFECT_NULL 0x0000
|
||||
#define AL_EFFECT_REVERB 0x0001
|
||||
#define AL_EFFECT_EAXREVERB 0x8000
|
||||
#define AL_EFFECTSLOT_EFFECT 0x0001
|
||||
#define AL_EFFECTSLOT_GAIN 0x0002
|
||||
#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003
|
||||
#define AL_AUXILIARY_SEND_FILTER 0x20006
|
||||
#define AL_DIRECT_FILTER 0x20005
|
||||
#define AL_FILTER_TYPE 0x8001
|
||||
#define AL_FILTER_NULL 0x0000
|
||||
#define AL_FILTER_LOWPASS 0x0001
|
||||
#define AL_LOWPASS_GAIN 0x0001
|
||||
#define AL_LOWPASS_GAINHF 0x0002
|
||||
#define AL_REVERB_DENSITY 0x0001
|
||||
#define AL_REVERB_DIFFUSION 0x0002
|
||||
#define AL_REVERB_GAIN 0x0003
|
||||
#define AL_REVERB_GAINHF 0x0004
|
||||
#define AL_REVERB_DECAY_TIME 0x0005
|
||||
#define AL_REVERB_DECAY_HFRATIO 0x0006
|
||||
#define AL_REVERB_REFLECTIONS_GAIN 0x0007
|
||||
#define AL_REVERB_REFLECTIONS_DELAY 0x0008
|
||||
#define AL_REVERB_LATE_REVERB_GAIN 0x0009
|
||||
#define AL_REVERB_LATE_REVERB_DELAY 0x000A
|
||||
#define AL_REVERB_AIR_ABSORPTION_GAINHF 0x000B
|
||||
#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C
|
||||
#define AL_REVERB_DECAY_HFLIMIT 0x000D
|
||||
#define AL_EAXREVERB_DENSITY 0x0001
|
||||
#define AL_EAXREVERB_DIFFUSION 0x0002
|
||||
#define AL_EAXREVERB_GAIN 0x0003
|
||||
#define AL_EAXREVERB_GAINHF 0x0004
|
||||
#define AL_EAXREVERB_GAINLF 0x0005
|
||||
#define AL_EAXREVERB_DECAY_TIME 0x0006
|
||||
#define AL_EAXREVERB_DECAY_HFRATIO 0x0007
|
||||
#define AL_EAXREVERB_DECAY_LFRATIO 0x0008
|
||||
#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009
|
||||
#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A
|
||||
#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B
|
||||
#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C
|
||||
#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D
|
||||
#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E
|
||||
#define AL_EAXREVERB_ECHO_TIME 0x000F
|
||||
#define AL_EAXREVERB_ECHO_DEPTH 0x0010
|
||||
#define AL_EAXREVERB_MODULATION_TIME 0x0011
|
||||
#define AL_EAXREVERB_MODULATION_DEPTH 0x0012
|
||||
#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013
|
||||
#define AL_EAXREVERB_HFREFERENCE 0x0014
|
||||
#define AL_EAXREVERB_LFREFERENCE 0x0015
|
||||
#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016
|
||||
#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017
|
||||
#endif
|
||||
|
||||
typedef void ( ALAPIENTRY *EfxGenEffects )( ALsizei, ALuint * );
|
||||
typedef void ( ALAPIENTRY *EfxDeleteEffects )( ALsizei, const ALuint * );
|
||||
typedef void ( ALAPIENTRY *EfxEffecti )( ALuint, ALenum, ALint );
|
||||
typedef void ( ALAPIENTRY *EfxEffectf )( ALuint, ALenum, ALfloat );
|
||||
typedef void ( ALAPIENTRY *EfxEffectfv )( ALuint, ALenum, const ALfloat * );
|
||||
typedef void ( ALAPIENTRY *EfxGenAuxiliaryEffectSlots )( ALsizei, ALuint * );
|
||||
typedef void ( ALAPIENTRY *EfxDeleteAuxiliaryEffectSlots )( ALsizei, const ALuint * );
|
||||
typedef void ( ALAPIENTRY *EfxAuxiliaryEffectSloti )( ALuint, ALenum, ALint );
|
||||
typedef void ( ALAPIENTRY *EfxAuxiliaryEffectSlotf )( ALuint, ALenum, ALfloat );
|
||||
typedef void ( ALAPIENTRY *EfxSource3i )( ALuint, ALenum, ALint, ALint, ALint );
|
||||
typedef void ( ALAPIENTRY *EfxGenFilters )( ALsizei, ALuint * );
|
||||
typedef void ( ALAPIENTRY *EfxDeleteFilters )( ALsizei, const ALuint * );
|
||||
typedef void ( ALAPIENTRY *EfxFilteri )( ALuint, ALenum, ALint );
|
||||
typedef void ( ALAPIENTRY *EfxFilterf )( ALuint, ALenum, ALfloat );
|
||||
|
||||
// demo sound commands
|
||||
typedef enum {
|
||||
SCMD_STATE, // followed by a load game state
|
||||
@@ -258,7 +329,7 @@ public:
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
Encapsulates functionality of a DirectSound buffer.
|
||||
Encapsulates functionality of a legacy software-mixer output buffer.
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
@@ -740,6 +811,10 @@ public:
|
||||
|
||||
ALuint AllocOpenALSource( idSoundChannel *chan, bool looping, bool stereo );
|
||||
void FreeOpenALSource( ALuint handle );
|
||||
bool InitOpenALEFX( void );
|
||||
void ShutdownOpenALEFX( void );
|
||||
void ApplyOpenALReverb( const EAXREVERBPROPERTIES &reverb );
|
||||
void ApplyOpenALSourceEffects( ALuint source, long occlusion, bool stereo );
|
||||
|
||||
#ifdef PREY
|
||||
virtual int GetSubtitleIndex(const char* soundName);
|
||||
@@ -789,10 +864,28 @@ public:
|
||||
EAXGet alEAXGet;
|
||||
EAXSetBufferMode alEAXSetBufferMode;
|
||||
EAXGetBufferMode alEAXGetBufferMode;
|
||||
EfxGenEffects alGenEffects;
|
||||
EfxDeleteEffects alDeleteEffects;
|
||||
EfxEffecti alEffecti;
|
||||
EfxEffectf alEffectf;
|
||||
EfxEffectfv alEffectfv;
|
||||
EfxGenAuxiliaryEffectSlots alGenAuxiliaryEffectSlots;
|
||||
EfxDeleteAuxiliaryEffectSlots alDeleteAuxiliaryEffectSlots;
|
||||
EfxAuxiliaryEffectSloti alAuxiliaryEffectSloti;
|
||||
EfxAuxiliaryEffectSlotf alAuxiliaryEffectSlotf;
|
||||
EfxSource3i alSource3i;
|
||||
EfxGenFilters alGenFilters;
|
||||
EfxDeleteFilters alDeleteFilters;
|
||||
EfxFilteri alFilteri;
|
||||
EfxFilterf alFilterf;
|
||||
ALuint openalReverbEffect;
|
||||
ALuint openalReverbSlot;
|
||||
ALuint openalOcclusionFilter;
|
||||
bool openalEFXAvailable;
|
||||
bool openalEFXEAXReverb;
|
||||
idEFXFile EFXDatabase;
|
||||
bool efxloaded;
|
||||
// latches
|
||||
static bool useOpenAL;
|
||||
static bool useEAXReverb;
|
||||
// mark available during initialization, or through an explicit test
|
||||
static int EAXAvailable;
|
||||
@@ -824,7 +917,6 @@ public:
|
||||
static idCVar s_clipVolumes;
|
||||
static idCVar s_realTimeDecoding;
|
||||
static idCVar s_libOpenAL;
|
||||
static idCVar s_useOpenAL;
|
||||
static idCVar s_useEAXReverb;
|
||||
static idCVar s_muteEAXReverb;
|
||||
static idCVar s_decompressionLimit;
|
||||
|
||||
+294
-208
@@ -29,9 +29,9 @@ If you have questions concerning this license or the applicable additional terms
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <initguid.h>
|
||||
#include "snd_local.h"
|
||||
|
||||
#include <initguid.h>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
@@ -74,35 +74,17 @@ idCVar idSoundSystemLocal::s_reverbFeedback( "s_reverbFeedback", "0.333", CVAR_S
|
||||
idCVar idSoundSystemLocal::s_enviroSuitVolumeScale( "s_enviroSuitVolumeScale", "0.9", CVAR_SOUND | CVAR_FLOAT, "" );
|
||||
idCVar idSoundSystemLocal::s_skipHelltimeFX( "s_skipHelltimeFX", "0", CVAR_SOUND | CVAR_BOOL, "" );
|
||||
|
||||
#if ID_OPENAL
|
||||
// off by default. OpenAL DLL gets loaded on-demand
|
||||
idCVar idSoundSystemLocal::s_libOpenAL( "s_libOpenAL", "openal32.dll", CVAR_SOUND | CVAR_ARCHIVE, "OpenAL DLL name/path" );
|
||||
idCVar idSoundSystemLocal::s_useOpenAL( "s_useOpenAL", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ARCHIVE, "use OpenAL" );
|
||||
idCVar idSoundSystemLocal::s_useEAXReverb( "s_useEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ARCHIVE, "use EAX reverb" );
|
||||
idCVar idSoundSystemLocal::s_libOpenAL( "s_libOpenAL", "OpenAL32.dll", CVAR_SOUND | CVAR_ARCHIVE, "OpenAL Soft DLL name/path" );
|
||||
idCVar idSoundSystemLocal::s_useEAXReverb( "s_useEAXReverb", "1", CVAR_SOUND | CVAR_BOOL | CVAR_ARCHIVE, "use OpenAL EFX/EAX reverb" );
|
||||
idCVar idSoundSystemLocal::s_muteEAXReverb( "s_muteEAXReverb", "0", CVAR_SOUND | CVAR_BOOL, "mute eax reverb" );
|
||||
idCVar idSoundSystemLocal::s_decompressionLimit( "s_decompressionLimit", "6", CVAR_SOUND | CVAR_INTEGER | CVAR_ARCHIVE, "specifies maximum uncompressed sample length in seconds" );
|
||||
#else
|
||||
idCVar idSoundSystemLocal::s_libOpenAL( "s_libOpenAL", "openal32.dll", CVAR_SOUND | CVAR_ARCHIVE, "OpenAL is not supported in this build" );
|
||||
idCVar idSoundSystemLocal::s_useOpenAL( "s_useOpenAL", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "OpenAL is not supported in this build" );
|
||||
idCVar idSoundSystemLocal::s_useEAXReverb( "s_useEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "EAX not available in this build" );
|
||||
idCVar idSoundSystemLocal::s_muteEAXReverb( "s_muteEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "mute eax reverb" );
|
||||
idCVar idSoundSystemLocal::s_decompressionLimit( "s_decompressionLimit", "6", CVAR_SOUND | CVAR_INTEGER | CVAR_ROM, "specifies maximum uncompressed sample length in seconds" );
|
||||
#endif
|
||||
|
||||
bool idSoundSystemLocal::useOpenAL = false;
|
||||
bool idSoundSystemLocal::useEAXReverb = false;
|
||||
int idSoundSystemLocal::EAXAvailable = -1;
|
||||
|
||||
idSoundSystemLocal soundSystemLocal;
|
||||
idSoundSystem *soundSystem = &soundSystemLocal;
|
||||
|
||||
// Define EAX 4.0 GUIDs
|
||||
DEFINE_GUID(EAXPROPERTYID_EAX40_Source,
|
||||
0xA8FA6881, 0x9FDA, 0x11D2, 0xBA, 0xA0, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96);
|
||||
|
||||
DEFINE_GUID(EAXPROPERTYID_EAX40_FXSlot0,
|
||||
0xA8FA6882, 0x9FDA, 0x11D2, 0xBA, 0xA0, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96);
|
||||
|
||||
static std::thread g_soundAsyncThread;
|
||||
static std::atomic<bool> g_soundAsyncRunning{ false };
|
||||
|
||||
@@ -131,6 +113,163 @@ void StopSoundAsyncThread() {
|
||||
}
|
||||
}
|
||||
|
||||
static float MillibelToGain( const long millibels ) {
|
||||
if ( millibels <= -10000 ) {
|
||||
return 0.0f;
|
||||
}
|
||||
if ( millibels >= 0 ) {
|
||||
return 1.0f;
|
||||
}
|
||||
return powf( 10.0f, (float)millibels / 2000.0f );
|
||||
}
|
||||
|
||||
static float ClampALFloat( const float value, const float minValue, const float maxValue ) {
|
||||
if ( value < minValue ) {
|
||||
return minValue;
|
||||
}
|
||||
if ( value > maxValue ) {
|
||||
return maxValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool idSoundSystemLocal::InitOpenALEFX( void ) {
|
||||
alGenEffects = (EfxGenEffects)alGetProcAddress( ID_ALCHAR "alGenEffects" );
|
||||
alDeleteEffects = (EfxDeleteEffects)alGetProcAddress( ID_ALCHAR "alDeleteEffects" );
|
||||
alEffecti = (EfxEffecti)alGetProcAddress( ID_ALCHAR "alEffecti" );
|
||||
alEffectf = (EfxEffectf)alGetProcAddress( ID_ALCHAR "alEffectf" );
|
||||
alEffectfv = (EfxEffectfv)alGetProcAddress( ID_ALCHAR "alEffectfv" );
|
||||
alGenAuxiliaryEffectSlots = (EfxGenAuxiliaryEffectSlots)alGetProcAddress( ID_ALCHAR "alGenAuxiliaryEffectSlots" );
|
||||
alDeleteAuxiliaryEffectSlots = (EfxDeleteAuxiliaryEffectSlots)alGetProcAddress( ID_ALCHAR "alDeleteAuxiliaryEffectSlots" );
|
||||
alAuxiliaryEffectSloti = (EfxAuxiliaryEffectSloti)alGetProcAddress( ID_ALCHAR "alAuxiliaryEffectSloti" );
|
||||
alAuxiliaryEffectSlotf = (EfxAuxiliaryEffectSlotf)alGetProcAddress( ID_ALCHAR "alAuxiliaryEffectSlotf" );
|
||||
alSource3i = (EfxSource3i)alGetProcAddress( ID_ALCHAR "alSource3i" );
|
||||
alGenFilters = (EfxGenFilters)alGetProcAddress( ID_ALCHAR "alGenFilters" );
|
||||
alDeleteFilters = (EfxDeleteFilters)alGetProcAddress( ID_ALCHAR "alDeleteFilters" );
|
||||
alFilteri = (EfxFilteri)alGetProcAddress( ID_ALCHAR "alFilteri" );
|
||||
alFilterf = (EfxFilterf)alGetProcAddress( ID_ALCHAR "alFilterf" );
|
||||
|
||||
if ( !alGenEffects || !alDeleteEffects || !alEffecti || !alEffectf || !alEffectfv ||
|
||||
!alGenAuxiliaryEffectSlots || !alDeleteAuxiliaryEffectSlots || !alAuxiliaryEffectSloti ||
|
||||
!alAuxiliaryEffectSlotf || !alSource3i || !alGenFilters || !alDeleteFilters ||
|
||||
!alFilteri || !alFilterf ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
alGetError();
|
||||
alGenEffects( 1, &openalReverbEffect );
|
||||
alGenAuxiliaryEffectSlots( 1, &openalReverbSlot );
|
||||
alGenFilters( 1, &openalOcclusionFilter );
|
||||
if ( alGetError() != AL_NO_ERROR ) {
|
||||
ShutdownOpenALEFX();
|
||||
return false;
|
||||
}
|
||||
|
||||
openalEFXEAXReverb = alGetEnumValue( ID_ALCHAR "AL_EFFECT_EAXREVERB" ) != 0;
|
||||
alEffecti( openalReverbEffect, AL_EFFECT_TYPE, openalEFXEAXReverb ? AL_EFFECT_EAXREVERB : AL_EFFECT_REVERB );
|
||||
alAuxiliaryEffectSlotf( openalReverbSlot, AL_EFFECTSLOT_GAIN, 1.0f );
|
||||
alAuxiliaryEffectSloti( openalReverbSlot, AL_EFFECTSLOT_EFFECT, openalReverbEffect );
|
||||
alFilteri( openalOcclusionFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS );
|
||||
openalEFXAvailable = alGetError() == AL_NO_ERROR;
|
||||
return openalEFXAvailable;
|
||||
}
|
||||
|
||||
void idSoundSystemLocal::ShutdownOpenALEFX( void ) {
|
||||
if ( openalReverbSlot && alAuxiliaryEffectSloti ) {
|
||||
alAuxiliaryEffectSloti( openalReverbSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL );
|
||||
}
|
||||
if ( openalOcclusionFilter && alDeleteFilters ) {
|
||||
alDeleteFilters( 1, &openalOcclusionFilter );
|
||||
}
|
||||
if ( openalReverbSlot && alDeleteAuxiliaryEffectSlots ) {
|
||||
alDeleteAuxiliaryEffectSlots( 1, &openalReverbSlot );
|
||||
}
|
||||
if ( openalReverbEffect && alDeleteEffects ) {
|
||||
alDeleteEffects( 1, &openalReverbEffect );
|
||||
}
|
||||
openalReverbEffect = 0;
|
||||
openalReverbSlot = 0;
|
||||
openalOcclusionFilter = 0;
|
||||
openalEFXAvailable = false;
|
||||
openalEFXEAXReverb = false;
|
||||
}
|
||||
|
||||
void idSoundSystemLocal::ApplyOpenALReverb( const EAXREVERBPROPERTIES &reverb ) {
|
||||
if ( !openalEFXAvailable ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float roomGain = MillibelToGain( reverb.lRoom );
|
||||
const float roomHFGain = MillibelToGain( reverb.lRoomHF );
|
||||
const float reflectionsGain = MillibelToGain( reverb.lReflections );
|
||||
const float lateReverbGain = MillibelToGain( reverb.lReverb );
|
||||
const ALfloat reflectionsPan[3] = { reverb.vReflectionsPan.x, reverb.vReflectionsPan.y, reverb.vReflectionsPan.z };
|
||||
const ALfloat lateReverbPan[3] = { reverb.vReverbPan.x, reverb.vReverbPan.y, reverb.vReverbPan.z };
|
||||
|
||||
alEffecti( openalReverbEffect, AL_EFFECT_TYPE, openalEFXEAXReverb ? AL_EFFECT_EAXREVERB : AL_EFFECT_REVERB );
|
||||
if ( !openalEFXEAXReverb ) {
|
||||
alEffectf( openalReverbEffect, AL_REVERB_DENSITY, ClampALFloat( reverb.flEnvironmentSize / 16.0f, 0.0f, 1.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_DIFFUSION, ClampALFloat( reverb.flEnvironmentDiffusion, 0.0f, 1.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_GAIN, roomGain );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_GAINHF, roomHFGain );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_DECAY_TIME, ClampALFloat( reverb.flDecayTime, 0.1f, 20.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_DECAY_HFRATIO, ClampALFloat( reverb.flDecayHFRatio, 0.1f, 2.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_REFLECTIONS_GAIN, reflectionsGain );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_REFLECTIONS_DELAY, ClampALFloat( reverb.flReflectionsDelay, 0.0f, 0.3f ) );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_LATE_REVERB_GAIN, lateReverbGain );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_LATE_REVERB_DELAY, ClampALFloat( reverb.flReverbDelay, 0.0f, 0.1f ) );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_AIR_ABSORPTION_GAINHF, ClampALFloat( MillibelToGain( (long)( reverb.flAirAbsorptionHF * 1000.0f ) ), 0.892f, 1.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_REVERB_ROOM_ROLLOFF_FACTOR, ClampALFloat( reverb.flRoomRolloffFactor, 0.0f, 10.0f ) );
|
||||
alEffecti( openalReverbEffect, AL_REVERB_DECAY_HFLIMIT, ( reverb.ulFlags & EAXREVERBFLAGS_DECAYHFLIMIT ) ? AL_TRUE : AL_FALSE );
|
||||
alAuxiliaryEffectSloti( openalReverbSlot, AL_EFFECTSLOT_EFFECT, openalReverbEffect );
|
||||
return;
|
||||
}
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_DENSITY, ClampALFloat( reverb.flEnvironmentSize / 16.0f, 0.0f, 1.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_DIFFUSION, ClampALFloat( reverb.flEnvironmentDiffusion, 0.0f, 1.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_GAIN, roomGain );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_GAINHF, roomHFGain );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_DECAY_TIME, ClampALFloat( reverb.flDecayTime, 0.1f, 20.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_DECAY_HFRATIO, ClampALFloat( reverb.flDecayHFRatio, 0.1f, 2.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_REFLECTIONS_GAIN, reflectionsGain );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_REFLECTIONS_DELAY, ClampALFloat( reverb.flReflectionsDelay, 0.0f, 0.3f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_LATE_REVERB_GAIN, lateReverbGain );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_LATE_REVERB_DELAY, ClampALFloat( reverb.flReverbDelay, 0.0f, 0.1f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, ClampALFloat( MillibelToGain( (long)( reverb.flAirAbsorptionHF * 1000.0f ) ), 0.892f, 1.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, ClampALFloat( reverb.flRoomRolloffFactor, 0.0f, 10.0f ) );
|
||||
|
||||
if ( openalEFXEAXReverb ) {
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_GAINLF, MillibelToGain( reverb.lRoomLF ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_DECAY_LFRATIO, ClampALFloat( reverb.flDecayLFRatio, 0.1f, 2.0f ) );
|
||||
alEffectfv( openalReverbEffect, AL_EAXREVERB_REFLECTIONS_PAN, reflectionsPan );
|
||||
alEffectfv( openalReverbEffect, AL_EAXREVERB_LATE_REVERB_PAN, lateReverbPan );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_ECHO_TIME, ClampALFloat( reverb.flEchoTime, 0.075f, 0.25f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_ECHO_DEPTH, ClampALFloat( reverb.flEchoDepth, 0.0f, 1.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_MODULATION_TIME, ClampALFloat( reverb.flModulationTime, 0.04f, 4.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_MODULATION_DEPTH, ClampALFloat( reverb.flModulationDepth, 0.0f, 1.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_HFREFERENCE, ClampALFloat( reverb.flHFReference, 1000.0f, 20000.0f ) );
|
||||
alEffectf( openalReverbEffect, AL_EAXREVERB_LFREFERENCE, ClampALFloat( reverb.flLFReference, 20.0f, 1000.0f ) );
|
||||
alEffecti( openalReverbEffect, AL_EAXREVERB_DECAY_HFLIMIT, ( reverb.ulFlags & EAXREVERBFLAGS_DECAYHFLIMIT ) ? AL_TRUE : AL_FALSE );
|
||||
}
|
||||
|
||||
alAuxiliaryEffectSloti( openalReverbSlot, AL_EFFECTSLOT_EFFECT, openalReverbEffect );
|
||||
}
|
||||
|
||||
void idSoundSystemLocal::ApplyOpenALSourceEffects( ALuint source, long occlusion, bool stereo ) {
|
||||
if ( openalEFXAvailable ) {
|
||||
alSource3i( source, AL_AUXILIARY_SEND_FILTER, stereo ? 0 : openalReverbSlot, 0, AL_FILTER_NULL );
|
||||
if ( occlusion < 0 ) {
|
||||
const float gain = MillibelToGain( occlusion );
|
||||
alFilterf( openalOcclusionFilter, AL_LOWPASS_GAIN, gain );
|
||||
alFilterf( openalOcclusionFilter, AL_LOWPASS_GAINHF, gain );
|
||||
alSourcei( source, AL_DIRECT_FILTER, openalOcclusionFilter );
|
||||
} else {
|
||||
alSourcei( source, AL_DIRECT_FILTER, AL_FILTER_NULL );
|
||||
}
|
||||
} else if ( alEAXSet ) {
|
||||
alEAXSet( &EAXPROPERTYID_EAX_Source, EAXSOURCE_OCCLUSION, source, &occlusion, sizeof( occlusion ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
SoundReloadSounds_f
|
||||
@@ -203,9 +342,9 @@ void ListSounds_f( const idCmdArgs &args ) {
|
||||
common->Printf( "%8d total sounds\n", totalSounds );
|
||||
common->Printf( "%8d total samples loaded\n", totalSamples );
|
||||
common->Printf( "%8d kB total system memory used\n", totalMemory >> 10 );
|
||||
#if ID_OPENAL
|
||||
common->Printf( "%8d kB total OpenAL audio memory used\n", ( alGetInteger( alGetEnumValue( (ALubyte*)"AL_EAX_RAM_SIZE" ) ) - alGetInteger( alGetEnumValue( (ALubyte*)"AL_EAX_RAM_FREE" ) ) ) >> 10 );
|
||||
#endif
|
||||
if ( alIsExtensionPresent( ID_ALCHAR "EAX-RAM" ) == AL_TRUE ) {
|
||||
common->Printf( "%8d kB total OpenAL audio memory used\n", ( alGetInteger( alGetEnumValue( ID_ALCHAR "AL_EAX_RAM_SIZE" ) ) - alGetInteger( alGetEnumValue( ID_ALCHAR "AL_EAX_RAM_FREE" ) ) ) >> 10 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -364,6 +503,32 @@ void idSoundSystemLocal::Init() {
|
||||
finalMixBuffer = (float *) ( ( ( (INT_PTR)realAccum ) + 15 ) & ~15 );
|
||||
|
||||
graph = NULL;
|
||||
openalDevice = NULL;
|
||||
openalContext = NULL;
|
||||
openalSourceCount = 0;
|
||||
alEAXSet = (EAXSet)NULL;
|
||||
alEAXGet = (EAXGet)NULL;
|
||||
alEAXSetBufferMode = (EAXSetBufferMode)NULL;
|
||||
alEAXGetBufferMode = (EAXGetBufferMode)NULL;
|
||||
alGenEffects = NULL;
|
||||
alDeleteEffects = NULL;
|
||||
alEffecti = NULL;
|
||||
alEffectf = NULL;
|
||||
alEffectfv = NULL;
|
||||
alGenAuxiliaryEffectSlots = NULL;
|
||||
alDeleteAuxiliaryEffectSlots = NULL;
|
||||
alAuxiliaryEffectSloti = NULL;
|
||||
alAuxiliaryEffectSlotf = NULL;
|
||||
alSource3i = NULL;
|
||||
alGenFilters = NULL;
|
||||
alDeleteFilters = NULL;
|
||||
alFilteri = NULL;
|
||||
alFilterf = NULL;
|
||||
openalReverbEffect = 0;
|
||||
openalReverbSlot = 0;
|
||||
openalOcclusionFilter = 0;
|
||||
openalEFXAvailable = false;
|
||||
openalEFXEAXReverb = false;
|
||||
|
||||
if ( !s_noSound.GetBool() ) {
|
||||
idSampleDecoder::Init();
|
||||
@@ -371,91 +536,81 @@ void idSoundSystemLocal::Init() {
|
||||
}
|
||||
|
||||
// set up openal device and context
|
||||
common->StartupVariable( "s_useOpenAL", true );
|
||||
common->StartupVariable( "s_useEAXReverb", true );
|
||||
|
||||
if ( idSoundSystemLocal::s_useOpenAL.GetBool() || idSoundSystemLocal::s_useEAXReverb.GetBool() ) {
|
||||
if ( !s_noSound.GetBool() ) {
|
||||
if ( !Sys_LoadOpenAL() ) {
|
||||
idSoundSystemLocal::s_useOpenAL.SetBool( false );
|
||||
} else {
|
||||
common->Printf( "Setup OpenAL device and context... " );
|
||||
openalDevice = alcOpenDevice( NULL );
|
||||
common->Error( "OpenAL is required but %s could not be loaded", s_libOpenAL.GetString() );
|
||||
}
|
||||
|
||||
common->Printf( "Setup OpenAL device and context... " );
|
||||
openalDevice = alcOpenDevice( NULL );
|
||||
if ( openalDevice ) {
|
||||
openalContext = alcCreateContext( openalDevice, NULL );
|
||||
alcMakeContextCurrent( openalContext );
|
||||
common->Printf( "Done.\n" );
|
||||
|
||||
// try to obtain EAX extensions
|
||||
if ( idSoundSystemLocal::s_useEAXReverb.GetBool() && alIsExtensionPresent( ID_ALCHAR "EAX4.0" ) ) {
|
||||
idSoundSystemLocal::s_useOpenAL.SetBool( true ); // EAX presence causes AL enable
|
||||
alEAXSet = (EAXSet)alGetProcAddress( ID_ALCHAR "EAXSet" );
|
||||
alEAXGet = (EAXGet)alGetProcAddress( ID_ALCHAR "EAXGet" );
|
||||
common->Printf( "OpenAL: found EAX 4.0 extension\n" );
|
||||
} else {
|
||||
common->Printf( "OpenAL: EAX 4.0 extension not found\n" );
|
||||
idSoundSystemLocal::s_useEAXReverb.SetBool( false );
|
||||
alEAXSet = (EAXSet)NULL;
|
||||
alEAXGet = (EAXGet)NULL;
|
||||
}
|
||||
|
||||
// try to obtain EAX-RAM extension - not required for operation
|
||||
if ( alIsExtensionPresent( ID_ALCHAR "EAX-RAM" ) == AL_TRUE ) {
|
||||
alEAXSetBufferMode = (EAXSetBufferMode)alGetProcAddress( ID_ALCHAR "EAXSetBufferMode" );
|
||||
alEAXGetBufferMode = (EAXGetBufferMode)alGetProcAddress( ID_ALCHAR "EAXGetBufferMode" );
|
||||
common->Printf( "OpenAL: found EAX-RAM extension, %dkB\\%dkB\n", alGetInteger( alGetEnumValue( ID_ALCHAR "AL_EAX_RAM_FREE" ) ) / 1024, alGetInteger( alGetEnumValue( ID_ALCHAR "AL_EAX_RAM_SIZE" ) ) / 1024 );
|
||||
} else {
|
||||
alEAXSetBufferMode = (EAXSetBufferMode)NULL;
|
||||
alEAXGetBufferMode = (EAXGetBufferMode)NULL;
|
||||
common->Printf( "OpenAL: no EAX-RAM extension\n" );
|
||||
}
|
||||
|
||||
if ( !idSoundSystemLocal::s_useOpenAL.GetBool() ) {
|
||||
common->Printf( "OpenAL: disabling ( no EAX ). Using legacy mixer.\n" );
|
||||
|
||||
alcMakeContextCurrent( NULL );
|
||||
|
||||
}
|
||||
if ( !openalDevice || !openalContext || !alcMakeContextCurrent( openalContext ) ) {
|
||||
common->Printf( "failed.\n" );
|
||||
if ( openalContext ) {
|
||||
alcDestroyContext( openalContext );
|
||||
openalContext = NULL;
|
||||
|
||||
}
|
||||
if ( openalDevice ) {
|
||||
alcCloseDevice( openalDevice );
|
||||
openalDevice = NULL;
|
||||
} else {
|
||||
|
||||
ALuint handle;
|
||||
openalSourceCount = 0;
|
||||
|
||||
while ( openalSourceCount < 256 ) {
|
||||
alGetError();
|
||||
alGenSources( 1, &handle );
|
||||
if ( alGetError() != AL_NO_ERROR ) {
|
||||
break;
|
||||
} else {
|
||||
// store in source array
|
||||
openalSources[openalSourceCount].handle = handle;
|
||||
openalSources[openalSourceCount].startTime = 0;
|
||||
openalSources[openalSourceCount].chan = NULL;
|
||||
openalSources[openalSourceCount].inUse = false;
|
||||
openalSources[openalSourceCount].looping = false;
|
||||
|
||||
// initialise sources
|
||||
alSourcef( handle, AL_ROLLOFF_FACTOR, 0.0f );
|
||||
|
||||
// found one source
|
||||
openalSourceCount++;
|
||||
}
|
||||
}
|
||||
|
||||
common->Printf( "OpenAL: found %s\n", alcGetString( openalDevice, ALC_DEVICE_SPECIFIER ) );
|
||||
common->Printf( "OpenAL: found %d hardware voices\n", openalSourceCount );
|
||||
|
||||
// adjust source count to allow for at least eight stereo sounds to play
|
||||
openalSourceCount -= 8;
|
||||
|
||||
EAXAvailable = 1;
|
||||
}
|
||||
common->Error( "OpenAL device/context initialization failed" );
|
||||
}
|
||||
common->Printf( "Done.\n" );
|
||||
|
||||
if ( idSoundSystemLocal::s_useEAXReverb.GetBool() && InitOpenALEFX() ) {
|
||||
common->Printf( "OpenAL: found EFX%s reverb\n", openalEFXEAXReverb ? " EAX" : "" );
|
||||
EAXAvailable = 1;
|
||||
} else if ( idSoundSystemLocal::s_useEAXReverb.GetBool() && alIsExtensionPresent( ID_ALCHAR "EAX4.0" ) ) {
|
||||
alEAXSet = (EAXSet)alGetProcAddress( ID_ALCHAR "EAXSet" );
|
||||
alEAXGet = (EAXGet)alGetProcAddress( ID_ALCHAR "EAXGet" );
|
||||
common->Printf( "OpenAL: found EAX 4.0 extension\n" );
|
||||
EAXAvailable = 1;
|
||||
} else {
|
||||
common->Printf( "OpenAL: no EFX/EAX reverb extension\n" );
|
||||
idSoundSystemLocal::s_useEAXReverb.SetBool( false );
|
||||
alEAXSet = (EAXSet)NULL;
|
||||
alEAXGet = (EAXGet)NULL;
|
||||
EAXAvailable = 0;
|
||||
}
|
||||
|
||||
// try to obtain EAX-RAM extension - not required for operation
|
||||
if ( alIsExtensionPresent( ID_ALCHAR "EAX-RAM" ) == AL_TRUE ) {
|
||||
alEAXSetBufferMode = (EAXSetBufferMode)alGetProcAddress( ID_ALCHAR "EAXSetBufferMode" );
|
||||
alEAXGetBufferMode = (EAXGetBufferMode)alGetProcAddress( ID_ALCHAR "EAXGetBufferMode" );
|
||||
common->Printf( "OpenAL: found EAX-RAM extension, %dkB\\%dkB\n", alGetInteger( alGetEnumValue( ID_ALCHAR "AL_EAX_RAM_FREE" ) ) / 1024, alGetInteger( alGetEnumValue( ID_ALCHAR "AL_EAX_RAM_SIZE" ) ) / 1024 );
|
||||
} else {
|
||||
alEAXSetBufferMode = (EAXSetBufferMode)NULL;
|
||||
alEAXGetBufferMode = (EAXGetBufferMode)NULL;
|
||||
common->Printf( "OpenAL: no EAX-RAM extension\n" );
|
||||
}
|
||||
|
||||
ALuint handle;
|
||||
openalSourceCount = 0;
|
||||
while ( openalSourceCount < 256 ) {
|
||||
alGetError();
|
||||
alGenSources( 1, &handle );
|
||||
if ( alGetError() != AL_NO_ERROR ) {
|
||||
break;
|
||||
}
|
||||
openalSources[openalSourceCount].handle = handle;
|
||||
openalSources[openalSourceCount].startTime = 0;
|
||||
openalSources[openalSourceCount].chan = NULL;
|
||||
openalSources[openalSourceCount].inUse = false;
|
||||
openalSources[openalSourceCount].looping = false;
|
||||
openalSources[openalSourceCount].stereo = false;
|
||||
alSourcef( handle, AL_ROLLOFF_FACTOR, 0.0f );
|
||||
openalSourceCount++;
|
||||
}
|
||||
|
||||
common->Printf( "OpenAL: found %s\n", alcGetString( openalDevice, ALC_DEVICE_SPECIFIER ) );
|
||||
common->Printf( "OpenAL: found %d voices\n", openalSourceCount );
|
||||
}
|
||||
|
||||
useOpenAL = idSoundSystemLocal::s_useOpenAL.GetBool();
|
||||
useEAXReverb = idSoundSystemLocal::s_useEAXReverb.GetBool();
|
||||
|
||||
StartSoundAsyncThread();
|
||||
@@ -484,13 +639,9 @@ void idSoundSystemLocal::Shutdown() {
|
||||
EFXDatabase.Clear();
|
||||
|
||||
// destroy openal sources
|
||||
if ( useOpenAL ) {
|
||||
|
||||
if ( openalContext ) {
|
||||
efxloaded = false;
|
||||
|
||||
// adjust source count back up to allow for freeing of all resources
|
||||
openalSourceCount += 8;
|
||||
|
||||
for ( ALsizei i = 0; i < openalSourceCount; i++ ) {
|
||||
// stop source
|
||||
alSourceStop( openalSources[i].handle );
|
||||
@@ -514,7 +665,8 @@ void idSoundSystemLocal::Shutdown() {
|
||||
soundCache = NULL;
|
||||
|
||||
// destroy openal device and context
|
||||
if ( useOpenAL ) {
|
||||
if ( openalContext ) {
|
||||
ShutdownOpenALEFX();
|
||||
alcMakeContextCurrent( NULL );
|
||||
|
||||
alcDestroyContext( openalContext );
|
||||
@@ -547,20 +699,18 @@ bool idSoundSystemLocal::InitHW() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !useOpenAL ) {
|
||||
if ( !snd_audio_hw->Initialize() ) {
|
||||
delete snd_audio_hw;
|
||||
snd_audio_hw = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( snd_audio_hw->GetNumberOfSpeakers() == 0 ) {
|
||||
return false;
|
||||
}
|
||||
// put the real number in there
|
||||
s_numberOfSpeakers.SetInteger( snd_audio_hw->GetNumberOfSpeakers() );
|
||||
if ( !snd_audio_hw->Initialize() ) {
|
||||
delete snd_audio_hw;
|
||||
snd_audio_hw = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( snd_audio_hw->GetNumberOfSpeakers() == 0 ) {
|
||||
return false;
|
||||
}
|
||||
// put the real number in there
|
||||
s_numberOfSpeakers.SetInteger( snd_audio_hw->GetNumberOfSpeakers() );
|
||||
|
||||
isInitialized = true;
|
||||
shutdown = false;
|
||||
|
||||
@@ -676,20 +826,9 @@ int idSoundSystemLocal::AsyncUpdate( int inTime ) {
|
||||
ulong dwCurrentWritePos;
|
||||
dword dwCurrentBlock;
|
||||
|
||||
// If not using openal, get actual playback position from sound hardware
|
||||
if ( useOpenAL ) {
|
||||
// here we do it in samples ( overflows in 27 hours or so )
|
||||
dwCurrentWritePos = idMath::Ftol( (float)Sys_Milliseconds() * 44.1f ) % ( MIXBUFFER_SAMPLES * ROOM_SLICES_IN_BUFFER );
|
||||
dwCurrentBlock = dwCurrentWritePos / MIXBUFFER_SAMPLES;
|
||||
} else {
|
||||
// and here in bytes
|
||||
// get the current byte position in the buffer where the sound hardware is currently reading
|
||||
if ( !snd_audio_hw->GetCurrentPosition( &dwCurrentWritePos ) ) {
|
||||
return 0;
|
||||
}
|
||||
// mixBufferSize is in bytes
|
||||
dwCurrentBlock = dwCurrentWritePos / snd_audio_hw->GetMixBufferSize();
|
||||
}
|
||||
// here we do it in samples ( overflows in 27 hours or so )
|
||||
dwCurrentWritePos = idMath::Ftol( (float)Sys_Milliseconds() * 44.1f ) % ( MIXBUFFER_SAMPLES * ROOM_SLICES_IN_BUFFER );
|
||||
dwCurrentBlock = dwCurrentWritePos / MIXBUFFER_SAMPLES;
|
||||
|
||||
if ( nextWriteBlock == 0xffffffff ) {
|
||||
nextWriteBlock = dwCurrentBlock;
|
||||
@@ -699,17 +838,6 @@ int idSoundSystemLocal::AsyncUpdate( int inTime ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// lock the buffer so we can actually write to it
|
||||
short *fBlock = NULL;
|
||||
ulong fBlockLen = 0;
|
||||
if ( !useOpenAL ) {
|
||||
snd_audio_hw->Lock( (void **)&fBlock, &fBlockLen );
|
||||
if ( !fBlock ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int j;
|
||||
soundStats.runs++;
|
||||
soundStats.activeSounds = 0;
|
||||
|
||||
@@ -742,37 +870,16 @@ int idSoundSystemLocal::AsyncUpdate( int inTime ) {
|
||||
soundStats.missedWindow++;
|
||||
}
|
||||
|
||||
if ( useOpenAL ) {
|
||||
// enable audio hardware caching
|
||||
alcSuspendContext( openalContext );
|
||||
} else {
|
||||
// clear the buffer for all the mixing output
|
||||
SIMDProcessor->Memset( finalMixBuffer, 0, MIXBUFFER_SAMPLES * sizeof(float) * numSpeakers );
|
||||
}
|
||||
// enable audio hardware caching
|
||||
alcSuspendContext( openalContext );
|
||||
|
||||
// let the active sound world mix all the channels in unless muted or avi demo recording
|
||||
if ( !muted && currentSoundWorld && !currentSoundWorld->fpa[0] ) {
|
||||
currentSoundWorld->MixLoop( newSoundTime, numSpeakers, finalMixBuffer );
|
||||
}
|
||||
|
||||
if ( useOpenAL ) {
|
||||
// disable audio hardware caching (this updates ALL settings since last alcSuspendContext)
|
||||
alcProcessContext( openalContext );
|
||||
} else {
|
||||
short *dest = fBlock + nextWriteSamples * numSpeakers;
|
||||
|
||||
SIMDProcessor->MixedSoundToSamples( dest, finalMixBuffer, MIXBUFFER_SAMPLES * numSpeakers );
|
||||
|
||||
// allow swapping the left / right speaker channels for people with miswired systems
|
||||
if ( numSpeakers == 2 && s_reverse.GetBool() ) {
|
||||
for( j = 0; j < MIXBUFFER_SAMPLES; j++ ) {
|
||||
short temp = dest[j*2];
|
||||
dest[j*2] = dest[j*2+1];
|
||||
dest[j*2+1] = temp;
|
||||
}
|
||||
}
|
||||
snd_audio_hw->Unlock( fBlock, fBlockLen );
|
||||
}
|
||||
// disable audio hardware caching (this updates ALL settings since last alcSuspendContext)
|
||||
alcProcessContext( openalContext );
|
||||
|
||||
CurrentSoundTime = newSoundTime;
|
||||
|
||||
@@ -795,10 +902,6 @@ int idSoundSystemLocal::AsyncUpdateWrite( int inTime ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !useOpenAL ) {
|
||||
snd_audio_hw->Flush();
|
||||
}
|
||||
|
||||
unsigned int dwCurrentBlock = (unsigned int)( inTime * 44.1f / MIXBUFFER_SAMPLES );
|
||||
|
||||
if ( nextWriteBlock == 0xffffffff ) {
|
||||
@@ -816,38 +919,16 @@ int idSoundSystemLocal::AsyncUpdateWrite( int inTime ) {
|
||||
int sampleTime = dwCurrentBlock * MIXBUFFER_SAMPLES;
|
||||
int numSpeakers = snd_audio_hw->GetNumberOfSpeakers();
|
||||
|
||||
if ( useOpenAL ) {
|
||||
// enable audio hardware caching
|
||||
alcSuspendContext( openalContext );
|
||||
} else {
|
||||
// clear the buffer for all the mixing output
|
||||
SIMDProcessor->Memset( finalMixBuffer, 0, MIXBUFFER_SAMPLES * sizeof(float) * numSpeakers );
|
||||
}
|
||||
// enable audio hardware caching
|
||||
alcSuspendContext( openalContext );
|
||||
|
||||
// let the active sound world mix all the channels in unless muted or avi demo recording
|
||||
if ( !muted && currentSoundWorld && !currentSoundWorld->fpa[0] ) {
|
||||
currentSoundWorld->MixLoop( sampleTime, numSpeakers, finalMixBuffer );
|
||||
}
|
||||
|
||||
if ( useOpenAL ) {
|
||||
// disable audio hardware caching (this updates ALL settings since last alcSuspendContext)
|
||||
alcProcessContext( openalContext );
|
||||
} else {
|
||||
short *dest = snd_audio_hw->GetMixBuffer();
|
||||
|
||||
SIMDProcessor->MixedSoundToSamples( dest, finalMixBuffer, MIXBUFFER_SAMPLES * numSpeakers );
|
||||
|
||||
// allow swapping the left / right speaker channels for people with miswired systems
|
||||
if ( numSpeakers == 2 && s_reverse.GetBool() ) {
|
||||
int j;
|
||||
for( j = 0; j < MIXBUFFER_SAMPLES; j++ ) {
|
||||
short temp = dest[j*2];
|
||||
dest[j*2] = dest[j*2+1];
|
||||
dest[j*2+1] = temp;
|
||||
}
|
||||
}
|
||||
snd_audio_hw->Write( false );
|
||||
}
|
||||
// disable audio hardware caching (this updates ALL settings since last alcSuspendContext)
|
||||
alcProcessContext( openalContext );
|
||||
|
||||
// only move to the next block if the write was successful
|
||||
nextWriteBlock = dwCurrentBlock + 1;
|
||||
@@ -1288,13 +1369,13 @@ void idSoundSystemLocal::FreeOpenALSource( ALuint handle ) {
|
||||
if ( openalSources[i].chan ) {
|
||||
openalSources[i].chan->openalSource = NULL;
|
||||
}
|
||||
#if ID_OPENAL
|
||||
// Reset source EAX ROOM level when freeing stereo source
|
||||
if ( openalSources[i].stereo && alEAXSet ) {
|
||||
if ( openalEFXAvailable ) {
|
||||
ApplyOpenALSourceEffects( openalSources[i].handle, 0, openalSources[i].stereo );
|
||||
} else if ( openalSources[i].stereo && alEAXSet ) {
|
||||
long Room = EAXSOURCE_DEFAULTROOM;
|
||||
alEAXSet( &EAXPROPERTYID_EAX_Source, EAXSOURCE_ROOM, openalSources[i].handle, &Room, sizeof(Room));
|
||||
}
|
||||
#endif
|
||||
// Initialize structure
|
||||
openalSources[i].startTime = 0;
|
||||
openalSources[i].chan = NULL;
|
||||
@@ -1395,8 +1476,6 @@ void idSoundSystemLocal::DoEnviroSuit( float* samples, int numSamples, int numSp
|
||||
float out[10000], *out_p = out + 2;
|
||||
float in[10000], *in_p = in + 2;
|
||||
|
||||
assert( !idSoundSystemLocal::useOpenAL );
|
||||
|
||||
if ( !fxList.Num() ) {
|
||||
for ( int i = 0; i < 6; i++ ) {
|
||||
SoundFX* fx;
|
||||
@@ -1471,9 +1550,6 @@ idSoundSystemLocal::EAXAvailable
|
||||
===============
|
||||
*/
|
||||
int idSoundSystemLocal::IsEAXAvailable( void ) {
|
||||
#if !ID_OPENAL
|
||||
return -1;
|
||||
#else
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
|
||||
@@ -1485,11 +1561,22 @@ int idSoundSystemLocal::IsEAXAvailable( void ) {
|
||||
EAXAvailable = 2;
|
||||
return 2;
|
||||
}
|
||||
// when dynamically loading the OpenAL subsystem, we need to get a context before alIsExtensionPresent would work
|
||||
// when dynamically loading the OpenAL subsystem, we need to get a context before extension checks work
|
||||
device = alcOpenDevice( NULL );
|
||||
if ( !device ) {
|
||||
EAXAvailable = 0;
|
||||
return 0;
|
||||
}
|
||||
context = alcCreateContext( device, NULL );
|
||||
alcMakeContextCurrent( context );
|
||||
if ( alIsExtensionPresent( ID_ALCHAR "EAX4.0" ) ) {
|
||||
if ( !context || !alcMakeContextCurrent( context ) ) {
|
||||
if ( context ) {
|
||||
alcDestroyContext( context );
|
||||
}
|
||||
alcCloseDevice( device );
|
||||
EAXAvailable = 0;
|
||||
return 0;
|
||||
}
|
||||
if ( alGetProcAddress( ID_ALCHAR "alGenEffects" ) || alIsExtensionPresent( ID_ALCHAR "EAX4.0" ) ) {
|
||||
alcMakeContextCurrent( NULL );
|
||||
alcDestroyContext( context );
|
||||
alcCloseDevice( device );
|
||||
@@ -1501,7 +1588,6 @@ int idSoundSystemLocal::IsEAXAvailable( void ) {
|
||||
alcCloseDevice( device );
|
||||
EAXAvailable = 0;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef PREY
|
||||
@@ -1662,4 +1748,4 @@ idSoundWorld* idSoundSystemLocal::GetSoundWorldFromId(int worldId) {
|
||||
|
||||
idSoundSample* idSoundSystemLocal::FindSample(const idStr& filename) {
|
||||
return soundCache->FindSound(filename, false);
|
||||
}
|
||||
}
|
||||
|
||||
+46
-150
@@ -276,7 +276,7 @@ void idSoundWorldLocal::ProcessDemoCommand( idDemoFile *readDemo ) {
|
||||
readDemo->ReadMat3( axis );
|
||||
readDemo->ReadInt( listenerId );
|
||||
readDemo->ReadInt( gameTime );
|
||||
|
||||
|
||||
PlaceListener( origin, axis, listenerId, gameTime, "" );
|
||||
};
|
||||
break;
|
||||
@@ -423,66 +423,63 @@ void idSoundWorldLocal::MixLoop( int current44kHz, int numSpeakers, float *final
|
||||
|
||||
// if noclip flying outside the world, leave silence
|
||||
if ( listenerArea == -1 ) {
|
||||
if ( idSoundSystemLocal::useOpenAL )
|
||||
alListenerf( AL_GAIN, 0.0f );
|
||||
alListenerf( AL_GAIN, 0.0f );
|
||||
return;
|
||||
}
|
||||
|
||||
// update the listener position and orientation
|
||||
if ( idSoundSystemLocal::useOpenAL ) {
|
||||
ALfloat listenerPosition[3];
|
||||
ALfloat listenerPosition[3];
|
||||
|
||||
listenerPosition[0] = -listenerPos.y;
|
||||
listenerPosition[1] = listenerPos.z;
|
||||
listenerPosition[2] = -listenerPos.x;
|
||||
listenerPosition[0] = -listenerPos.y;
|
||||
listenerPosition[1] = listenerPos.z;
|
||||
listenerPosition[2] = -listenerPos.x;
|
||||
|
||||
ALfloat listenerOrientation[6];
|
||||
ALfloat listenerOrientation[6];
|
||||
|
||||
listenerOrientation[0] = -listenerAxis[0].y;
|
||||
listenerOrientation[1] = listenerAxis[0].z;
|
||||
listenerOrientation[2] = -listenerAxis[0].x;
|
||||
listenerOrientation[0] = -listenerAxis[0].y;
|
||||
listenerOrientation[1] = listenerAxis[0].z;
|
||||
listenerOrientation[2] = -listenerAxis[0].x;
|
||||
|
||||
listenerOrientation[3] = -listenerAxis[2].y;
|
||||
listenerOrientation[4] = listenerAxis[2].z;
|
||||
listenerOrientation[5] = -listenerAxis[2].x;
|
||||
listenerOrientation[3] = -listenerAxis[2].y;
|
||||
listenerOrientation[4] = listenerAxis[2].z;
|
||||
listenerOrientation[5] = -listenerAxis[2].x;
|
||||
|
||||
alListenerf( AL_GAIN, 1.0f );
|
||||
alListenerfv( AL_POSITION, listenerPosition );
|
||||
alListenerfv( AL_ORIENTATION, listenerOrientation );
|
||||
alListenerf( AL_GAIN, 1.0f );
|
||||
alListenerfv( AL_POSITION, listenerPosition );
|
||||
alListenerfv( AL_ORIENTATION, listenerOrientation );
|
||||
|
||||
#if ID_OPENAL
|
||||
if ( soundSystemLocal.s_useEAXReverb.GetBool() ) {
|
||||
if ( soundSystemLocal.efxloaded ) {
|
||||
idSoundEffect *effect = NULL;
|
||||
int EnvironmentID = -1;
|
||||
idStr defaultStr( "default" );
|
||||
idStr listenerAreaStr( listenerArea );
|
||||
|
||||
soundSystemLocal.EFXDatabase.FindEffect( listenerAreaStr, &effect, &EnvironmentID );
|
||||
if (!effect)
|
||||
soundSystemLocal.EFXDatabase.FindEffect( listenerAreaName, &effect, &EnvironmentID );
|
||||
if (!effect)
|
||||
soundSystemLocal.EFXDatabase.FindEffect( defaultStr, &effect, &EnvironmentID );
|
||||
|
||||
// only update if change in settings
|
||||
if ( soundSystemLocal.s_muteEAXReverb.GetBool() || ( listenerEnvironmentID != EnvironmentID ) ) {
|
||||
EAXREVERBPROPERTIES EnvironmentParameters;
|
||||
|
||||
// get area reverb setting from EAX Manager
|
||||
if ( ( effect ) && ( effect->data) && ( memcpy( &EnvironmentParameters, effect->data, effect->datasize ) ) ) {
|
||||
if ( soundSystemLocal.s_muteEAXReverb.GetBool() ) {
|
||||
EnvironmentParameters.lRoom = -10000;
|
||||
EnvironmentID = -2;
|
||||
}
|
||||
if ( soundSystemLocal.alEAXSet ) {
|
||||
soundSystemLocal.alEAXSet( &EAXPROPERTYID_EAX_FXSlot0, EAXREVERB_ALLPARAMETERS, 0, &EnvironmentParameters, sizeof( EnvironmentParameters ) );
|
||||
}
|
||||
if ( soundSystemLocal.s_useEAXReverb.GetBool() ) {
|
||||
if ( soundSystemLocal.efxloaded ) {
|
||||
idSoundEffect *effect = NULL;
|
||||
int EnvironmentID = -1;
|
||||
idStr defaultStr( "default" );
|
||||
idStr listenerAreaStr( listenerArea );
|
||||
|
||||
soundSystemLocal.EFXDatabase.FindEffect( listenerAreaStr, &effect, &EnvironmentID );
|
||||
if (!effect)
|
||||
soundSystemLocal.EFXDatabase.FindEffect( listenerAreaName, &effect, &EnvironmentID );
|
||||
if (!effect)
|
||||
soundSystemLocal.EFXDatabase.FindEffect( defaultStr, &effect, &EnvironmentID );
|
||||
|
||||
// only update if change in settings
|
||||
if ( soundSystemLocal.s_muteEAXReverb.GetBool() || ( listenerEnvironmentID != EnvironmentID ) ) {
|
||||
EAXREVERBPROPERTIES EnvironmentParameters;
|
||||
|
||||
// get area reverb setting from EAX Manager
|
||||
if ( ( effect ) && ( effect->data) && ( memcpy( &EnvironmentParameters, effect->data, effect->datasize ) ) ) {
|
||||
if ( soundSystemLocal.s_muteEAXReverb.GetBool() ) {
|
||||
EnvironmentParameters.lRoom = -10000;
|
||||
EnvironmentID = -2;
|
||||
}
|
||||
if ( soundSystemLocal.openalEFXAvailable ) {
|
||||
soundSystemLocal.ApplyOpenALReverb( EnvironmentParameters );
|
||||
} else if ( soundSystemLocal.alEAXSet ) {
|
||||
soundSystemLocal.alEAXSet( &EAXPROPERTYID_EAX_FXSlot0, EAXREVERB_ALLPARAMETERS, 0, &EnvironmentParameters, sizeof( EnvironmentParameters ) );
|
||||
}
|
||||
listenerEnvironmentID = EnvironmentID;
|
||||
}
|
||||
listenerEnvironmentID = EnvironmentID;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// debugging option to mute all but a single soundEmitter
|
||||
@@ -530,9 +527,6 @@ void idSoundWorldLocal::MixLoop( int current44kHz, int numSpeakers, float *final
|
||||
}
|
||||
}
|
||||
|
||||
if ( !idSoundSystemLocal::useOpenAL && enviroSuitActive ) {
|
||||
soundSystemLocal.DoEnviroSuit( finalMixBuffer, MIXBUFFER_SAMPLES, numSpeakers );
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
@@ -1718,7 +1712,7 @@ void idSoundWorldLocal::AddChannelContribution( idSoundEmitterLocal *sound, idSo
|
||||
//
|
||||
// allocate and initialize hardware source
|
||||
//
|
||||
if ( idSoundSystemLocal::useOpenAL && sound->removeStatus < REMOVE_STATUS_SAMPLEFINISHED ) {
|
||||
if ( sound->removeStatus < REMOVE_STATUS_SAMPLEFINISHED ) {
|
||||
if ( !alIsSource( chan->openalSource ) ) {
|
||||
chan->openalSource = soundSystemLocal.AllocOpenALSource( chan, !chan->leadinSample->hardwareBuffer || !chan->soundShader->entries[0]->hardwareBuffer || looping, chan->leadinSample->objectInfo.nChannels == 2 );
|
||||
}
|
||||
@@ -1746,12 +1740,8 @@ void idSoundWorldLocal::AddChannelContribution( idSoundEmitterLocal *sound, idSo
|
||||
alSourcef( chan->openalSource, AL_MAX_DISTANCE, maxd );
|
||||
#endif
|
||||
alSourcef( chan->openalSource, AL_PITCH, ( slowmoActive && !chan->disallowSlow ) ? ( slowmoSpeed ) : ( 1.0f ) );
|
||||
#if ID_OPENAL
|
||||
long lOcclusion = ( enviroSuitActive ? -1150 : 0);
|
||||
if ( soundSystemLocal.alEAXSet ) {
|
||||
soundSystemLocal.alEAXSet( &EAXPROPERTYID_EAX_Source, EAXSOURCE_OCCLUSION, chan->openalSource, &lOcclusion, sizeof(lOcclusion) );
|
||||
}
|
||||
#endif
|
||||
soundSystemLocal.ApplyOpenALSourceEffects( chan->openalSource, lOcclusion, chan->leadinSample->objectInfo.nChannels == 2 );
|
||||
if ( ( !looping && chan->leadinSample->hardwareBuffer ) || ( looping && chan->soundShader->entries[0]->hardwareBuffer ) ) {
|
||||
// handle uncompressed (non streaming) single shot and looping sounds
|
||||
if ( chan->triggered ) {
|
||||
@@ -1809,100 +1799,6 @@ void idSoundWorldLocal::AddChannelContribution( idSoundEmitterLocal *sound, idSo
|
||||
chan->triggered = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if ( slowmoActive && !chan->disallowSlow ) {
|
||||
idSlowChannel slow = sound->GetSlowChannel( chan );
|
||||
|
||||
slow.AttachSoundChannel( chan );
|
||||
|
||||
if ( sample->objectInfo.nChannels == 2 ) {
|
||||
// need to add a stereo path, but very few samples go through this
|
||||
memset( alignedInputSamples, 0, sizeof( alignedInputSamples[0] ) * MIXBUFFER_SAMPLES * 2 );
|
||||
} else {
|
||||
slow.GatherChannelSamples( offset, MIXBUFFER_SAMPLES, alignedInputSamples );
|
||||
}
|
||||
|
||||
sound->SetSlowChannel( chan, slow );
|
||||
} else {
|
||||
sound->ResetSlowChannel( chan );
|
||||
|
||||
// if we are getting a stereo sample adjust accordingly
|
||||
if ( sample->objectInfo.nChannels == 2 ) {
|
||||
// we should probably check to make sure any looping is also to a stereo sample...
|
||||
chan->GatherChannelSamples( offset*2, MIXBUFFER_SAMPLES*2, alignedInputSamples );
|
||||
} else {
|
||||
chan->GatherChannelSamples( offset, MIXBUFFER_SAMPLES, alignedInputSamples );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// work out the left / right ear values
|
||||
//
|
||||
float ears[6];
|
||||
if ( global || omni ) {
|
||||
// same for all speakers
|
||||
for ( int i = 0 ; i < 6 ; i++ ) {
|
||||
ears[i] = idSoundSystemLocal::s_globalFraction.GetFloat() * volume;
|
||||
}
|
||||
ears[3] = idSoundSystemLocal::s_subFraction.GetFloat() * volume; // subwoofer
|
||||
|
||||
} else {
|
||||
CalcEars( numSpeakers, spatializedOriginInMeters, listenerPos, listenerAxis, ears, spatialize );
|
||||
|
||||
for ( int i = 0 ; i < 6 ; i++ ) {
|
||||
ears[i] *= volume;
|
||||
}
|
||||
}
|
||||
|
||||
// if the mask is 0, it really means do every channel
|
||||
if ( !mask ) {
|
||||
mask = 255;
|
||||
}
|
||||
// cleared mask bits set the mix volume to zero
|
||||
for ( int i = 0 ; i < 6 ; i++ ) {
|
||||
if ( !(mask & ( 1 << i ) ) ) {
|
||||
ears[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// if sounds are generally normalized, using a mixing volume over 1.0 will
|
||||
// almost always cause clipping noise. If samples aren't normalized, there
|
||||
// is a good call to allow overvolumes
|
||||
if ( idSoundSystemLocal::s_clipVolumes.GetBool() && !( parms->soundShaderFlags & SSF_UNCLAMPED ) ) {
|
||||
for ( int i = 0 ; i < 6 ; i++ ) {
|
||||
if ( ears[i] > 1.0f ) {
|
||||
ears[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if this is the very first mixing block, set the lastV
|
||||
// to the current volume
|
||||
if ( current44kHz == chan->trigger44kHzTime ) {
|
||||
for ( j = 0 ; j < 6 ; j++ ) {
|
||||
chan->lastV[j] = ears[j];
|
||||
}
|
||||
}
|
||||
|
||||
if ( numSpeakers == 6 ) {
|
||||
if ( sample->objectInfo.nChannels == 1 ) {
|
||||
SIMDProcessor->MixSoundSixSpeakerMono( finalMixBuffer, alignedInputSamples, MIXBUFFER_SAMPLES, chan->lastV, ears );
|
||||
} else {
|
||||
SIMDProcessor->MixSoundSixSpeakerStereo( finalMixBuffer, alignedInputSamples, MIXBUFFER_SAMPLES, chan->lastV, ears );
|
||||
}
|
||||
} else {
|
||||
if ( sample->objectInfo.nChannels == 1 ) {
|
||||
SIMDProcessor->MixSoundTwoSpeakerMono( finalMixBuffer, alignedInputSamples, MIXBUFFER_SAMPLES, chan->lastV, ears );
|
||||
} else {
|
||||
SIMDProcessor->MixSoundTwoSpeakerStereo( finalMixBuffer, alignedInputSamples, MIXBUFFER_SAMPLES, chan->lastV, ears );
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0 ; j < 6 ; j++ ) {
|
||||
chan->lastV[j] = ears[j];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
soundSystemLocal.soundStats.activeSounds++;
|
||||
|
||||
@@ -133,7 +133,7 @@ void Sys_DoPreferences( void ) {
|
||||
KeyMap *keymap = (KeyMap*)&km;
|
||||
GetKeys(*keymap);
|
||||
|
||||
Boolean prefAways, keyFound, useOpenAL;
|
||||
Boolean prefAways, keyFound;
|
||||
prefAways = CFPreferencesGetAppBooleanValue ( kPref_PrefsDialogAlways, kCFPreferencesCurrentApplication, &keyFound );
|
||||
bool fAlways = prefAways && keyFound;
|
||||
|
||||
@@ -191,15 +191,7 @@ void Sys_DoPreferences( void ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
useOpenAL = CFPreferencesGetAppBooleanValue (kPref_PrefsDialogOpenAL, kCFPreferencesCurrentApplication, &keyFound);
|
||||
if ( keyFound && useOpenAL ) {
|
||||
cvarSystem->SetCVarInteger( "com_asyncSound", 1 );
|
||||
cvarSystem->SetCVarInteger( "s_useOpenAL", 1 );
|
||||
}
|
||||
else {
|
||||
cvarSystem->SetCVarInteger( "com_asyncSound", 2 );
|
||||
cvarSystem->SetCVarInteger( "s_useOpenAL", 0 );
|
||||
}
|
||||
cvarSystem->SetCVarInteger( "com_asyncSound", 1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,533 +0,0 @@
|
||||
/******************************************************************
|
||||
*
|
||||
* EAX.H - Environmental Audio Extensions version 3.0
|
||||
* for OpenAL and DirectSound3D
|
||||
* Updated May 22, 2001 by Jean-Marc Jot, Sam Dicker (version 1.0).
|
||||
*
|
||||
*******************************************************************
|
||||
*/
|
||||
|
||||
#ifndef EAX_H_INCLUDED
|
||||
#define EAX_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef OPENAL
|
||||
#include <dsound.h>
|
||||
|
||||
/*
|
||||
* EAX Wrapper Interface (using Direct X 7) {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound,
|
||||
0x4ff53b81,
|
||||
0x1ce0,
|
||||
0x11d3,
|
||||
0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5);
|
||||
|
||||
/*
|
||||
* EAX Wrapper Interface (using Direct X 8) {CA503B60-B176-11d4-A094-D0C0BF3A560C}
|
||||
*/
|
||||
DEFINE_GUID(CLSID_EAXDirectSound8,
|
||||
0xca503b60,
|
||||
0xb176,
|
||||
0x11d4,
|
||||
0xa0, 0x94, 0xd0, 0xc0, 0xbf, 0x3a, 0x56, 0xc);
|
||||
|
||||
|
||||
|
||||
#ifdef DIRECTSOUND_VERSION
|
||||
#if DIRECTSOUND_VERSION == 0x0800
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate8(GUID*, LPDIRECTSOUND8*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE8)(GUID*, LPDIRECTSOUND*, IUnknown FAR*);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID*, LPDIRECTSOUND*, IUnknown FAR *);
|
||||
typedef HRESULT (FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID*, LPDIRECTSOUND*, IUnknown FAR*);
|
||||
|
||||
#else // OPENAL
|
||||
#include "..\Sdk\OpenAL\Include\al.h"
|
||||
|
||||
#ifndef GUID_DEFINED
|
||||
#define GUID_DEFINED
|
||||
typedef struct _GUID
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[8];
|
||||
} GUID;
|
||||
#endif // !GUID_DEFINED
|
||||
|
||||
#ifndef DEFINE_GUID
|
||||
#ifndef INITGUID
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID FAR name
|
||||
#else
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
extern const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
#endif // INITGUID
|
||||
#endif // DEFINE_GUID
|
||||
|
||||
|
||||
/*
|
||||
* EAX OpenAL Extension
|
||||
*/
|
||||
typedef ALenum (*EAXSet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
typedef ALenum (*EAXGet)(const GUID*, ALuint, ALuint, ALvoid*, ALuint);
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 4)
|
||||
|
||||
/*
|
||||
* EAX 3.0 listener property set {A8FA6880-B476-11d3-BDB9-00C0F02DDF87}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX30_ListenerProperties,
|
||||
0xa8fa6882,
|
||||
0xb476,
|
||||
0x11d3,
|
||||
0xbd, 0xb9, 0x00, 0xc0, 0xf0, 0x2d, 0xdf, 0x87);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX_ListenerProperties DSPROPSETID_EAX30_ListenerProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXLISTENER_NONE,
|
||||
DSPROPERTY_EAXLISTENER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENT,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION,
|
||||
DSPROPERTY_EAXLISTENER_ROOM,
|
||||
DSPROPERTY_EAXLISTENER_ROOMHF,
|
||||
DSPROPERTY_EAXLISTENER_ROOMLF,
|
||||
DSPROPERTY_EAXLISTENER_DECAYTIME,
|
||||
DSPROPERTY_EAXLISTENER_DECAYHFRATIO,
|
||||
DSPROPERTY_EAXLISTENER_DECAYLFRATIO,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONS,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONSPAN,
|
||||
DSPROPERTY_EAXLISTENER_REVERB,
|
||||
DSPROPERTY_EAXLISTENER_REVERBDELAY,
|
||||
DSPROPERTY_EAXLISTENER_REVERBPAN,
|
||||
DSPROPERTY_EAXLISTENER_ECHOTIME,
|
||||
DSPROPERTY_EAXLISTENER_ECHODEPTH,
|
||||
DSPROPERTY_EAXLISTENER_MODULATIONTIME,
|
||||
DSPROPERTY_EAXLISTENER_MODULATIONDEPTH,
|
||||
DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF,
|
||||
DSPROPERTY_EAXLISTENER_HFREFERENCE,
|
||||
DSPROPERTY_EAXLISTENER_LFREFERENCE,
|
||||
DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXLISTENER_FLAGS
|
||||
} DSPROPERTY_EAX_LISTENERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAXLISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXLISTENER_NONE | \
|
||||
DSPROPERTY_EAXLISTENER_IMMEDIATE)
|
||||
|
||||
typedef struct _EAXVECTOR {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} EAXVECTOR;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXLISTENER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
// - all times and delays are in seconds
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myListener.lRoom = -1000;
|
||||
// myListener.lRoomHF = -100;
|
||||
// ...
|
||||
// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myListener = { -1000, -100, ... , 0x00000009 };
|
||||
// If you want to save and load presets in binary form, you
|
||||
// should define your own structure to insure future compatibility.
|
||||
//
|
||||
typedef struct _EAXLISTENERPROPERTIES
|
||||
{
|
||||
unsigned long ulEnvironment; // sets all listener properties
|
||||
float flEnvironmentSize; // environment size in meters
|
||||
float flEnvironmentDiffusion; // environment diffusion
|
||||
long lRoom; // room effect level (at mid frequencies)
|
||||
long lRoomHF; // relative room effect level at high frequencies
|
||||
long lRoomLF; // relative room effect level at low frequencies
|
||||
float flDecayTime; // reverberation decay time at mid frequencies
|
||||
float flDecayHFRatio; // high-frequency to mid-frequency decay time ratio
|
||||
float flDecayLFRatio; // low-frequency to mid-frequency decay time ratio
|
||||
long lReflections; // early reflections level relative to room effect
|
||||
float flReflectionsDelay; // initial reflection delay time
|
||||
EAXVECTOR vReflectionsPan; // early reflections panning vector
|
||||
long lReverb; // late reverberation level relative to room effect
|
||||
float flReverbDelay; // late reverberation delay time relative to initial reflection
|
||||
EAXVECTOR vReverbPan; // late reverberation panning vector
|
||||
float flEchoTime; // echo time
|
||||
float flEchoDepth; // echo depth
|
||||
float flModulationTime; // modulation time
|
||||
float flModulationDepth; // modulation depth
|
||||
float flAirAbsorptionHF; // change in level per meter at high frequencies
|
||||
float flHFReference; // reference high frequency
|
||||
float flLFReference; // reference low frequency
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
unsigned long ulFlags; // modifies the behavior of properties
|
||||
} EAXLISTENERPROPERTIES, *LPEAXLISTENERPROPERTIES;
|
||||
|
||||
// used by DSPROPERTY_EAXLISTENER_ENVIRONMENT
|
||||
enum
|
||||
{
|
||||
EAX_ENVIRONMENT_GENERIC,
|
||||
EAX_ENVIRONMENT_PADDEDCELL,
|
||||
EAX_ENVIRONMENT_ROOM,
|
||||
EAX_ENVIRONMENT_BATHROOM,
|
||||
EAX_ENVIRONMENT_LIVINGROOM,
|
||||
EAX_ENVIRONMENT_STONEROOM,
|
||||
EAX_ENVIRONMENT_AUDITORIUM,
|
||||
EAX_ENVIRONMENT_CONCERTHALL,
|
||||
EAX_ENVIRONMENT_CAVE,
|
||||
EAX_ENVIRONMENT_ARENA,
|
||||
EAX_ENVIRONMENT_HANGAR,
|
||||
EAX_ENVIRONMENT_CARPETEDHALLWAY,
|
||||
EAX_ENVIRONMENT_HALLWAY,
|
||||
EAX_ENVIRONMENT_STONECORRIDOR,
|
||||
EAX_ENVIRONMENT_ALLEY,
|
||||
EAX_ENVIRONMENT_FOREST,
|
||||
EAX_ENVIRONMENT_CITY,
|
||||
EAX_ENVIRONMENT_MOUNTAINS,
|
||||
EAX_ENVIRONMENT_QUARRY,
|
||||
EAX_ENVIRONMENT_PLAIN,
|
||||
EAX_ENVIRONMENT_PARKINGLOT,
|
||||
EAX_ENVIRONMENT_SEWERPIPE,
|
||||
EAX_ENVIRONMENT_UNDERWATER,
|
||||
EAX_ENVIRONMENT_DRUGGED,
|
||||
EAX_ENVIRONMENT_DIZZY,
|
||||
EAX_ENVIRONMENT_PSYCHOTIC,
|
||||
|
||||
EAX_ENVIRONMENT_UNDEFINED,
|
||||
|
||||
EAX_ENVIRONMENT_COUNT
|
||||
};
|
||||
|
||||
// Used by DSPROPERTY_EAXLISTENER_FLAGS
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// It is recommended to use the flag defines as follows:
|
||||
// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE;
|
||||
// instead of:
|
||||
// myFlags = 0x00000009;
|
||||
//
|
||||
// These flags determine what properties are affected by environment size.
|
||||
#define EAXLISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time
|
||||
#define EAXLISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level
|
||||
#define EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time
|
||||
#define EAXLISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level
|
||||
#define EAXLISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time
|
||||
#define EAXLISTENERFLAGS_ECHOTIMESCALE 0x00000040 // echo time
|
||||
#define EAXLISTENERFLAGS_MODULATIONTIMESCALE 0x00000080 // modulation time
|
||||
|
||||
// This flag limits high-frequency decay time according to air absorption.
|
||||
#define EAXLISTENERFLAGS_DECAYHFLIMIT 0x00000020
|
||||
|
||||
#define EAXLISTENERFLAGS_RESERVED 0xFFFFFF00 // reserved future use
|
||||
|
||||
// Property ranges and defaults:
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENT 0
|
||||
#define EAXLISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT-1)
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENTSIZE 1.0f
|
||||
#define EAXLISTENER_MAXENVIRONMENTSIZE 100.0f
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENTSIZE 7.5f
|
||||
|
||||
#define EAXLISTENER_MINENVIRONMENTDIFFUSION 0.0f
|
||||
#define EAXLISTENER_MAXENVIRONMENTDIFFUSION 1.0f
|
||||
#define EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f
|
||||
|
||||
#define EAXLISTENER_MINROOM (-10000)
|
||||
#define EAXLISTENER_MAXROOM 0
|
||||
#define EAXLISTENER_DEFAULTROOM (-1000)
|
||||
|
||||
#define EAXLISTENER_MINROOMHF (-10000)
|
||||
#define EAXLISTENER_MAXROOMHF 0
|
||||
#define EAXLISTENER_DEFAULTROOMHF (-100)
|
||||
|
||||
#define EAXLISTENER_MINROOMLF (-10000)
|
||||
#define EAXLISTENER_MAXROOMLF 0
|
||||
#define EAXLISTENER_DEFAULTROOMLF 0
|
||||
|
||||
#define EAXLISTENER_MINDECAYTIME 0.1f
|
||||
#define EAXLISTENER_MAXDECAYTIME 20.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYTIME 1.49f
|
||||
|
||||
#define EAXLISTENER_MINDECAYHFRATIO 0.1f
|
||||
#define EAXLISTENER_MAXDECAYHFRATIO 2.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYHFRATIO 0.83f
|
||||
|
||||
#define EAXLISTENER_MINDECAYLFRATIO 0.1f
|
||||
#define EAXLISTENER_MAXDECAYLFRATIO 2.0f
|
||||
#define EAXLISTENER_DEFAULTDECAYLFRATIO 1.00f
|
||||
|
||||
#define EAXLISTENER_MINREFLECTIONS (-10000)
|
||||
#define EAXLISTENER_MAXREFLECTIONS 1000
|
||||
#define EAXLISTENER_DEFAULTREFLECTIONS (-2602)
|
||||
|
||||
#define EAXLISTENER_MINREFLECTIONSDELAY 0.0f
|
||||
#define EAXLISTENER_MAXREFLECTIONSDELAY 0.3f
|
||||
#define EAXLISTENER_DEFAULTREFLECTIONSDELAY 0.007f
|
||||
|
||||
#define EAXLISTENER_MINREVERB (-10000)
|
||||
#define EAXLISTENER_MAXREVERB 2000
|
||||
#define EAXLISTENER_DEFAULTREVERB 200
|
||||
|
||||
#define EAXLISTENER_MINREVERBDELAY 0.0f
|
||||
#define EAXLISTENER_MAXREVERBDELAY 0.1f
|
||||
#define EAXLISTENER_DEFAULTREVERBDELAY 0.011f
|
||||
|
||||
#define EAXLISTENER_MINECHOTIME 0.075f
|
||||
#define EAXLISTENER_MAXECHOTIME 0.25f
|
||||
#define EAXLISTENER_DEFAULTECHOTIME 0.25f
|
||||
|
||||
#define EAXLISTENER_MINECHODEPTH 0.0f
|
||||
#define EAXLISTENER_MAXECHODEPTH 1.0f
|
||||
#define EAXLISTENER_DEFAULTECHODEPTH 0.0f
|
||||
|
||||
#define EAXLISTENER_MINMODULATIONTIME 0.04f
|
||||
#define EAXLISTENER_MAXMODULATIONTIME 4.0f
|
||||
#define EAXLISTENER_DEFAULTMODULATIONTIME 0.25f
|
||||
|
||||
#define EAXLISTENER_MINMODULATIONDEPTH 0.0f
|
||||
#define EAXLISTENER_MAXMODULATIONDEPTH 1.0f
|
||||
#define EAXLISTENER_DEFAULTMODULATIONDEPTH 0.0f
|
||||
|
||||
#define EAXLISTENER_MINAIRABSORPTIONHF (-100.0f)
|
||||
#define EAXLISTENER_MAXAIRABSORPTIONHF 0.0f
|
||||
#define EAXLISTENER_DEFAULTAIRABSORPTIONHF (-5.0f)
|
||||
|
||||
#define EAXLISTENER_MINHFREFERENCE 1000.0f
|
||||
#define EAXLISTENER_MAXHFREFERENCE 20000.0f
|
||||
#define EAXLISTENER_DEFAULTHFREFERENCE 5000.0f
|
||||
|
||||
#define EAXLISTENER_MINLFREFERENCE 20.0f
|
||||
#define EAXLISTENER_MAXLFREFERENCE 1000.0f
|
||||
#define EAXLISTENER_DEFAULTLFREFERENCE 250.0f
|
||||
|
||||
#define EAXLISTENER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAXLISTENER_MAXROOMROLLOFFFACTOR 10.0f
|
||||
#define EAXLISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXLISTENER_DEFAULTFLAGS (EAXLISTENERFLAGS_DECAYTIMESCALE | \
|
||||
EAXLISTENERFLAGS_REFLECTIONSSCALE | \
|
||||
EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE | \
|
||||
EAXLISTENERFLAGS_REVERBSCALE | \
|
||||
EAXLISTENERFLAGS_REVERBDELAYSCALE | \
|
||||
EAXLISTENERFLAGS_DECAYHFLIMIT)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EAX 3.0 buffer property set {A8FA6881-B476-11d3-BDB9-00C0F02DDF87}
|
||||
*/
|
||||
DEFINE_GUID(DSPROPSETID_EAX30_BufferProperties,
|
||||
0xa8fa6881,
|
||||
0xb476,
|
||||
0x11d3,
|
||||
0xbd, 0xb9, 0x0, 0xc0, 0xf0, 0x2d, 0xdf, 0x87);
|
||||
|
||||
// For compatibility with future EAX versions:
|
||||
#define DSPROPSETID_EAX_BufferProperties DSPROPSETID_EAX30_BufferProperties
|
||||
#define DSPROPSETID_EAX_SourceProperties DSPROPSETID_EAX30_BufferProperties
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXBUFFER_NONE,
|
||||
DSPROPERTY_EAXBUFFER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSIONPARAMETERS,
|
||||
DSPROPERTY_EAXBUFFER_DIRECT,
|
||||
DSPROPERTY_EAXBUFFER_DIRECTHF,
|
||||
DSPROPERTY_EAXBUFFER_ROOM,
|
||||
DSPROPERTY_EAXBUFFER_ROOMHF,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTION,
|
||||
DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSION,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OCCLUSIONDIRECTRATIO,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSION,
|
||||
DSPROPERTY_EAXBUFFER_EXCLUSIONLFRATIO,
|
||||
DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF,
|
||||
DSPROPERTY_EAXBUFFER_DOPPLERFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_ROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR,
|
||||
DSPROPERTY_EAXBUFFER_FLAGS
|
||||
} DSPROPERTY_EAX_BUFFERPROPERTY;
|
||||
|
||||
// OR these flags with property id
|
||||
#define DSPROPERTY_EAXBUFFER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXBUFFER_DEFERRED 0x80000000 // changes take effect later
|
||||
#define DSPROPERTY_EAXBUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXBUFFER_NONE | \
|
||||
DSPROPERTY_EAXBUFFER_IMMEDIATE)
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_ALLPARAMETERS
|
||||
// - all levels are hundredths of decibels
|
||||
// - all delays are in seconds
|
||||
//
|
||||
// NOTE: This structure may change in future EAX versions.
|
||||
// It is recommended to initialize fields by name:
|
||||
// myBuffer.lDirect = 0;
|
||||
// myBuffer.lDirectHF = -200;
|
||||
// ...
|
||||
// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ;
|
||||
// instead of:
|
||||
// myBuffer = { 0, -200, ... , 0x00000003 };
|
||||
//
|
||||
typedef struct _EAXBUFFERPROPERTIES
|
||||
{
|
||||
long lDirect; // direct path level (at low and mid frequencies)
|
||||
long lDirectHF; // relative direct path level at high frequencies
|
||||
long lRoom; // room effect level (at low and mid frequencies)
|
||||
long lRoomHF; // relative room effect level at high frequencies
|
||||
long lObstruction; // main obstruction control (attenuation at high frequencies)
|
||||
float flObstructionLFRatio; // obstruction low-frequency level re. main control
|
||||
long lOcclusion; // main occlusion control (attenuation at high frequencies)
|
||||
float flOcclusionLFRatio; // occlusion low-frequency level re. main control
|
||||
float flOcclusionRoomRatio; // relative occlusion control for room effect
|
||||
float flOcclusionDirectRatio; // relative occlusion control for direct path
|
||||
long lExclusion; // main exlusion control (attenuation at high frequencies)
|
||||
float flExclusionLFRatio; // exclusion low-frequency level re. main control
|
||||
long lOutsideVolumeHF; // outside sound cone level at high frequencies
|
||||
float flDopplerFactor; // like DS3D flDopplerFactor but per source
|
||||
float flRolloffFactor; // like DS3D flRolloffFactor but per source
|
||||
float flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
|
||||
float flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF
|
||||
unsigned long ulFlags; // modifies the behavior of properties
|
||||
} EAXBUFFERPROPERTIES, *LPEAXBUFFERPROPERTIES;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_OBSTRUCTION,
|
||||
typedef struct _EAXOBSTRUCTIONPROPERTIES
|
||||
{
|
||||
long lObstruction;
|
||||
float flObstructionLFRatio;
|
||||
} EAXOBSTRUCTIONPROPERTIES, *LPEAXOBSTRUCTIONPROPERTIES;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_OCCLUSION
|
||||
typedef struct _EAXOCCLUSIONPROPERTIES
|
||||
{
|
||||
long lOcclusion;
|
||||
float flOcclusionLFRatio;
|
||||
float flOcclusionRoomRatio;
|
||||
float flOcclusionDirectRatio;
|
||||
} EAXOCCLUSIONPROPERTIES, *LPEAXOCCLUSIONPROPERTIES;
|
||||
|
||||
// Use this structure for DSPROPERTY_EAXBUFFER_EXCLUSION
|
||||
typedef struct _EAXEXCLUSIONPROPERTIES
|
||||
{
|
||||
long lExclusion;
|
||||
float flExclusionLFRatio;
|
||||
} EAXEXCLUSIONPROPERTIES, *LPEAXEXCLUSIONPROPERTIES;
|
||||
|
||||
// Used by DSPROPERTY_EAXBUFFER_FLAGS
|
||||
// TRUE: value is computed automatically - property is an offset
|
||||
// FALSE: value is used directly
|
||||
//
|
||||
// Note: The number and order of flags may change in future EAX versions.
|
||||
// To insure future compatibility, use flag defines as follows:
|
||||
// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO;
|
||||
// instead of:
|
||||
// myFlags = 0x00000003;
|
||||
//
|
||||
#define EAXBUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF
|
||||
#define EAXBUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM
|
||||
#define EAXBUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF
|
||||
|
||||
#define EAXBUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use
|
||||
|
||||
// Property ranges and defaults:
|
||||
|
||||
#define EAXBUFFER_MINDIRECT (-10000)
|
||||
#define EAXBUFFER_MAXDIRECT 1000
|
||||
#define EAXBUFFER_DEFAULTDIRECT 0
|
||||
|
||||
#define EAXBUFFER_MINDIRECTHF (-10000)
|
||||
#define EAXBUFFER_MAXDIRECTHF 0
|
||||
#define EAXBUFFER_DEFAULTDIRECTHF 0
|
||||
|
||||
#define EAXBUFFER_MINROOM (-10000)
|
||||
#define EAXBUFFER_MAXROOM 1000
|
||||
#define EAXBUFFER_DEFAULTROOM 0
|
||||
|
||||
#define EAXBUFFER_MINROOMHF (-10000)
|
||||
#define EAXBUFFER_MAXROOMHF 0
|
||||
#define EAXBUFFER_DEFAULTROOMHF 0
|
||||
|
||||
#define EAXBUFFER_MINOBSTRUCTION (-10000)
|
||||
#define EAXBUFFER_MAXOBSTRUCTION 0
|
||||
#define EAXBUFFER_DEFAULTOBSTRUCTION 0
|
||||
|
||||
#define EAXBUFFER_MINOBSTRUCTIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOBSTRUCTIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSION (-10000)
|
||||
#define EAXBUFFER_MAXOCCLUSION 0
|
||||
#define EAXBUFFER_DEFAULTOCCLUSION 0
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONROOMRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONROOMRATIO 10.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO 1.5f
|
||||
|
||||
#define EAXBUFFER_MINOCCLUSIONDIRECTRATIO 0.0f
|
||||
#define EAXBUFFER_MAXOCCLUSIONDIRECTRATIO 10.0f
|
||||
#define EAXBUFFER_DEFAULTOCCLUSIONDIRECTRATIO 1.0f
|
||||
|
||||
#define EAXBUFFER_MINEXCLUSION (-10000)
|
||||
#define EAXBUFFER_MAXEXCLUSION 0
|
||||
#define EAXBUFFER_DEFAULTEXCLUSION 0
|
||||
|
||||
#define EAXBUFFER_MINEXCLUSIONLFRATIO 0.0f
|
||||
#define EAXBUFFER_MAXEXCLUSIONLFRATIO 1.0f
|
||||
#define EAXBUFFER_DEFAULTEXCLUSIONLFRATIO 1.0f
|
||||
|
||||
#define EAXBUFFER_MINOUTSIDEVOLUMEHF (-10000)
|
||||
#define EAXBUFFER_MAXOUTSIDEVOLUMEHF 0
|
||||
#define EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF 0
|
||||
|
||||
#define EAXBUFFER_MINDOPPLERFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXDOPPLERFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTDOPPLERFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINROLLOFFFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXROLLOFFFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINROOMROLLOFFFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXROOMROLLOFFFACTOR 10.f
|
||||
#define EAXBUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f
|
||||
|
||||
#define EAXBUFFER_MINAIRABSORPTIONFACTOR 0.0f
|
||||
#define EAXBUFFER_MAXAIRABSORPTIONFACTOR 10.0f
|
||||
#define EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f
|
||||
|
||||
#define EAXBUFFER_DEFAULTFLAGS (EAXBUFFERFLAGS_DIRECTHFAUTO | \
|
||||
EAXBUFFERFLAGS_ROOMAUTO | \
|
||||
EAXBUFFERFLAGS_ROOMHFAUTO )
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -2,507 +2,59 @@
|
||||
===========================================================================
|
||||
|
||||
IceTech GPL Source Code
|
||||
Copyright (C) 2026 Justin Marshall
|
||||
|
||||
This file is part of the IceTech GPL Source Code (?IceTech Source Code?).
|
||||
|
||||
IceTech Source Code is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
IceTech Source Code 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with IceTech Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com
|
||||
Copyright (C) 2026 Justin Marshall
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
// DirectX SDK
|
||||
//#include <DxErr.h>
|
||||
#define DXTRACE_ERR(str,hr) (hr)
|
||||
|
||||
#include <ks.h>
|
||||
#include <ksmedia.h>
|
||||
#include "../../sound/snd_local.h"
|
||||
#include "win_local.h"
|
||||
|
||||
#include "../../openal/idal.cpp"
|
||||
|
||||
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
|
||||
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
class idAudioBufferWIN32 : public idAudioBuffer {
|
||||
public:
|
||||
idAudioBufferWIN32( LPDIRECTSOUNDBUFFER apDSBuffer, dword dwDSBufferSize, idWaveFile* pWaveFile=NULL );
|
||||
~idAudioBufferWIN32();
|
||||
|
||||
int FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, bool bRepeatWavIfBufferLarger );
|
||||
|
||||
bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize );
|
||||
bool Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize );
|
||||
bool GetCurrentPosition( ulong *pdwCurrentWriteCursor );
|
||||
|
||||
int Play( dword dwPriority=0, dword dwFlags=0 );
|
||||
int Stop( void );
|
||||
int Reset( void );
|
||||
bool IsSoundPlaying( void );
|
||||
void SetVolume( float x);
|
||||
|
||||
idWaveFile* m_pWaveFile;
|
||||
private:
|
||||
LPDIRECTSOUNDBUFFER m_apDSBuffer;
|
||||
dword m_dwDSBufferSize;
|
||||
|
||||
int RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, bool* pbWasRestored );
|
||||
};
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32
|
||||
|
||||
OpenAL owns the Windows playback device. The sound system still asks for an
|
||||
idAudioHardware object so shared mixer timing and speaker-count code can run.
|
||||
===============
|
||||
*/
|
||||
class idAudioHardwareWIN32 : public idAudioHardware {
|
||||
|
||||
public:
|
||||
idAudioHardwareWIN32();
|
||||
~idAudioHardwareWIN32();
|
||||
idAudioHardwareWIN32() {
|
||||
numSpeakers = idSoundSystemLocal::s_numberOfSpeakers.GetInteger();
|
||||
if ( numSpeakers != 6 ) {
|
||||
numSpeakers = 2;
|
||||
}
|
||||
}
|
||||
|
||||
bool Initialize( );
|
||||
bool InitializeSpeakers( byte *buffer, int bufferSize, dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers );
|
||||
|
||||
void SetPrimaryBufferFormat( dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers );
|
||||
|
||||
int Create( idWaveFile* pWaveFile, idAudioBuffer** ppiab );
|
||||
int Create( idAudioBuffer** ppSound, const char* strWaveFileName, dword dwCreationFlags = 0 );
|
||||
int CreateFromMemory( idAudioBufferWIN32** ppSound, byte* pbData, ulong ulDataSize, waveformatextensible_t *pwfx, dword dwCreationFlags = 0 );
|
||||
|
||||
bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize );
|
||||
bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize );
|
||||
bool GetCurrentPosition( ulong *pdwCurrentWriteCursor );
|
||||
|
||||
int GetNumberOfSpeakers() { return numSpeakers; }
|
||||
int GetMixBufferSize() { return MIXBUFFER_SAMPLES * blockAlign; }
|
||||
|
||||
// WIN32 driver doesn't support write API
|
||||
bool Flush( void ) { return true; }
|
||||
void Write( bool ) { }
|
||||
short* GetMixBuffer( void ) { return NULL; }
|
||||
virtual bool Initialize() { return true; }
|
||||
virtual bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) {
|
||||
*pDSLockedBuffer = NULL;
|
||||
*dwDSLockedBufferSize = 0;
|
||||
return false;
|
||||
}
|
||||
virtual bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) { return false; }
|
||||
virtual bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ) {
|
||||
*pdwCurrentWriteCursor = 0;
|
||||
return false;
|
||||
}
|
||||
virtual bool Flush( void ) { return true; }
|
||||
virtual void Write( bool flushing ) {}
|
||||
virtual int GetNumberOfSpeakers( void ) { return numSpeakers; }
|
||||
virtual int GetMixBufferSize( void ) { return MIXBUFFER_SAMPLES * numSpeakers * sizeof( short ); }
|
||||
virtual short *GetMixBuffer( void ) { return NULL; }
|
||||
|
||||
private:
|
||||
LPDIRECTSOUND m_pDS;
|
||||
LPDIRECTSOUNDBUFFER pDSBPrimary;
|
||||
idAudioBufferWIN32 *speakers;
|
||||
|
||||
int numSpeakers;
|
||||
int bitsPerSample;
|
||||
int bufferSize; // allocate buffer handed over to DirectSound
|
||||
int blockAlign; // channels * bits per sample / 8: sound frame size
|
||||
int numSpeakers;
|
||||
};
|
||||
|
||||
idAudioHardware *idAudioHardware::Alloc() { return new idAudioHardwareWIN32; }
|
||||
idAudioHardware::~idAudioHardware() {}
|
||||
|
||||
/*
|
||||
================
|
||||
idAudioHardwareWIN32::idAudioHardware
|
||||
================
|
||||
*/
|
||||
idAudioHardwareWIN32::idAudioHardwareWIN32() {
|
||||
m_pDS = NULL;
|
||||
pDSBPrimary = NULL;
|
||||
speakers = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idAudioHardwareWIN32::~idAudioHardware
|
||||
================
|
||||
*/
|
||||
idAudioHardwareWIN32::~idAudioHardwareWIN32() {
|
||||
SAFE_DELETE( speakers );
|
||||
SAFE_RELEASE( pDSBPrimary );
|
||||
SAFE_RELEASE( m_pDS );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::Initialize
|
||||
===============
|
||||
*/
|
||||
bool idAudioHardwareWIN32::Initialize( void ) {
|
||||
int hr;
|
||||
|
||||
bufferSize = 0;
|
||||
numSpeakers = 0;
|
||||
blockAlign = 0;
|
||||
|
||||
SAFE_RELEASE( m_pDS );
|
||||
|
||||
// Create IDirectSound using the primary sound device
|
||||
if( FAILED( hr = DirectSoundCreate( NULL, &m_pDS, NULL ) )) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set primary buffer format
|
||||
SetPrimaryBufferFormat( PRIMARYFREQ, 16, idSoundSystemLocal::s_numberOfSpeakers.GetInteger() );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::InitializeSpeakers
|
||||
===============
|
||||
*/
|
||||
bool idAudioHardwareWIN32::InitializeSpeakers( byte *speakerData, int bufferSize, dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers ) {
|
||||
if ( dwSpeakers == 2 ) {
|
||||
WAVEFORMATEXTENSIBLE wfx;
|
||||
ZeroMemory( &wfx, sizeof(WAVEFORMATEXTENSIBLE) );
|
||||
wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.Format.nChannels = 2;
|
||||
wfx.Format.nSamplesPerSec = dwPrimaryFreq;
|
||||
wfx.Format.wBitsPerSample = dwPrimaryBitRate;
|
||||
wfx.Format.nBlockAlign = wfx.Format.wBitsPerSample / 8 * wfx.Format.nChannels;
|
||||
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
|
||||
wfx.Format.cbSize = sizeof(WAVEFORMATEX);
|
||||
|
||||
CreateFromMemory( &speakers, speakerData, bufferSize, (waveformatextensible_t *)&wfx );
|
||||
|
||||
common->Printf("sound: STEREO\n");
|
||||
} else {
|
||||
WAVEFORMATEXTENSIBLE waveFormatPCMEx;
|
||||
ZeroMemory( &waveFormatPCMEx, sizeof(WAVEFORMATEXTENSIBLE) );
|
||||
|
||||
waveFormatPCMEx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
waveFormatPCMEx.Format.nChannels = 6;
|
||||
waveFormatPCMEx.Format.nSamplesPerSec = dwPrimaryFreq;
|
||||
waveFormatPCMEx.Format.wBitsPerSample = dwPrimaryBitRate;
|
||||
waveFormatPCMEx.Format.nBlockAlign = waveFormatPCMEx.Format.wBitsPerSample / 8 * waveFormatPCMEx.Format.nChannels;
|
||||
waveFormatPCMEx.Format.nAvgBytesPerSec = waveFormatPCMEx.Format.nSamplesPerSec * waveFormatPCMEx.Format.nBlockAlign;
|
||||
waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
|
||||
// SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
|
||||
// SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
|
||||
// SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT
|
||||
waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; // Specify PCM
|
||||
waveFormatPCMEx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE);
|
||||
waveFormatPCMEx.Samples.wValidBitsPerSample = 16;
|
||||
|
||||
CreateFromMemory( &speakers, speakerData, bufferSize, (waveformatextensible_t *)&waveFormatPCMEx );
|
||||
|
||||
common->Printf("sound: MULTICHANNEL\n");
|
||||
}
|
||||
|
||||
if (!speakers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
speakers->Play(0,DSBPLAY_LOOPING);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::SetPrimaryBufferFormat
|
||||
Set primary buffer to a specified format
|
||||
For example, to set the primary buffer format to 22kHz stereo, 16-bit
|
||||
then: dwPrimaryChannels = 2
|
||||
dwPrimaryFreq = 22050,
|
||||
dwPrimaryBitRate = 16
|
||||
===============
|
||||
*/
|
||||
void idAudioHardwareWIN32::SetPrimaryBufferFormat( dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers ) {
|
||||
HRESULT hr;
|
||||
|
||||
if( m_pDS == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ulong cfgSpeakers;
|
||||
m_pDS->GetSpeakerConfig( &cfgSpeakers );
|
||||
|
||||
DSCAPS dscaps;
|
||||
dscaps.dwSize = sizeof(DSCAPS);
|
||||
m_pDS->GetCaps(&dscaps);
|
||||
|
||||
if (dscaps.dwFlags & DSCAPS_EMULDRIVER) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the primary buffer
|
||||
DSBUFFERDESC dsbd;
|
||||
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
dsbd.dwBufferBytes = 0;
|
||||
dsbd.lpwfxFormat = NULL;
|
||||
|
||||
// Obtain write-primary cooperative level.
|
||||
if( FAILED( hr = m_pDS->SetCooperativeLevel(win32.hWnd, DSSCL_PRIORITY ) ) ) {
|
||||
DXTRACE_ERR( TEXT("SetPrimaryBufferFormat"), hr );
|
||||
return;
|
||||
}
|
||||
|
||||
if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( dwSpeakers == 6 && (cfgSpeakers == DSSPEAKER_5POINT1 || cfgSpeakers == DSSPEAKER_SURROUND) ) {
|
||||
WAVEFORMATEXTENSIBLE waveFormatPCMEx;
|
||||
ZeroMemory( &waveFormatPCMEx, sizeof(WAVEFORMATEXTENSIBLE) );
|
||||
|
||||
waveFormatPCMEx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
waveFormatPCMEx.Format.nChannels = 6;
|
||||
waveFormatPCMEx.Format.nSamplesPerSec = dwPrimaryFreq;
|
||||
waveFormatPCMEx.Format.wBitsPerSample = (WORD) dwPrimaryBitRate;
|
||||
waveFormatPCMEx.Format.nBlockAlign = waveFormatPCMEx.Format.wBitsPerSample / 8 * waveFormatPCMEx.Format.nChannels;
|
||||
waveFormatPCMEx.Format.nAvgBytesPerSec = waveFormatPCMEx.Format.nSamplesPerSec * waveFormatPCMEx.Format.nBlockAlign;
|
||||
waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
|
||||
// SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
|
||||
// SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
|
||||
// SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT
|
||||
waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; // Specify PCM
|
||||
waveFormatPCMEx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE);
|
||||
waveFormatPCMEx.Samples.wValidBitsPerSample = 16;
|
||||
|
||||
if( FAILED( hr = pDSBPrimary->SetFormat((WAVEFORMATEX*)&waveFormatPCMEx) ) ) {
|
||||
DXTRACE_ERR( TEXT("SetPrimaryBufferFormat"), hr );
|
||||
return;
|
||||
}
|
||||
numSpeakers = 6; // force it to think 5.1
|
||||
blockAlign = waveFormatPCMEx.Format.nBlockAlign;
|
||||
} else {
|
||||
if (dwSpeakers == 6) {
|
||||
common->Printf("sound: hardware reported unable to use multisound, defaulted to stereo\n");
|
||||
}
|
||||
WAVEFORMATEX wfx;
|
||||
ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
wfx.nSamplesPerSec = dwPrimaryFreq;
|
||||
wfx.wBitsPerSample = (WORD) dwPrimaryBitRate;
|
||||
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
wfx.cbSize = sizeof(WAVEFORMATEX);
|
||||
|
||||
if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) ) {
|
||||
return;
|
||||
}
|
||||
numSpeakers = 2; // force it to think stereo
|
||||
blockAlign = wfx.nBlockAlign;
|
||||
}
|
||||
|
||||
byte *speakerData;
|
||||
bufferSize = MIXBUFFER_SAMPLES * sizeof(word) * numSpeakers * ROOM_SLICES_IN_BUFFER;
|
||||
speakerData = (byte *)Mem_Alloc( bufferSize );
|
||||
memset( speakerData, 0, bufferSize );
|
||||
|
||||
InitializeSpeakers( speakerData, bufferSize, dwPrimaryFreq, dwPrimaryBitRate, numSpeakers );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::Create
|
||||
===============
|
||||
*/
|
||||
int idAudioHardwareWIN32::Create( idAudioBuffer** ppSound,
|
||||
const char* strWaveFileName,
|
||||
dword dwCreationFlags ) {
|
||||
int hr;
|
||||
LPDIRECTSOUNDBUFFER apDSBuffer = NULL;
|
||||
dword dwDSBufferSize = NULL;
|
||||
idWaveFile* pWaveFile = NULL;
|
||||
|
||||
if( m_pDS == NULL )
|
||||
return -1;
|
||||
if( strWaveFileName == NULL || ppSound == NULL )
|
||||
return -1;
|
||||
|
||||
pWaveFile = new idWaveFile();
|
||||
|
||||
pWaveFile->Open( strWaveFileName, NULL );
|
||||
|
||||
if( pWaveFile->GetOutputSize() == 0 ) {
|
||||
// Wave is blank, so don't create it.
|
||||
hr = E_FAIL;
|
||||
goto LFail;
|
||||
}
|
||||
|
||||
// Make the DirectSound buffer the same size as the wav file
|
||||
dwDSBufferSize = pWaveFile->GetOutputSize();
|
||||
|
||||
// Create the direct sound buffer, and only request the flags needed
|
||||
// since each requires some overhead and limits if the buffer can
|
||||
// be hardware accelerated
|
||||
DSBUFFERDESC dsbd;
|
||||
memset( &dsbd, 0, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = dwCreationFlags;
|
||||
dsbd.dwBufferBytes = dwDSBufferSize;
|
||||
dsbd.guid3DAlgorithm = GUID_NULL;
|
||||
dsbd.lpwfxFormat = (WAVEFORMATEX*)&pWaveFile->mpwfx;
|
||||
|
||||
// DirectSound is only guarenteed to play PCM data. Other
|
||||
// formats may or may not work depending the sound card driver.
|
||||
if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer, NULL ) ) )
|
||||
return -1;
|
||||
|
||||
// Create the sound
|
||||
*ppSound = new idAudioBufferWIN32( apDSBuffer, dwDSBufferSize, pWaveFile );
|
||||
|
||||
pWaveFile->Close();
|
||||
|
||||
return 0;
|
||||
|
||||
LFail:
|
||||
// Cleanup
|
||||
SAFE_DELETE( pWaveFile );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::Create
|
||||
===============
|
||||
*/
|
||||
int idAudioHardwareWIN32::Create( idWaveFile* pWaveFile, idAudioBuffer** ppiab ) {
|
||||
int hr;
|
||||
LPDIRECTSOUNDBUFFER apDSBuffer = NULL;
|
||||
dword dwDSBufferSize = NULL;
|
||||
|
||||
if( m_pDS == NULL )
|
||||
return -1;
|
||||
|
||||
if( pWaveFile == NULL )
|
||||
return -1;
|
||||
|
||||
*ppiab = NULL;
|
||||
|
||||
if( pWaveFile->GetOutputSize() == 0 ) {
|
||||
// Wave is blank, so don't create it.
|
||||
hr = E_FAIL;
|
||||
goto LFail;
|
||||
}
|
||||
|
||||
// Make the DirectSound buffer the same size as the wav file
|
||||
dwDSBufferSize = pWaveFile->GetOutputSize();
|
||||
|
||||
// Create the direct sound buffer, and only request the flags needed
|
||||
// since each requires some overhead and limits if the buffer can
|
||||
// be hardware accelerated
|
||||
DSBUFFERDESC dsbd;
|
||||
memset( &dsbd, 0, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = 0;
|
||||
dsbd.dwBufferBytes = dwDSBufferSize;
|
||||
dsbd.guid3DAlgorithm = GUID_NULL;
|
||||
dsbd.lpwfxFormat = (WAVEFORMATEX*)&pWaveFile->mpwfx;
|
||||
|
||||
// DirectSound is only guarenteed to play PCM data. Other
|
||||
// formats may or may not work depending the sound card driver.
|
||||
if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer, NULL ) ) )
|
||||
return -1;
|
||||
|
||||
// Create the sound
|
||||
*ppiab = new idAudioBufferWIN32( apDSBuffer, dwDSBufferSize, pWaveFile );
|
||||
|
||||
return 0;
|
||||
|
||||
LFail:
|
||||
// Cleanup
|
||||
SAFE_DELETE( pWaveFile );
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: idAudioHardwareWIN32::CreateFromMemory()
|
||||
// Desc:
|
||||
//-----------------------------------------------------------------------------
|
||||
int idAudioHardwareWIN32::CreateFromMemory( idAudioBufferWIN32** ppSound,
|
||||
byte* pbData,
|
||||
ulong ulDataSize,
|
||||
waveformatextensible_t* pwfx,
|
||||
dword dwCreationFlags ) {
|
||||
int hr;
|
||||
LPDIRECTSOUNDBUFFER apDSBuffer = NULL;
|
||||
dword dwDSBufferSize = NULL;
|
||||
idWaveFile* pWaveFile = NULL;
|
||||
|
||||
if( m_pDS == NULL )
|
||||
return -1;
|
||||
if( pbData == NULL || ppSound == NULL )
|
||||
return -1;
|
||||
|
||||
pWaveFile = new idWaveFile();
|
||||
|
||||
pWaveFile->OpenFromMemory( (short *)pbData, ulDataSize, (waveformatextensible_t *)pwfx);
|
||||
|
||||
|
||||
// Make the DirectSound buffer the same size as the wav file
|
||||
dwDSBufferSize = ulDataSize;
|
||||
|
||||
// Create the direct sound buffer, and only request the flags needed
|
||||
// since each requires some overhead and limits if the buffer can
|
||||
// be hardware accelerated
|
||||
DSBUFFERDESC dsbd;
|
||||
memset( &dsbd, 0, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = dwCreationFlags | DSBCAPS_GETCURRENTPOSITION2;
|
||||
dsbd.dwBufferBytes = dwDSBufferSize;
|
||||
dsbd.guid3DAlgorithm = GUID_NULL;
|
||||
dsbd.lpwfxFormat = (WAVEFORMATEX *)pwfx;
|
||||
|
||||
if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer, NULL ) ) )
|
||||
return -1;
|
||||
|
||||
// Create the sound
|
||||
*ppSound = new idAudioBufferWIN32( apDSBuffer, dwDSBufferSize, pWaveFile );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::Lock
|
||||
===============
|
||||
*/
|
||||
bool idAudioHardwareWIN32::Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) {
|
||||
if (speakers) {
|
||||
return speakers->Lock( pDSLockedBuffer, dwDSLockedBufferSize );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::Unlock
|
||||
===============
|
||||
*/
|
||||
bool idAudioHardwareWIN32::Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize ) {
|
||||
if (speakers) {
|
||||
return speakers->Unlock( pDSLockedBuffer, dwDSLockedBufferSize );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioHardwareWIN32::GetCurrentPosition
|
||||
===============
|
||||
*/
|
||||
bool idAudioHardwareWIN32::GetCurrentPosition( ulong *pdwCurrentWriteCursor ) {
|
||||
if (speakers) {
|
||||
return speakers->GetCurrentPosition( pdwCurrentWriteCursor );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static HMODULE hOpenAL = NULL;
|
||||
|
||||
/*
|
||||
@@ -511,14 +63,13 @@ Sys_LoadOpenAL
|
||||
===============
|
||||
*/
|
||||
bool Sys_LoadOpenAL( void ) {
|
||||
#if ID_OPENAL
|
||||
const char *sym;
|
||||
|
||||
if ( hOpenAL ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
hOpenAL = LoadLibrary( idSoundSystemLocal::s_libOpenAL.GetString() );
|
||||
hOpenAL = LoadLibraryA( idSoundSystemLocal::s_libOpenAL.GetString() );
|
||||
if ( !hOpenAL ) {
|
||||
common->Warning( "LoadLibrary %s failed.", idSoundSystemLocal::s_libOpenAL.GetString() );
|
||||
return false;
|
||||
@@ -530,9 +81,6 @@ bool Sys_LoadOpenAL( void ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -546,303 +94,3 @@ void Sys_FreeOpenAL( void ) {
|
||||
hOpenAL = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::idAudioBuffer
|
||||
===============
|
||||
*/
|
||||
idAudioBufferWIN32::idAudioBufferWIN32( LPDIRECTSOUNDBUFFER apDSBuffer, dword dwDSBufferSize, idWaveFile* pWaveFile ) {
|
||||
|
||||
m_apDSBuffer = apDSBuffer;
|
||||
|
||||
m_dwDSBufferSize = dwDSBufferSize;
|
||||
m_pWaveFile = pWaveFile;
|
||||
|
||||
if (pWaveFile) {
|
||||
FillBufferWithSound( m_apDSBuffer, false );
|
||||
|
||||
m_apDSBuffer->SetCurrentPosition(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::~idAudioBuffer
|
||||
===============
|
||||
*/
|
||||
idAudioBufferWIN32::~idAudioBufferWIN32() {
|
||||
SAFE_DELETE(m_pWaveFile);
|
||||
SAFE_RELEASE( m_apDSBuffer );
|
||||
m_pWaveFile = NULL;
|
||||
m_apDSBuffer = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::FillBufferWithSound
|
||||
===============
|
||||
*/
|
||||
int idAudioBufferWIN32::FillBufferWithSound( LPDIRECTSOUNDBUFFER pDSB, bool bRepeatWavIfBufferLarger ) {
|
||||
int hr;
|
||||
void* pDSLockedBuffer = NULL; // Pointer to locked buffer memory
|
||||
ulong dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer
|
||||
int dwWavDataRead = 0; // Amount of data read from the wav file
|
||||
|
||||
if( pDSB == NULL )
|
||||
return -1;
|
||||
|
||||
// we may not even have a wavefile
|
||||
if (m_pWaveFile==NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make sure we have focus, and we didn't just switch in from
|
||||
// an app which had a DirectSound device
|
||||
if( FAILED( hr = RestoreBuffer( pDSB, NULL ) ) ) {
|
||||
DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Lock the buffer down
|
||||
if( FAILED( hr = pDSB->Lock( 0, m_dwDSBufferSize, &pDSLockedBuffer, &dwDSLockedBufferSize, NULL, NULL, 0L ) ) ) {
|
||||
DXTRACE_ERR( TEXT("Lock"), hr );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Reset the wave file to the beginning
|
||||
m_pWaveFile->ResetFile();
|
||||
|
||||
if( FAILED( hr = m_pWaveFile->Read( (byte*) pDSLockedBuffer, dwDSLockedBufferSize, &dwWavDataRead ) ) ) {
|
||||
return DXTRACE_ERR( TEXT("Read"), hr );
|
||||
}
|
||||
|
||||
if( dwWavDataRead == 0 ) {
|
||||
// Wav is blank, so just fill with silence
|
||||
memset( pDSLockedBuffer, (byte)(m_pWaveFile->mpwfx.Format.wBitsPerSample == 8 ? 128 : 0 ), dwDSLockedBufferSize );
|
||||
} else if( dwWavDataRead < (int)dwDSLockedBufferSize ) {
|
||||
// If the wav file was smaller than the DirectSound buffer,
|
||||
// we need to fill the remainder of the buffer with data
|
||||
if( bRepeatWavIfBufferLarger ) {
|
||||
// Reset the file and fill the buffer with wav data
|
||||
int dwReadSoFar = dwWavDataRead; // From previous call above.
|
||||
while( dwReadSoFar < (int)dwDSLockedBufferSize ) {
|
||||
// This will keep reading in until the buffer is full
|
||||
// for very short files
|
||||
if( FAILED( hr = m_pWaveFile->ResetFile() ) ) {
|
||||
return DXTRACE_ERR( TEXT("ResetFile"), hr );
|
||||
}
|
||||
|
||||
hr = m_pWaveFile->Read( (byte*)pDSLockedBuffer + dwReadSoFar, dwDSLockedBufferSize - dwReadSoFar, &dwWavDataRead );
|
||||
if( FAILED(hr) ) {
|
||||
return DXTRACE_ERR( TEXT("Read"), hr );
|
||||
}
|
||||
|
||||
dwReadSoFar += dwWavDataRead;
|
||||
}
|
||||
} else {
|
||||
// Don't repeat the wav file, just fill in silence
|
||||
memset( (byte*) pDSLockedBuffer + dwWavDataRead, (byte)(m_pWaveFile->mpwfx.Format.wBitsPerSample == 8 ? 128 : 0 ), dwDSLockedBufferSize - dwWavDataRead);
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock the buffer, we don't need it anymore.
|
||||
pDSB->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::RestoreBuffer
|
||||
Desc: Restores the lost buffer. *pbWasRestored returns true if the buffer was
|
||||
restored. It can also NULL if the information is not needed.
|
||||
===============
|
||||
*/
|
||||
int idAudioBufferWIN32::RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB, bool* pbWasRestored ) {
|
||||
int hr;
|
||||
|
||||
if( pDSB == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
if( pbWasRestored ) {
|
||||
*pbWasRestored = false;
|
||||
}
|
||||
|
||||
ulong dwStatus;
|
||||
if( FAILED( hr = pDSB->GetStatus( &dwStatus ) ) ) {
|
||||
return DXTRACE_ERR( TEXT("GetStatus"), hr );
|
||||
}
|
||||
|
||||
if( dwStatus & DSBSTATUS_BUFFERLOST ) {
|
||||
// Since the app could have just been activated, then
|
||||
// DirectSound may not be giving us control yet, so
|
||||
// the restoring the buffer may fail.
|
||||
// If it does, sleep until DirectSound gives us control.
|
||||
do {
|
||||
hr = pDSB->Restore();
|
||||
if( hr == DSERR_BUFFERLOST ) {
|
||||
Sleep( 10 );
|
||||
}
|
||||
hr = pDSB->Restore();
|
||||
} while( hr );
|
||||
|
||||
if( pbWasRestored != NULL ) {
|
||||
*pbWasRestored = true;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
} else {
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::Play
|
||||
Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING
|
||||
in the dwFlags to loop the sound
|
||||
===============
|
||||
*/
|
||||
int idAudioBufferWIN32::Play( dword dwPriority, dword dwFlags ) {
|
||||
int hr;
|
||||
bool bRestored;
|
||||
|
||||
if( m_apDSBuffer == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Restore the buffer if it was lost
|
||||
if( FAILED( hr = RestoreBuffer( m_apDSBuffer, &bRestored ) ) ) {
|
||||
common->Error( TEXT("RestoreBuffer"), hr );
|
||||
}
|
||||
|
||||
if( bRestored ) {
|
||||
// The buffer was restored, so we need to fill it with new data
|
||||
if( FAILED( hr = FillBufferWithSound( m_apDSBuffer, false ) ) ) {
|
||||
common->Error( TEXT("FillBufferWithSound"), hr );
|
||||
}
|
||||
|
||||
// Make DirectSound do pre-processing on sound effects
|
||||
Reset();
|
||||
}
|
||||
|
||||
m_apDSBuffer->Play( 0, dwPriority, dwFlags );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::Stop
|
||||
Desc: Stops the sound from playing
|
||||
===============
|
||||
*/
|
||||
int idAudioBufferWIN32::Stop() {
|
||||
if( this == NULL || m_apDSBuffer == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_apDSBuffer->Stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::Reset
|
||||
Desc: Reset all of the sound buffers
|
||||
===============
|
||||
*/
|
||||
int idAudioBufferWIN32::Reset() {
|
||||
if( m_apDSBuffer == NULL ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_apDSBuffer->SetCurrentPosition( 0 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::IsSoundPlaying
|
||||
Desc: Checks to see if a buffer is playing and returns true if it
|
||||
===============
|
||||
*/
|
||||
bool idAudioBufferWIN32::IsSoundPlaying( ) {
|
||||
if( m_apDSBuffer == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( m_apDSBuffer ) {
|
||||
ulong dwStatus = 0;
|
||||
m_apDSBuffer->GetStatus( &dwStatus );
|
||||
if ( dwStatus & DSBSTATUS_PLAYING ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::Lock
|
||||
===============
|
||||
*/
|
||||
bool idAudioBufferWIN32::Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) {
|
||||
int hr;
|
||||
// Restore the buffer if it was lost
|
||||
bool bRestored;
|
||||
if( FAILED( hr = RestoreBuffer( m_apDSBuffer, &bRestored ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lock the DirectSound buffer
|
||||
if( FAILED( hr = m_apDSBuffer->Lock( 0, m_dwDSBufferSize, pDSLockedBuffer, dwDSLockedBufferSize, NULL, NULL, 0 ) ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::Unlock
|
||||
===============
|
||||
*/
|
||||
bool idAudioBufferWIN32::Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize ) {
|
||||
// Unlock the DirectSound buffer
|
||||
m_apDSBuffer->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0 );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::GetCurrentPosition
|
||||
===============
|
||||
*/
|
||||
bool idAudioBufferWIN32::GetCurrentPosition( ulong *pdwCurrentWriteCursor ) {
|
||||
int hr;
|
||||
|
||||
// Make sure we have focus, and we didn't just switch in from
|
||||
// an app which had a DirectSound device
|
||||
if( FAILED( hr = RestoreBuffer( m_apDSBuffer, NULL ) ) ) {
|
||||
DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( FAILED( hr = m_apDSBuffer->GetCurrentPosition( NULL, pdwCurrentWriteCursor ) ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idAudioBufferWIN32::SetVolume
|
||||
===============
|
||||
*/
|
||||
void idAudioBufferWIN32::SetVolume( float x) {
|
||||
if (m_apDSBuffer) {
|
||||
m_apDSBuffer->SetVolume(x);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user