Don't restart OAL device when switching EAX

This commit is contained in:
Sergeanur 2021-06-24 14:15:18 +03:00
parent 27df328ec2
commit 3ebc475494
3 changed files with 174 additions and 167 deletions

View file

@ -24,12 +24,6 @@
#include "aldlist.h"
#ifndef _WIN32
#define _stricmp strcasecmp
#define _strnicmp strncasecmp
#define _strdup strdup
#endif
#ifdef AUDIO_OAL
/*
* Init call
@ -47,8 +41,8 @@ ALDeviceList::ALDeviceList()
defaultDeviceIndex = 0;
if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) {
devices = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
defaultDeviceName = (char *)alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
devices = (char *)alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
defaultDeviceName = (char *)alcGetString(NULL, ALC_DEFAULT_ALL_DEVICES_SPECIFIER);
index = 0;
// go through device list (each device terminated with a single NULL, list terminated with double NULL)
@ -62,17 +56,11 @@ ALDeviceList::ALDeviceList()
if (context) {
alcMakeContextCurrent(context);
// if new actual device name isn't already in the list, then add it...
actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER);
bool bNewName = true;
for (unsigned int i = 0; i < GetNumDevices(); i++) {
if (strcmp(GetDeviceName(i), actualDeviceName) == 0) {
bNewName = false;
}
}
if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) {
ALDEVICEINFO ALDeviceInfo;
actualDeviceName = alcGetString(device, ALC_ALL_DEVICES_SPECIFIER);
if ((actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) {
ALDEVICEINFO &ALDeviceInfo = aDeviceInfo[nNumOfDevices++];
ALDeviceInfo.bSelected = true;
ALDeviceInfo.strDeviceName = _strdup(actualDeviceName);
ALDeviceInfo.SetName(actualDeviceName);
alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion);
alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion);
@ -105,8 +93,6 @@ ALDeviceList::ALDeviceList()
// Get Source Count
ALDeviceInfo.uiSourceCount = GetMaxNumSources();
aDeviceInfo[nNumOfDevices++] = ALDeviceInfo;
}
alcMakeContextCurrent(NULL);
alcDestroyContext(context);

View file

@ -21,7 +21,7 @@ enum
};
struct ALDEVICEINFO {
const char *strDeviceName;
char *strDeviceName;
int iMajorVersion;
int iMinorVersion;
unsigned int uiSourceCount;
@ -33,6 +33,19 @@ struct ALDEVICEINFO {
strDeviceName = NULL;
Extensions = 0;
}
~ALDEVICEINFO()
{
delete[] strDeviceName;
strDeviceName = NULL;
}
void SetName(const char *name)
{
if(strDeviceName) delete[] strDeviceName;
strDeviceName = new char[strlen(name) + 1];
strcpy(strDeviceName, name);
}
};
typedef ALDEVICEINFO *LPALDEVICEINFO;

View file

@ -45,7 +45,6 @@
#endif
//TODO: fix eax3 reverb
//TODO: max channels
cSampleManager SampleManager;
bool8 _bSampmanInitialised = FALSE;
@ -61,15 +60,17 @@ ALCdevice *ALDevice = NULL;
ALCcontext *ALContext = NULL;
unsigned int _maxSamples;
float _fPrevEaxRatioDestination;
bool _effectsSupported = false;
bool _usingEFX;
float _fEffectsLevel;
ALuint ALEffect = AL_EFFECT_NULL;
ALuint ALEffectSlot = AL_EFFECTSLOT_NULL;
struct
{
char id[256];
const char *id;
char name[256];
int sources;
bool bSupportsFx;
}providers[MAXPROVIDERS];
int defaultProvider;
@ -135,7 +136,7 @@ EAXLISTENERPROPERTIES EAX3Params;
bool IsFXSupported()
{
return usingEAX || usingEAX3 || _usingEFX;
return _effectsSupported; // usingEAX || usingEAX3 || _usingEFX;
}
void EAX_SetAll(const EAXLISTENERPROPERTIES *allparameters)
@ -151,20 +152,21 @@ add_providers()
{
SampleManager.SetNum3DProvidersAvailable(0);
ALDeviceList *pDeviceList = NULL;
pDeviceList = new ALDeviceList();
static ALDeviceList DeviceList;
ALDeviceList *pDeviceList = &DeviceList;
if ((pDeviceList) && (pDeviceList->GetNumDevices()))
{
const int devNumber = Min(pDeviceList->GetNumDevices(), MAXPROVIDERS);
int n = 0;
for (int i = 0; i < devNumber; i++)
//for (int i = 0; i < devNumber; i++)
int i = pDeviceList->GetDefaultDevice();
{
if ( n < MAXPROVIDERS )
{
strcpy(providers[n].id, pDeviceList->GetDeviceName(i));
strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name));
providers[n].id = pDeviceList->GetDeviceName(i);
strcpy(providers[n].name, "OPENAL SOFT");
providers[n].sources = pDeviceList->GetMaxNumSources(i);
SampleManager.Set3DProviderName(n, providers[n].name);
n++;
@ -176,22 +178,23 @@ add_providers()
|| pDeviceList->IsExtensionSupported(i, ADEXT_EAX4)
|| pDeviceList->IsExtensionSupported(i, ADEXT_EAX5) )
{
providers[n - 1].bSupportsFx = true;
if ( n < MAXPROVIDERS )
{
strcpy(providers[n].id, pDeviceList->GetDeviceName(i));
strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name));
strcat(providers[n].name, " EAX");
providers[n].id = pDeviceList->GetDeviceName(i);
strcpy(providers[n].name, "OPENAL SOFT EAX");
providers[n].sources = pDeviceList->GetMaxNumSources(i);
providers[n].bSupportsFx = true;
SampleManager.Set3DProviderName(n, providers[n].name);
n++;
}
if ( n < MAXPROVIDERS )
{
strcpy(providers[n].id, pDeviceList->GetDeviceName(i));
strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name));
strcat(providers[n].name, " EAX3");
providers[n].id = pDeviceList->GetDeviceName(i);
strcpy(providers[n].name, "OPENAL SOFT EAX3");
providers[n].sources = pDeviceList->GetMaxNumSources(i);
providers[n].bSupportsFx = true;
SampleManager.Set3DProviderName(n, providers[n].name);
n++;
}
@ -202,66 +205,30 @@ add_providers()
for(int j=n;j<MAXPROVIDERS;j++)
SampleManager.Set3DProviderName(j, NULL);
defaultProvider = pDeviceList->GetDefaultDevice();
if ( defaultProvider > MAXPROVIDERS )
// devices are gone now
//defaultProvider = pDeviceList->GetDefaultDevice();
//if ( defaultProvider > MAXPROVIDERS )
defaultProvider = 0;
}
delete pDeviceList;
}
static void
release_existing()
{
for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
aChannel[i].Term();
if ( IsFXSupported() )
{
if ( alIsEffect(ALEffect) )
{
alEffecti(ALEffect, AL_EFFECT_TYPE, AL_EFFECT_NULL);
alDeleteEffects(1, &ALEffect);
ALEffect = AL_EFFECT_NULL;
}
if (alIsAuxiliaryEffectSlot(ALEffectSlot))
{
alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL);
alDeleteAuxiliaryEffectSlots(1, &ALEffectSlot);
ALEffectSlot = AL_EFFECTSLOT_NULL;
}
}
for ( int32 i = 0; i < MAX_STREAMS; i++ )
{
CStream *stream = aStream[i];
if (stream)
stream->ProviderTerm();
alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
}
alDeleteSources(MAX_STREAMS*2, ALStreamSources[0]);
CChannel::DestroyChannels();
if ( ALContext )
{
alcMakeContextCurrent(NULL);
alcSuspendContext(ALContext);
alcDestroyContext(ALContext);
}
if ( ALDevice )
alcCloseDevice(ALDevice);
ALDevice = NULL;
ALContext = NULL;
_fPrevEaxRatioDestination = 0.0f;
_usingEFX = false;
_fEffectsLevel = 0.0f;
DEV("release_existing()\n");
}
@ -279,62 +246,6 @@ set_new_provider(int index)
{
DEV("set_new_provider()\n");
//TODO:
_maxSamples = MAXCHANNELS;
ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,
ALC_MONO_SOURCES, MAX_DIGITAL_MIXER_CHANNELS - MAX2DCHANNELS,
ALC_STEREO_SOURCES, MAX2DCHANNELS,
0,
};
ALDevice = alcOpenDevice(providers[index].id);
ASSERT(ALDevice != NULL);
ALContext = alcCreateContext(ALDevice, attr);
ASSERT(ALContext != NULL);
alcMakeContextCurrent(ALContext);
const char* ext=(const char*)alGetString(AL_EXTENSIONS);
ASSERT(strstr(ext,"AL_SOFT_loop_points")!=NULL);
if ( strstr(ext,"AL_SOFT_loop_points")==NULL )
{
curprovider=-1;
release_existing();
return FALSE;
}
alListenerf (AL_GAIN, 1.0f);
alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f);
ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };
alListenerfv(AL_ORIENTATION, orientation);
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
{
alGenAuxiliaryEffectSlots(1, &ALEffectSlot);
alGenEffects(1, &ALEffect);
}
alGenSources(MAX_STREAMS*2, ALStreamSources[0]);
for ( int32 i = 0; i < MAX_STREAMS; i++ )
{
alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
alSourcei(ALStreamSources[i][0], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(ALStreamSources[i][0], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSourcef(ALStreamSources[i][0], AL_GAIN, 1.0f);
alSourcei(ALStreamSources[i][1], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(ALStreamSources[i][1], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSourcef(ALStreamSources[i][1], AL_GAIN, 1.0f);
CStream *stream = aStream[i];
if (stream)
stream->ProviderInit();
}
usingEAX = 0;
usingEAX3 = 0;
_usingEFX = false;
@ -342,16 +253,16 @@ set_new_provider(int index)
if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX3")], " EAX3")
&& alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
{
EAX_SetAll(&FinishEAX3);
usingEAX = 1;
usingEAX3 = 1;
alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
EAX_SetAll(&FinishEAX3);
DEV("EAX3\n");
}
else if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
{
EAX_SetAll(&EAX30_ORIGINAL_PRESETS[EAX_ENVIRONMENT_CAVE]);
if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX")], " EAX"))
{
@ -363,23 +274,15 @@ set_new_provider(int index)
_usingEFX = true;
DEV("EFX\n");
}
alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
EAX_SetAll(&EAX30_ORIGINAL_PRESETS[EAX_ENVIRONMENT_CAVE]);
}
//SampleManager.SetSpeakerConfig(speaker_type);
CChannel::InitChannels();
for ( int32 i = 0; i < MAXCHANNELS; i++ )
aChannel[i].Init(i);
for ( int32 i = 0; i < MAX2DCHANNELS; i++ )
aChannel[CHANNEL2D+i].Init(CHANNEL2D+i, true);
if ( IsFXSupported() )
{
/**/
alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
/**/
for ( int32 i = 0; i < MAXCHANNELS; i++ )
aChannel[i].SetReverbMix(ALEffectSlot, 0.0f);
}
@ -969,21 +872,12 @@ cSampleManager::IsMP3RadioChannelAvailable(void)
void cSampleManager::ReleaseDigitalHandle(void)
{
if ( ALDevice )
{
prevprovider = curprovider;
release_existing();
curprovider = -1;
}
// TODO? alcSuspendContext
}
void cSampleManager::ReacquireDigitalHandle(void)
{
if ( ALDevice )
{
if ( prevprovider != -1 )
set_new_provider(prevprovider);
}
// TODO? alcProcessContext
}
bool8
@ -1000,7 +894,7 @@ cSampleManager::Initialise(void)
{
m_aSamples[i].nOffset = 0;
m_aSamples[i].nSize = 0;
m_aSamples[i].nFrequency = MAX_FREQ;
m_aSamples[i].nFrequency = 22050;
m_aSamples[i].nLoopStart = 0;
m_aSamples[i].nLoopEnd = -1;
}
@ -1057,13 +951,84 @@ cSampleManager::Initialise(void)
nChannelVolume[i] = 0;
}
add_providers();
{
int index = 0;
_maxSamples = Min(MAXCHANNELS, providers[index].sources);
ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,
ALC_MONO_SOURCES, MAX_DIGITAL_MIXER_CHANNELS - MAX2DCHANNELS,
ALC_STEREO_SOURCES, MAX2DCHANNELS,
0,
};
ALDevice = alcOpenDevice(providers[index].id);
ASSERT(ALDevice != NULL);
ALContext = alcCreateContext(ALDevice, attr);
ASSERT(ALContext != NULL);
alcMakeContextCurrent(ALContext);
const char* ext=(const char*)alGetString(AL_EXTENSIONS);
ASSERT(strstr(ext,"AL_SOFT_loop_points")!=NULL);
if ( strstr(ext,"AL_SOFT_loop_points")==NULL )
{
Terminate();
return FALSE;
}
alListenerf (AL_GAIN, 1.0f);
alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f);
ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };
alListenerfv(AL_ORIENTATION, orientation);
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
{
_effectsSupported = providers[index].bSupportsFx;
alGenAuxiliaryEffectSlots(1, &ALEffectSlot);
alGenEffects(1, &ALEffect);
}
alGenSources(MAX_STREAMS*2, ALStreamSources[0]);
for ( int32 i = 0; i < MAX_STREAMS; i++ )
{
alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
alSourcei(ALStreamSources[i][0], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(ALStreamSources[i][0], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSourcef(ALStreamSources[i][0], AL_GAIN, 1.0f);
alSourcei(ALStreamSources[i][1], AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(ALStreamSources[i][1], AL_POSITION, 0.0f, 0.0f, 0.0f);
alSourcef(ALStreamSources[i][1], AL_GAIN, 1.0f);
}
CChannel::InitChannels();
for ( int32 i = 0; i < MAXCHANNELS; i++ )
aChannel[i].Init(i);
for ( int32 i = 0; i < MAX2DCHANNELS; i++ )
aChannel[MAXCHANNELS+i].Init(MAXCHANNELS+i, true);
if ( IsFXSupported() )
{
/**/
alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
/**/
for ( int32 i = 0; i < MAXCHANNELS; i++ )
aChannel[i].SetReverbMix(ALEffectSlot, 0.0f);
}
}
{
for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
nStreamLength[i] = 0;
}
add_providers();
#ifdef AUDIO_CACHE
FILE *cacheFile = fcaseopen("audio\\sound.cache", "rb");
if (cacheFile) {
@ -1241,7 +1206,50 @@ cSampleManager::Terminate(void)
}
}
release_existing();
for ( int32 i = 0; i < NUM_CHANNELS; i++ )
aChannel[i].Term();
if ( IsFXSupported() )
{
if ( alIsEffect(ALEffect) )
{
alEffecti(ALEffect, AL_EFFECT_TYPE, AL_EFFECT_NULL);
alDeleteEffects(1, &ALEffect);
ALEffect = AL_EFFECT_NULL;
}
if (alIsAuxiliaryEffectSlot(ALEffectSlot))
{
alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL);
alDeleteAuxiliaryEffectSlots(1, &ALEffectSlot);
ALEffectSlot = AL_EFFECTSLOT_NULL;
}
}
for ( int32 i = 0; i < MAX_STREAMS; i++ )
{
alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
}
alDeleteSources(MAX_STREAMS*2, ALStreamSources[0]);
CChannel::DestroyChannels();
if ( ALContext )
{
alcMakeContextCurrent(NULL);
alcSuspendContext(ALContext);
alcDestroyContext(ALContext);
}
if ( ALDevice )
alcCloseDevice(ALDevice);
ALDevice = NULL;
ALContext = NULL;
_fPrevEaxRatioDestination = 0.0f;
_usingEFX = false;
_fEffectsLevel = 0.0f;
_DeleteMP3Entries();