1
0
Fork 1
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:
Chris Robinson 2017-09-14 04:48:12 -07:00
parent c17edfd547
commit 3757571d46
4 changed files with 85 additions and 50 deletions

View file

@ -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)
{ {

View file

@ -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);

View file

@ -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;

View file

@ -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()