mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 11:00:38 +02:00
OpenAL is enabled, EAX fixes and removed DirectSound completely.
This commit is contained in:
@@ -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++;
|
||||
|
||||
Reference in New Issue
Block a user