mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 22:15:32 +00:00
Set HRTF when initializing the device
This commit is contained in:
parent
c17edfd547
commit
3757571d46
4 changed files with 85 additions and 50 deletions
|
@ -592,7 +592,7 @@ std::vector<std::string> OpenAL_Output::enumerate()
|
||||||
return devlist;
|
return devlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenAL_Output::init(const std::string &devname)
|
bool OpenAL_Output::init(const std::string &devname, const std::string &hrtfname, HrtfMode hrtfmode)
|
||||||
{
|
{
|
||||||
deinit();
|
deinit();
|
||||||
|
|
||||||
|
@ -615,7 +615,47 @@ bool OpenAL_Output::init(const std::string &devname)
|
||||||
std::cout << "Opened \""<<name<<"\"" << std::endl;
|
std::cout << "Opened \""<<name<<"\"" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
mContext = alcCreateContext(mDevice, NULL);
|
ALC.EXT_EFX = alcIsExtensionPresent(mDevice, "ALC_EXT_EFX");
|
||||||
|
ALC.SOFT_HRTF = alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF");
|
||||||
|
|
||||||
|
std::vector<ALCint> attrs;
|
||||||
|
attrs.reserve(15);
|
||||||
|
if(ALC.SOFT_HRTF)
|
||||||
|
{
|
||||||
|
LPALCGETSTRINGISOFT alcGetStringiSOFT = 0;
|
||||||
|
getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT");
|
||||||
|
|
||||||
|
attrs.push_back(ALC_HRTF_SOFT);
|
||||||
|
attrs.push_back(hrtfmode == HrtfMode::Disable ? ALC_FALSE :
|
||||||
|
hrtfmode == HrtfMode::Enable ? ALC_TRUE :
|
||||||
|
/*hrtfmode == HrtfMode::Auto ?*/ ALC_DONT_CARE_SOFT);
|
||||||
|
if(!hrtfname.empty())
|
||||||
|
{
|
||||||
|
ALCint index = -1;
|
||||||
|
ALCint num_hrtf;
|
||||||
|
alcGetIntegerv(mDevice, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf);
|
||||||
|
for(ALCint i = 0;i < num_hrtf;++i)
|
||||||
|
{
|
||||||
|
const ALCchar *entry = alcGetStringiSOFT(mDevice, ALC_HRTF_SPECIFIER_SOFT, i);
|
||||||
|
if(hrtfname == entry)
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(index < 0)
|
||||||
|
std::cerr<< "Failed to find HRTF name \""<<hrtfname<<"\", using default" <<std::endl;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attrs.push_back(ALC_HRTF_ID_SOFT);
|
||||||
|
attrs.push_back(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attrs.push_back(0);
|
||||||
|
|
||||||
|
mContext = alcCreateContext(mDevice, attrs.data());
|
||||||
if(!mContext || alcMakeContextCurrent(mContext) == ALC_FALSE)
|
if(!mContext || alcMakeContextCurrent(mContext) == ALC_FALSE)
|
||||||
{
|
{
|
||||||
std::cerr<< "Failed to setup audio context: "<<alcGetString(mDevice, alcGetError(mDevice)) <<std::endl;
|
std::cerr<< "Failed to setup audio context: "<<alcGetString(mDevice, alcGetError(mDevice)) <<std::endl;
|
||||||
|
@ -627,8 +667,22 @@ bool OpenAL_Output::init(const std::string &devname)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALC.EXT_EFX = !!alcIsExtensionPresent(mDevice, "ALC_EXT_EFX");
|
if(!ALC.SOFT_HRTF)
|
||||||
AL.SOFT_source_spatialize = !!alIsExtensionPresent("AL_SOFT_source_spatialize");
|
std::cout<< "HRTF status unavailable" <<std::endl;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ALCint hrtf_state;
|
||||||
|
alcGetIntegerv(mDevice, ALC_HRTF_SOFT, 1, &hrtf_state);
|
||||||
|
if(!hrtf_state)
|
||||||
|
std::cout<< "HRTF disabled" <<std::endl;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const ALCchar *hrtf = alcGetString(mDevice, ALC_HRTF_SPECIFIER_SOFT);
|
||||||
|
std::cout<< "Enabled HRTF "<<hrtf <<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AL.SOFT_source_spatialize = alIsExtensionPresent("AL_SOFT_source_spatialize");
|
||||||
|
|
||||||
ALCuint maxtotal;
|
ALCuint maxtotal;
|
||||||
ALCint maxmono = 0, maxstereo = 0;
|
ALCint maxmono = 0, maxstereo = 0;
|
||||||
|
@ -805,7 +859,7 @@ std::vector<std::string> OpenAL_Output::enumerateHrtf()
|
||||||
{
|
{
|
||||||
std::vector<std::string> ret;
|
std::vector<std::string> ret;
|
||||||
|
|
||||||
if(!mDevice || !alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF"))
|
if(!mDevice || !ALC.SOFT_HRTF)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
LPALCGETSTRINGISOFT alcGetStringiSOFT = 0;
|
LPALCGETSTRINGISOFT alcGetStringiSOFT = 0;
|
||||||
|
@ -823,9 +877,9 @@ std::vector<std::string> OpenAL_Output::enumerateHrtf()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenAL_Output::enableHrtf(const std::string &hrtfname, bool auto_enable)
|
void OpenAL_Output::setHrtf(const std::string &hrtfname, HrtfMode hrtfmode)
|
||||||
{
|
{
|
||||||
if(!alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF"))
|
if(!mDevice || !ALC.SOFT_HRTF)
|
||||||
{
|
{
|
||||||
std::cerr<< "HRTF extension not present" <<std::endl;
|
std::cerr<< "HRTF extension not present" <<std::endl;
|
||||||
return;
|
return;
|
||||||
|
@ -838,8 +892,12 @@ void OpenAL_Output::enableHrtf(const std::string &hrtfname, bool auto_enable)
|
||||||
getALCFunc(alcResetDeviceSOFT, mDevice, "alcResetDeviceSOFT");
|
getALCFunc(alcResetDeviceSOFT, mDevice, "alcResetDeviceSOFT");
|
||||||
|
|
||||||
std::vector<ALCint> attrs;
|
std::vector<ALCint> attrs;
|
||||||
|
attrs.reserve(15);
|
||||||
|
|
||||||
attrs.push_back(ALC_HRTF_SOFT);
|
attrs.push_back(ALC_HRTF_SOFT);
|
||||||
attrs.push_back(auto_enable ? ALC_DONT_CARE_SOFT : ALC_TRUE);
|
attrs.push_back(hrtfmode == HrtfMode::Disable ? ALC_FALSE :
|
||||||
|
hrtfmode == HrtfMode::Enable ? ALC_TRUE :
|
||||||
|
/*hrtfmode == HrtfMode::Auto ?*/ ALC_DONT_CARE_SOFT);
|
||||||
if(!hrtfname.empty())
|
if(!hrtfname.empty())
|
||||||
{
|
{
|
||||||
ALCint index = -1;
|
ALCint index = -1;
|
||||||
|
@ -864,12 +922,12 @@ void OpenAL_Output::enableHrtf(const std::string &hrtfname, bool auto_enable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
attrs.push_back(0);
|
attrs.push_back(0);
|
||||||
alcResetDeviceSOFT(mDevice, &attrs[0]);
|
alcResetDeviceSOFT(mDevice, attrs.data());
|
||||||
|
|
||||||
ALCint hrtf_state;
|
ALCint hrtf_state;
|
||||||
alcGetIntegerv(mDevice, ALC_HRTF_SOFT, 1, &hrtf_state);
|
alcGetIntegerv(mDevice, ALC_HRTF_SOFT, 1, &hrtf_state);
|
||||||
if(!hrtf_state)
|
if(!hrtf_state)
|
||||||
std::cerr<< "Failed to enable HRTF" <<std::endl;
|
std::cout<< "HRTF disabled" <<std::endl;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const ALCchar *hrtf = alcGetString(mDevice, ALC_HRTF_SPECIFIER_SOFT);
|
const ALCchar *hrtf = alcGetString(mDevice, ALC_HRTF_SPECIFIER_SOFT);
|
||||||
|
@ -877,31 +935,6 @@ void OpenAL_Output::enableHrtf(const std::string &hrtfname, bool auto_enable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenAL_Output::disableHrtf()
|
|
||||||
{
|
|
||||||
if(!alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF"))
|
|
||||||
{
|
|
||||||
std::cerr<< "HRTF extension not present" <<std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPALCRESETDEVICESOFT alcResetDeviceSOFT = 0;
|
|
||||||
getALCFunc(alcResetDeviceSOFT, mDevice, "alcResetDeviceSOFT");
|
|
||||||
|
|
||||||
std::vector<ALCint> attrs;
|
|
||||||
attrs.push_back(ALC_HRTF_SOFT);
|
|
||||||
attrs.push_back(ALC_FALSE);
|
|
||||||
attrs.push_back(0);
|
|
||||||
alcResetDeviceSOFT(mDevice, &attrs[0]);
|
|
||||||
|
|
||||||
ALCint hrtf_state;
|
|
||||||
alcGetIntegerv(mDevice, ALC_HRTF_SOFT, 1, &hrtf_state);
|
|
||||||
if(hrtf_state)
|
|
||||||
std::cerr<< "Failed to disable HRTF" <<std::endl;
|
|
||||||
else
|
|
||||||
std::cout<< "Disabled HRTF" <<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Sound_Handle OpenAL_Output::loadSound(const std::string &fname)
|
Sound_Handle OpenAL_Output::loadSound(const std::string &fname)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,10 +24,11 @@ namespace MWSound
|
||||||
ALCcontext *mContext;
|
ALCcontext *mContext;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int EXT_EFX : 1;
|
bool EXT_EFX : 1;
|
||||||
|
bool SOFT_HRTF : 1;
|
||||||
} ALC;
|
} ALC;
|
||||||
struct {
|
struct {
|
||||||
int SOFT_source_spatialize : 1;
|
bool SOFT_source_spatialize : 1;
|
||||||
} AL;
|
} AL;
|
||||||
|
|
||||||
typedef std::deque<ALuint> IDDq;
|
typedef std::deque<ALuint> IDDq;
|
||||||
|
@ -59,12 +60,11 @@ namespace MWSound
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual std::vector<std::string> enumerate();
|
virtual std::vector<std::string> enumerate();
|
||||||
virtual bool init(const std::string &devname=std::string());
|
virtual bool init(const std::string &devname, const std::string &hrtfname, HrtfMode hrtfmode);
|
||||||
virtual void deinit();
|
virtual void deinit();
|
||||||
|
|
||||||
virtual std::vector<std::string> enumerateHrtf();
|
virtual std::vector<std::string> enumerateHrtf();
|
||||||
virtual void enableHrtf(const std::string &hrtfname, bool auto_enable);
|
virtual void setHrtf(const std::string &hrtfname, HrtfMode hrtfmode);
|
||||||
virtual void disableHrtf();
|
|
||||||
|
|
||||||
virtual Sound_Handle loadSound(const std::string &fname);
|
virtual Sound_Handle loadSound(const std::string &fname);
|
||||||
virtual void unloadSound(Sound_Handle data);
|
virtual void unloadSound(Sound_Handle data);
|
||||||
|
|
|
@ -19,17 +19,22 @@ namespace MWSound
|
||||||
// An opaque handle for the implementation's sound instances.
|
// An opaque handle for the implementation's sound instances.
|
||||||
typedef void *Sound_Instance;
|
typedef void *Sound_Instance;
|
||||||
|
|
||||||
|
enum class HrtfMode {
|
||||||
|
Disable,
|
||||||
|
Enable,
|
||||||
|
Auto
|
||||||
|
};
|
||||||
|
|
||||||
class Sound_Output
|
class Sound_Output
|
||||||
{
|
{
|
||||||
SoundManager &mManager;
|
SoundManager &mManager;
|
||||||
|
|
||||||
virtual std::vector<std::string> enumerate() = 0;
|
virtual std::vector<std::string> enumerate() = 0;
|
||||||
virtual bool init(const std::string &devname=std::string()) = 0;
|
virtual bool init(const std::string &devname, const std::string &hrtfname, HrtfMode hrtfmode) = 0;
|
||||||
virtual void deinit() = 0;
|
virtual void deinit() = 0;
|
||||||
|
|
||||||
virtual std::vector<std::string> enumerateHrtf() = 0;
|
virtual std::vector<std::string> enumerateHrtf() = 0;
|
||||||
virtual void enableHrtf(const std::string &hrtfname, bool auto_enable) = 0;
|
virtual void setHrtf(const std::string &hrtfname, HrtfMode hrtfmode) = 0;
|
||||||
virtual void disableHrtf() = 0;
|
|
||||||
|
|
||||||
virtual Sound_Handle loadSound(const std::string &fname) = 0;
|
virtual Sound_Handle loadSound(const std::string &fname) = 0;
|
||||||
virtual void unloadSound(Sound_Handle data) = 0;
|
virtual void unloadSound(Sound_Handle data) = 0;
|
||||||
|
|
|
@ -85,6 +85,8 @@ namespace MWSound
|
||||||
|
|
||||||
std::string hrtfname = Settings::Manager::getString("hrtf", "Sound");
|
std::string hrtfname = Settings::Manager::getString("hrtf", "Sound");
|
||||||
int hrtfstate = Settings::Manager::getInt("hrtf enable", "Sound");
|
int hrtfstate = Settings::Manager::getInt("hrtf enable", "Sound");
|
||||||
|
HrtfMode hrtfmode = hrtfstate < 0 ? HrtfMode::Auto :
|
||||||
|
hrtfstate > 0 ? HrtfMode::Enable : HrtfMode::Disable;
|
||||||
|
|
||||||
std::cout << "Sound output: " << SOUND_OUT << std::endl;
|
std::cout << "Sound output: " << SOUND_OUT << std::endl;
|
||||||
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
|
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
|
||||||
|
@ -98,11 +100,11 @@ namespace MWSound
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
|
|
||||||
std::string devname = Settings::Manager::getString("device", "Sound");
|
std::string devname = Settings::Manager::getString("device", "Sound");
|
||||||
bool inited = mOutput->init(devname);
|
bool inited = mOutput->init(devname, hrtfname, hrtfmode);
|
||||||
if(!inited && !devname.empty())
|
if(!inited && !devname.empty())
|
||||||
{
|
{
|
||||||
std::cerr<< "Failed to initialize device \""<<devname<<"\", trying default" <<std::endl;
|
std::cerr<< "Failed to initialize device \""<<devname<<"\", trying default" <<std::endl;
|
||||||
inited = mOutput->init();
|
inited = mOutput->init(std::string(), hrtfname, hrtfmode);
|
||||||
}
|
}
|
||||||
if(!inited)
|
if(!inited)
|
||||||
{
|
{
|
||||||
|
@ -120,11 +122,6 @@ namespace MWSound
|
||||||
);
|
);
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hrtfstate == 0)
|
|
||||||
mOutput->disableHrtf();
|
|
||||||
else if(!hrtfname.empty())
|
|
||||||
mOutput->enableHrtf(hrtfname, hrtfstate<0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundManager::~SoundManager()
|
SoundManager::~SoundManager()
|
||||||
|
|
Loading…
Reference in a new issue