Merge pull request #291 from TES3MP/master

Add master commits up to 17 Sep 2017
new-script-api
David Cernat 7 years ago committed by GitHub
commit 381a5fabc4

@ -16,6 +16,7 @@ set(ESSIMPORTER_FILES
importjour.cpp
importscri.cpp
importscpt.cpp
importproj.cpp
importercontext.cpp
converter.cpp
convertacdt.cpp

@ -6,6 +6,7 @@
#include <components/esm/creaturestate.hpp>
#include <components/esm/containerstate.hpp>
#include <components/esm/projectilestate.hpp>
#include "convertcrec.hpp"
#include "convertcntc.hpp"
@ -53,6 +54,36 @@ namespace
return true;
return false;
}
void splitIndexedRefId(const std::string& indexedRefId, int& refIndex, std::string& refId)
{
std::stringstream stream;
stream << std::hex << indexedRefId.substr(indexedRefId.size()-8,8);
stream >> refIndex;
refId = indexedRefId.substr(0,indexedRefId.size()-8);
}
int convertActorId(const std::string& indexedRefId, ESSImport::Context& context)
{
if (isIndexedRefId(indexedRefId))
{
int refIndex;
std::string refId;
splitIndexedRefId(indexedRefId, refIndex, refId);
auto it = context.mActorIdMap.find(std::make_pair(refIndex, refId));
if (it == context.mActorIdMap.end())
return -1;
return it->second;
}
else if (indexedRefId == "PlayerSaveGame")
{
return context.mPlayer.mObject.mCreatureStats.mActorId;
}
return -1;
}
}
namespace ESSImport
@ -322,12 +353,9 @@ namespace ESSImport
}
else
{
std::stringstream stream;
stream << std::hex << cellref.mIndexedRefId.substr(cellref.mIndexedRefId.size()-8,8);
int refIndex;
stream >> refIndex;
splitIndexedRefId(cellref.mIndexedRefId, refIndex, out.mRefID);
out.mRefID = cellref.mIndexedRefId.substr(0,cellref.mIndexedRefId.size()-8);
std::string idLower = Misc::StringUtils::lowerCase(out.mRefID);
std::map<std::pair<int, std::string>, NPCC>::const_iterator npccIt = mContext->mNpcChanges.find(
@ -347,6 +375,10 @@ namespace ESSImport
convertNpcData(cellref, objstate.mNpcStats);
convertNPCC(npccIt->second, objstate);
convertCellRef(cellref, objstate);
objstate.mCreatureStats.mActorId = mContext->generateActorId();
mContext->mActorIdMap.insert(std::make_pair(std::make_pair(refIndex, out.mRefID), objstate.mCreatureStats.mActorId));
esm.writeHNT ("OBJE", ESM::REC_NPC_);
objstate.save(esm);
continue;
@ -383,6 +415,10 @@ namespace ESSImport
convertACSC(cellref.mACSC, objstate.mCreatureStats);
convertCREC(crecIt->second, objstate);
convertCellRef(cellref, objstate);
objstate.mCreatureStats.mActorId = mContext->generateActorId();
mContext->mActorIdMap.insert(std::make_pair(std::make_pair(refIndex, out.mRefID), objstate.mCreatureStats.mActorId));
esm.writeHNT ("OBJE", ESM::REC_CREA);
objstate.save(esm);
continue;
@ -413,4 +449,44 @@ namespace ESSImport
}
}
void ConvertPROJ::read(ESM::ESMReader& esm)
{
mProj.load(esm);
}
void ConvertPROJ::write(ESM::ESMWriter& esm)
{
for (const PROJ::PNAM& pnam : mProj.mProjectiles)
{
if (!pnam.isMagic())
{
ESM::ProjectileState out;
out.mId = pnam.mArrowId.toString();
out.mPosition = pnam.mPosition;
out.mOrientation.mValues[0] = out.mOrientation.mValues[1] = out.mOrientation.mValues[2] = 0.0f;
out.mOrientation.mValues[3] = 1.0f;
out.mActorId = convertActorId(pnam.mActorId.toString(), *mContext);
out.mBowId = pnam.mBowId.toString();
out.mVelocity = pnam.mVelocity;
out.mAttackStrength = pnam.mAttackStrength;
esm.startRecord(ESM::REC_PROJ);
out.save(esm);
esm.endRecord(ESM::REC_PROJ);
}
else
{
// TODO: Implement magic projectile conversion.
/*esm.startRecord(ESM::REC_MPRJ);
out.save(esm);
esm.endRecord(ESM::REC_MPRJ);*/
std::cerr << "Warning: Skipped conversion for magic projectile \"" << pnam.mArrowId.toString() << "\" (not implemented)" << std::endl;
continue;
}
}
}
}

@ -35,6 +35,7 @@
#include "importques.hpp"
#include "importjour.hpp"
#include "importscpt.hpp"
#include "importproj.h"
#include "convertacdt.hpp"
#include "convertnpcc.hpp"
@ -593,6 +594,17 @@ private:
std::vector<ESM::GlobalScript> mScripts;
};
/// Projectile converter
class ConvertPROJ : public Converter
{
public:
virtual int getStage() override { return 2; }
virtual void read(ESM::ESMReader& esm) override;
virtual void write(ESM::ESMWriter& esm) override;
private:
PROJ mProj;
};
}
#endif

@ -303,6 +303,7 @@ namespace ESSImport
converters[ESM::REC_QUES] = std::shared_ptr<Converter>(new ConvertQUES());
converters[recJOUR ] = std::shared_ptr<Converter>(new ConvertJOUR());
converters[ESM::REC_SCPT] = std::shared_ptr<Converter>(new ConvertSCPT());
converters[ESM::REC_PROJ] = std::shared_ptr<Converter>(new ConvertPROJ());
// TODO:
// - REGN (weather in certain regions?)
@ -420,6 +421,19 @@ namespace ESSImport
context.mPlayer.save(writer);
writer.endRecord(ESM::REC_PLAY);
writer.startRecord(ESM::REC_ACTC);
writer.writeHNT("COUN", context.mNextActorId);
writer.endRecord(ESM::REC_ACTC);
// Stage 2 requires cell references to be written / actors IDs assigned
for (std::map<unsigned int, std::shared_ptr<Converter> >::const_iterator it = converters.begin();
it != converters.end(); ++it)
{
if (it->second->getStage() != 2)
continue;
it->second->write(writer);
}
writer.startRecord (ESM::REC_DIAS);
context.mDialogueState.save(writer);
writer.endRecord(ESM::REC_DIAS);

@ -48,6 +48,9 @@ namespace ESSImport
std::map<std::pair<int, std::string>, NPCC> mNpcChanges;
std::map<std::pair<int, std::string>, CNTC> mContainerChanges;
std::map<std::pair<int, std::string>, int> mActorIdMap;
int mNextActorId;
std::map<std::string, ESM::Creature> mCreatures;
std::map<std::string, ESM::NPC> mNpcs;
@ -56,6 +59,7 @@ namespace ESSImport
, mMonth(0)
, mYear(0)
, mHour(0.f)
, mNextActorId(0)
{
mPlayer.mAutoMove = 0;
ESM::CellId playerCellId;
@ -67,16 +71,23 @@ namespace ESSImport
= mPlayer.mLastKnownExteriorPosition[2]
= 0.0f;
mPlayer.mHasMark = 0;
mPlayer.mCurrentCrimeId = 0; // TODO
mPlayer.mCurrentCrimeId = -1; // TODO
mPlayer.mPaidCrimeId = -1;
mPlayer.mObject.blank();
mPlayer.mObject.mEnabled = true;
mPlayer.mObject.mRef.mRefID = "player"; // REFR.mRefID would be PlayerSaveGame
mPlayer.mObject.mCreatureStats.mActorId = generateActorId();
mGlobalMapState.mBounds.mMinX = 0;
mGlobalMapState.mBounds.mMaxX = 0;
mGlobalMapState.mBounds.mMinY = 0;
mGlobalMapState.mBounds.mMaxY = 0;
}
int generateActorId()
{
return mNextActorId++;
}
};
}

@ -0,0 +1,18 @@
#include "importproj.h"
#include <components/esm/esmreader.hpp>
namespace ESSImport
{
void ESSImport::PROJ::load(ESM::ESMReader& esm)
{
while (esm.isNextSub("PNAM"))
{
PNAM pnam;
esm.getHT(pnam);
mProjectiles.push_back(pnam);
}
}
}

@ -0,0 +1,47 @@
#ifndef OPENMW_ESSIMPORT_IMPORTPROJ_H
#define OPENMW_ESSIMPORT_IMPORTPROJ_H
#include <vector>
#include <components/esm/esmcommon.hpp>
#include <components/esm/util.hpp>
namespace ESM
{
class ESMReader;
}
namespace ESSImport
{
struct PROJ
{
#pragma pack(push)
#pragma pack(1)
struct PNAM // 184 bytes
{
float mAttackStrength;
float mSpeed;
unsigned char mUnknown[4*2];
float mFlightTime;
int mSplmIndex; // reference to a SPLM record (0 for ballistic projectiles)
unsigned char mUnknown2[4];
ESM::Vector3 mVelocity;
ESM::Vector3 mPosition;
unsigned char mUnknown3[4*9];
ESM::NAME32 mActorId; // indexed refID (with the exception of "PlayerSaveGame")
ESM::NAME32 mArrowId;
ESM::NAME32 mBowId;
bool isMagic() const { return mSplmIndex != 0; }
};
#pragma pack(pop)
std::vector<PNAM> mProjectiles;
void load(ESM::ESMReader& esm);
};
}
#endif

@ -57,7 +57,8 @@ add_openmw_dir (mwscript
)
add_openmw_dir (mwsound
soundmanagerimp openal_output ffmpeg_decoder sound sound_buffer sound_decoder sound_output loudness movieaudiofactory
soundmanagerimp openal_output ffmpeg_decoder sound sound_buffer sound_decoder sound_output
loudness movieaudiofactory alext efx efx-presets
)
add_openmw_dir (mwworld

@ -18,54 +18,59 @@ namespace MWSound
class Stream;
struct Sound_Decoder;
typedef std::shared_ptr<Sound_Decoder> DecoderPtr;
/* These must all fit together */
enum class PlayMode {
Normal = 0, /* non-looping, affected by environment */
Loop = 1<<0, /* Sound will continually loop until explicitly stopped */
NoEnv = 1<<1, /* Do not apply environment effects (eg, underwater filters) */
RemoveAtDistance = 1<<2, /* (3D only) If the listener gets further than 2000 units away
* from the sound source, the sound is removed.
* This is weird stuff but apparently how vanilla works for sounds
* played by the PlayLoopSound family of script functions. Perhaps
* we can make this cut off a more subtle fade later, but have to
* be careful to not change the overall volume of areas by too
* much. */
NoPlayerLocal = 1<<3, /* (3D only) Don't play the sound local to the listener even if the
* player is making it. */
LoopNoEnv = Loop | NoEnv,
LoopRemoveAtDistance = Loop | RemoveAtDistance
};
enum class Type {
Sfx = 1<<4, /* Normal SFX sound */
Voice = 1<<5, /* Voice sound */
Foot = 1<<6, /* Footstep sound */
Music = 1<<7, /* Music track */
Movie = 1<<8, /* Movie audio track */
Mask = Sfx | Voice | Foot | Music | Movie
};
// Used for creating a type mask for SoundManager::pauseSounds and resumeSounds
inline int operator~(Type a) { return ~static_cast<int>(a); }
inline int operator&(Type a, Type b) { return static_cast<int>(a) & static_cast<int>(b); }
inline int operator&(int a, Type b) { return a & static_cast<int>(b); }
inline int operator|(Type a, Type b) { return static_cast<int>(a) | static_cast<int>(b); }
}
namespace MWBase
{
typedef std::shared_ptr<MWSound::Sound> SoundPtr;
typedef std::shared_ptr<MWSound::Stream> SoundStreamPtr;
using Sound = MWSound::Sound;
using SoundStream = MWSound::Stream;
/// \brief Interface for sound manager (implemented in MWSound)
class SoundManager
{
public:
/* These must all fit together */
enum PlayMode {
Play_Normal = 0, /* non-looping, affected by environment */
Play_Loop = 1<<0, /* Sound will continually loop until explicitly stopped */
Play_NoEnv = 1<<1, /* Do not apply environment effects (eg, underwater filters) */
Play_RemoveAtDistance = 1<<2, /* (3D only) If the listener gets further than 2000 units away
from the sound source, the sound is removed.
This is weird stuff but apparently how vanilla works for sounds
played by the PlayLoopSound family of script functions. Perhaps we
can make this cut off a more subtle fade later, but have to
be careful to not change the overall volume of areas by too much. */
Play_NoPlayerLocal = 1<<3, /* (3D only) Don't play the sound local to the listener even if the
player is making it. */
Play_LoopNoEnv = Play_Loop | Play_NoEnv,
Play_LoopRemoveAtDistance = Play_Loop | Play_RemoveAtDistance
};
enum PlayType {
Play_TypeSfx = 1<<4, /* Normal SFX sound */
Play_TypeVoice = 1<<5, /* Voice sound */
Play_TypeFoot = 1<<6, /* Footstep sound */
Play_TypeMusic = 1<<7, /* Music track */
Play_TypeMovie = 1<<8, /* Movie audio track */
Play_TypeMask = Play_TypeSfx|Play_TypeVoice|Play_TypeFoot|Play_TypeMusic|Play_TypeMovie
};
private:
SoundManager (const SoundManager&);
///< not implemented
SoundManager& operator= (const SoundManager&);
///< not implemented
public:
protected:
using PlayMode = MWSound::PlayMode;
using Type = MWSound::Type;
public:
SoundManager() {}
virtual ~SoundManager() {}
virtual void processChangedSettings(const std::set< std::pair<std::string, std::string> >& settings) = 0;
@ -106,34 +111,36 @@ namespace MWBase
/// and get an average loudness value (scale [0,1]) at the current time position.
/// If the actor is not saying anything, returns 0.
virtual SoundStreamPtr playTrack(const MWSound::DecoderPtr& decoder, PlayType type) = 0;
///< Play a 2D audio track, using a custom decoder
virtual SoundStream *playTrack(const MWSound::DecoderPtr& decoder, Type type) = 0;
///< Play a 2D audio track, using a custom decoder. The caller is expected to call
/// stopTrack with the returned handle when done.
virtual void stopTrack(SoundStreamPtr stream) = 0;
virtual void stopTrack(SoundStream *stream) = 0;
///< Stop the given audio track from playing
virtual double getTrackTimeDelay(SoundStreamPtr stream) = 0;
virtual double getTrackTimeDelay(SoundStream *stream) = 0;
///< Retives the time delay, in seconds, of the audio track (must be a sound
/// returned by \ref playTrack). Only intended to be called by the track
/// decoder's read method.
virtual SoundPtr playSound(const std::string& soundId, float volume, float pitch,
PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal,
float offset=0) = 0;
virtual Sound *playSound(const std::string& soundId, float volume, float pitch,
Type type=Type::Sfx, PlayMode mode=PlayMode::Normal,
float offset=0) = 0;
///< Play a sound, independently of 3D-position
///< @param offset Number of seconds into the sound to start playback.
virtual MWBase::SoundPtr playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId,
float volume, float pitch, PlayType type=Play_TypeSfx,
PlayMode mode=Play_Normal, float offset=0) = 0;
virtual Sound *playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId,
float volume, float pitch, Type type=Type::Sfx,
PlayMode mode=PlayMode::Normal, float offset=0) = 0;
///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified.
///< @param offset Number of seconds into the sound to start playback.
virtual MWBase::SoundPtr playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal, float offset=0) = 0;
virtual Sound *playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, Type type=Type::Sfx,
PlayMode mode=PlayMode::Normal, float offset=0) = 0;
///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using Sound::setPosition.
virtual void stopSound(SoundPtr sound) = 0;
virtual void stopSound(Sound *sound) = 0;
///< Stop the given sound from playing
virtual void stopSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId) = 0;
@ -158,10 +165,10 @@ namespace MWBase
///< Is the given sound currently playing on the given object?
/// If you want to check if sound played with playSound is playing, use empty Ptr
virtual void pauseSounds(int types=Play_TypeMask) = 0;
virtual void pauseSounds(int types=static_cast<int>(Type::Mask)) = 0;
///< Pauses all currently playing sounds, including music.
virtual void resumeSounds(int types=Play_TypeMask) = 0;
virtual void resumeSounds(int types=static_cast<int>(Type::Mask)) = 0;
///< Resumes all previously paused sounds.
virtual void update(float duration) = 0;

@ -181,9 +181,7 @@ namespace MWClass
if(isTrapped)
{
ptr.getCellRef().setTrap("");
MWBase::Environment::get().getSoundManager()->playSound3D(ptr,
"Disarm Trap", 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Normal);
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "Disarm Trap", 1.0f, 1.0f);
isTrapped = false;
/*

@ -175,9 +175,7 @@ namespace MWClass
if(isTrapped)
{
ptr.getCellRef().setTrap("");
MWBase::Environment::get().getSoundManager()->playSound3D(ptr,
"Disarm Trap", 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Normal);
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "Disarm Trap", 1.0f, 1.0f);
isTrapped = false;
/*

@ -49,8 +49,8 @@ namespace MWClass
if (!ref->mBase->mSound.empty() && !(ref->mBase->mData.mFlags & ESM::Light::OffDefault))
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0,
MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Loop);
MWSound::Type::Sfx,
MWSound::PlayMode::Loop);
}
bool Light::useAnim() const

@ -1886,7 +1886,8 @@ namespace MWGui
if (mVideoWidget->hasAudioStream())
MWBase::Environment::get().getSoundManager()->pauseSounds(
MWBase::SoundManager::Play_TypeMask&(~MWBase::SoundManager::Play_TypeMovie));
~MWSound::Type::Movie & MWSound::Type::Mask
);
osg::Timer frameTimer;
while (mVideoWidget->update() && !MWBase::Environment::get().getStateManager()->hasQuitRequest())
{
@ -2073,7 +2074,7 @@ namespace MWGui
void WindowManager::playSound(const std::string& soundId, float volume, float pitch)
{
MWBase::Environment::get().getSoundManager()->playSound(soundId, volume, pitch, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoEnv);
MWBase::Environment::get().getSoundManager()->playSound(soundId, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv);
}
void WindowManager::setConsoleSelectedObject(const MWWorld::Ptr &object)

@ -1051,7 +1051,7 @@ namespace MWMechanics
// ...But, only the player makes a sound.
if(isPlayer)
MWBase::Environment::get().getSoundManager()->playSound("torch out",
1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoEnv);
1.0, 1.0, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv);
}
}
}

@ -873,8 +873,8 @@ void CharacterController::handleTextKey(const std::string &groupname, const std:
{
// Don't make foot sounds local for the player, it makes sense to keep them
// positioned on the ground.
sndMgr->playSound3D(mPtr, sound, volume, pitch, MWBase::SoundManager::Play_TypeFoot,
MWBase::SoundManager::Play_NoPlayerLocal);
sndMgr->playSound3D(mPtr, sound, volume, pitch, MWSound::Type::Foot,
MWSound::PlayMode::NoPlayerLocal);
}
else
{
@ -1237,8 +1237,8 @@ bool CharacterController::updateWeaponState()
&& mWeaponType == WeapType_None)
{
if(!sndMgr->getSoundPlaying(mPtr, "WolfRun"))
sndMgr->playSound3D(mPtr, "WolfRun", 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Loop);
sndMgr->playSound3D(mPtr, "WolfRun", 1.0f, 1.0f, MWSound::Type::Sfx,
MWSound::PlayMode::Loop);
}
else
sndMgr->stopSound3D(mPtr, "WolfRun");
@ -1276,6 +1276,7 @@ bool CharacterController::updateWeaponState()
if(mUpperBodyState == UpperCharState_WeapEquiped && (mHitState == CharState_None || mHitState == CharState_Block))
{
MWBase::Environment::get().getWorld()->breakInvisibility(mPtr);
mAttackStrength = 0;
if(mWeaponType == WeapType_Spell)
{
// Unset casting flag, otherwise pressing the mouse button down would
@ -1388,9 +1389,8 @@ bool CharacterController::updateWeaponState()
if(!resultMessage.empty())
MWBase::Environment::get().getWindowManager()->messageBox(resultMessage);
if(!resultSound.empty())
MWBase::Environment::get().getSoundManager()->playSound3D(target,
resultSound, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Normal);
MWBase::Environment::get().getSoundManager()->playSound3D(target, resultSound,
1.0f, 1.0f);
}
else if (ammunition)
{

@ -770,8 +770,9 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g
mSoundIds[type] = csi->getClass().getSound(*csi);
if (!mSoundIds[type].empty())
{
MWBase::Environment::get().getSoundManager()->playSound3D(mPtr, mSoundIds[type], 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Loop);
MWBase::Environment::get().getSoundManager()->playSound3D(mPtr, mSoundIds[type],
1.0f, 1.0f, MWSound::Type::Sfx, MWSound::PlayMode::Loop
);
}
}
}

@ -108,7 +108,7 @@ namespace MWScript
std::string sound = runtime.getStringLiteral (runtime[0].mInteger);
runtime.pop();
MWBase::Environment::get().getSoundManager()->playSound(sound, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoEnv);
MWBase::Environment::get().getSoundManager()->playSound(sound, 1.0, 1.0, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv);
}
};
@ -127,7 +127,7 @@ namespace MWScript
Interpreter::Type_Float pitch = runtime[0].mFloat;
runtime.pop();
MWBase::Environment::get().getSoundManager()->playSound(sound, volume, pitch, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoEnv);
MWBase::Environment::get().getSoundManager()->playSound(sound, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv);
}
};
@ -148,9 +148,9 @@ namespace MWScript
runtime.pop();
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, sound, 1.0, 1.0,
MWBase::SoundManager::Play_TypeSfx,
mLoop ? MWBase::SoundManager::Play_LoopRemoveAtDistance
: MWBase::SoundManager::Play_Normal);
MWSound::Type::Sfx,
mLoop ? MWSound::PlayMode::LoopRemoveAtDistance
: MWSound::PlayMode::Normal);
}
};
@ -177,9 +177,9 @@ namespace MWScript
runtime.pop();
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, sound, volume, pitch,
MWBase::SoundManager::Play_TypeSfx,
mLoop ? MWBase::SoundManager::Play_LoopRemoveAtDistance
: MWBase::SoundManager::Play_Normal);
MWSound::Type::Sfx,
mLoop ? MWSound::PlayMode::LoopRemoveAtDistance
: MWSound::PlayMode::Normal);
}
};

@ -0,0 +1,466 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 2008 by authors.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#ifndef AL_ALEXT_H
#define AL_ALEXT_H
#include <stddef.h>
/* Define int64_t and uint64_t types */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#include <inttypes.h>
#elif defined(_WIN32) && defined(__GNUC__)
#include <stdint.h>
#elif defined(_WIN32)
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
/* Fallback if nothing above works */
#include <inttypes.h>
#endif
#include "alc.h"
#include "al.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef AL_LOKI_IMA_ADPCM_format
#define AL_LOKI_IMA_ADPCM_format 1
#define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000
#define AL_FORMAT_IMA_ADPCM_STEREO16_EXT 0x10001
#endif
#ifndef AL_LOKI_WAVE_format
#define AL_LOKI_WAVE_format 1
#define AL_FORMAT_WAVE_EXT 0x10002
#endif
#ifndef AL_EXT_vorbis
#define AL_EXT_vorbis 1
#define AL_FORMAT_VORBIS_EXT 0x10003
#endif
#ifndef AL_LOKI_quadriphonic
#define AL_LOKI_quadriphonic 1
#define AL_FORMAT_QUAD8_LOKI 0x10004
#define AL_FORMAT_QUAD16_LOKI 0x10005
#endif
#ifndef AL_EXT_float32
#define AL_EXT_float32 1
#define AL_FORMAT_MONO_FLOAT32 0x10010
#define AL_FORMAT_STEREO_FLOAT32 0x10011
#endif
#ifndef AL_EXT_double
#define AL_EXT_double 1
#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012
#define AL_FORMAT_STEREO_DOUBLE_EXT 0x10013
#endif
#ifndef AL_EXT_MULAW
#define AL_EXT_MULAW 1
#define AL_FORMAT_MONO_MULAW_EXT 0x10014
#define AL_FORMAT_STEREO_MULAW_EXT 0x10015
#endif
#ifndef AL_EXT_ALAW
#define AL_EXT_ALAW 1
#define AL_FORMAT_MONO_ALAW_EXT 0x10016
#define AL_FORMAT_STEREO_ALAW_EXT 0x10017
#endif
#ifndef ALC_LOKI_audio_channel
#define ALC_LOKI_audio_channel 1
#define ALC_CHAN_MAIN_LOKI 0x500001
#define ALC_CHAN_PCM_LOKI 0x500002
#define ALC_CHAN_CD_LOKI 0x500003
#endif
#ifndef AL_EXT_MCFORMATS
#define AL_EXT_MCFORMATS 1
#define AL_FORMAT_QUAD8 0x1204
#define AL_FORMAT_QUAD16 0x1205
#define AL_FORMAT_QUAD32 0x1206
#define AL_FORMAT_REAR8 0x1207
#define AL_FORMAT_REAR16 0x1208
#define AL_FORMAT_REAR32 0x1209
#define AL_FORMAT_51CHN8 0x120A
#define AL_FORMAT_51CHN16 0x120B
#define AL_FORMAT_51CHN32 0x120C
#define AL_FORMAT_61CHN8 0x120D
#define AL_FORMAT_61CHN16 0x120E
#define AL_FORMAT_61CHN32 0x120F
#define AL_FORMAT_71CHN8 0x1210
#define AL_FORMAT_71CHN16 0x1211
#define AL_FORMAT_71CHN32 0x1212
#endif
#ifndef AL_EXT_MULAW_MCFORMATS
#define AL_EXT_MULAW_MCFORMATS 1
#define AL_FORMAT_MONO_MULAW 0x10014
#define AL_FORMAT_STEREO_MULAW 0x10015
#define AL_FORMAT_QUAD_MULAW 0x10021
#define AL_FORMAT_REAR_MULAW 0x10022
#define AL_FORMAT_51CHN_MULAW 0x10023
#define AL_FORMAT_61CHN_MULAW 0x10024
#define AL_FORMAT_71CHN_MULAW 0x10025
#endif
#ifndef AL_EXT_IMA4
#define AL_EXT_IMA4 1
#define AL_FORMAT_MONO_IMA4 0x1300
#define AL_FORMAT_STEREO_IMA4 0x1301
#endif
#ifndef AL_EXT_STATIC_BUFFER
#define AL_EXT_STATIC_BUFFER 1
typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq);
#endif
#endif
#ifndef ALC_EXT_EFX
#define ALC_EXT_EFX 1
#include "efx.h"
#endif
#ifndef ALC_EXT_disconnect
#define ALC_EXT_disconnect 1
#define ALC_CONNECTED 0x313
#endif
#ifndef ALC_EXT_thread_local_context
#define ALC_EXT_thread_local_context 1
typedef ALCboolean (ALC_APIENTRY*PFNALCSETTHREADCONTEXTPROC)(ALCcontext *context);
typedef ALCcontext* (ALC_APIENTRY*PFNALCGETTHREADCONTEXTPROC)(void);
#ifdef AL_ALEXT_PROTOTYPES
ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context);
ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void);
#endif
#endif
#ifndef AL_EXT_source_distance_model
#define AL_EXT_source_distance_model 1
#define AL_SOURCE_DISTANCE_MODEL 0x200
#endif
#ifndef AL_SOFT_buffer_sub_data
#define AL_SOFT_buffer_sub_data 1
#define AL_BYTE_RW_OFFSETS_SOFT 0x1031
#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032
typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length);
#endif
#endif
#ifndef AL_SOFT_loop_points
#define AL_SOFT_loop_points 1
#define AL_LOOP_POINTS_SOFT 0x2015
#endif
#ifndef AL_EXT_FOLDBACK
#define AL_EXT_FOLDBACK 1
#define AL_EXT_FOLDBACK_NAME "AL_EXT_FOLDBACK"
#define AL_FOLDBACK_EVENT_BLOCK 0x4112
#define AL_FOLDBACK_EVENT_START 0x4111
#define AL_FOLDBACK_EVENT_STOP 0x4113
#define AL_FOLDBACK_MODE_MONO 0x4101
#define AL_FOLDBACK_MODE_STEREO 0x4102
typedef void (AL_APIENTRY*LPALFOLDBACKCALLBACK)(ALenum,ALsizei);
typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTART)(ALenum,ALsizei,ALsizei,ALfloat*,LPALFOLDBACKCALLBACK);
typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTOP)(void);
#ifdef AL_ALEXT_PROTOTYPES
AL_API void AL_APIENTRY alRequestFoldbackStart(ALenum mode,ALsizei count,ALsizei length,ALfloat *mem,LPALFOLDBACKCALLBACK callback);
AL_API void AL_APIENTRY alRequestFoldbackStop(void);
#endif
#endif
#ifndef ALC_EXT_DEDICATED
#define ALC_EXT_DEDICATED 1
#define AL_DEDICATED_GAIN 0x0001
#define AL_EFFECT_DEDICATED_DIALOGUE 0x9001
#define AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT 0x9000
#endif
#ifndef AL_SOFT_buffer_samples
#define AL_SOFT_buffer_samples 1
/* Channel configurations */
#define AL_MONO_SOFT 0x1500
#define AL_STEREO_SOFT 0x1501
#define AL_REAR_SOFT 0x1502
#define AL_QUAD_SOFT 0x1503
#define AL_5POINT1_SOFT 0x1504
#define AL_6POINT1_SOFT 0x1505
#define AL_7POINT1_SOFT 0x1506
/* Sample types */
#define AL_BYTE_SOFT 0x1400
#define AL_UNSIGNED_BYTE_SOFT 0x1401
#define AL_SHORT_SOFT 0x1402
#define AL_UNSIGNED_SHORT_SOFT 0x1403
#define AL_INT_SOFT 0x1404
#define AL_UNSIGNED_INT_SOFT 0x1405
#define AL_FLOAT_SOFT 0x1406
#define AL_DOUBLE_SOFT 0x1407
#define AL_BYTE3_SOFT 0x1408
#define AL_UNSIGNED_BYTE3_SOFT 0x1409
/* Storage formats */
#define AL_MONO8_SOFT 0x1100
#define AL_MONO16_SOFT 0x1101
#define AL_MONO32F_SOFT 0x10010
#define AL_STEREO8_SOFT 0x1102
#define AL_STEREO16_SOFT 0x1103
#define AL_STEREO32F_SOFT 0x10011
#define AL_QUAD8_SOFT 0x1204
#define AL_QUAD16_SOFT 0x1205
#define AL_QUAD32F_SOFT 0x1206
#define AL_REAR8_SOFT 0x1207
#define AL_REAR16_SOFT 0x1208
#define AL_REAR32F_SOFT 0x1209
#define AL_5POINT1_8_SOFT 0x120A
#define AL_5POINT1_16_SOFT 0x120B
#define AL_5POINT1_32F_SOFT 0x120C
#define AL_6POINT1_8_SOFT 0x120D
#define AL_6POINT1_16_SOFT 0x120E
#define AL_6POINT1_32F_SOFT 0x120F
#define AL_7POINT1_8_SOFT 0x1210
#define AL_7POINT1_16_SOFT 0x1211
#define AL_7POINT1_32F_SOFT 0x1212
/* Buffer attributes */
#define AL_INTERNAL_FORMAT_SOFT 0x2008
#define AL_BYTE_LENGTH_SOFT 0x2009
#define AL_SAMPLE_LENGTH_SOFT 0x200A
#define AL_SEC_LENGTH_SOFT 0x200B
typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*);
typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*);
typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*);
typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum);
#ifdef AL_ALEXT_PROTOTYPES
AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data);
AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data);
AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data);
AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format);
#endif
#endif
#ifndef AL_SOFT_direct_channels
#define AL_SOFT_direct_channels 1
#define AL_DIRECT_CHANNELS_SOFT 0x1033
#endif
#ifndef ALC_SOFT_loopback
#define ALC_SOFT_loopback 1
#define ALC_FORMAT_CHANNELS_SOFT 0x1990
#define ALC_FORMAT_TYPE_SOFT 0x1991
/* Sample types */
#define ALC_BYTE_SOFT 0x1400
#define ALC_UNSIGNED_BYTE_SOFT 0x1401
#define ALC_SHORT_SOFT 0x1402
#define ALC_UNSIGNED_SHORT_SOFT 0x1403
#define ALC_INT_SOFT 0x1404
#define ALC_UNSIGNED_INT_SOFT 0x1405
#define ALC_FLOAT_SOFT 0x1406
/* Channel configurations */
#define ALC_MONO_SOFT 0x1500
#define ALC_STEREO_SOFT 0x1501
#define ALC_QUAD_SOFT 0x1503
#define ALC_5POINT1_SOFT 0x1504
#define ALC_6POINT1_SOFT 0x1505
#define ALC_7POINT1_SOFT 0x1506
typedef ALCdevice* (ALC_APIENTRY*LPALCLOOPBACKOPENDEVICESOFT)(const ALCchar*);
typedef ALCboolean (ALC_APIENTRY*LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice*,ALCsizei,ALCenum,ALCenum);
typedef void (ALC_APIENTRY*LPALCRENDERSAMPLESSOFT)(ALCdevice*,ALCvoid*,ALCsizei);
#ifdef AL_ALEXT_PROTOTYPES
ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName);
ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type);
ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
#endif
#endif
#ifndef AL_EXT_STEREO_ANGLES
#define AL_EXT_STEREO_ANGLES 1
#define AL_STEREO_ANGLES 0x1030
#endif
#ifndef AL_EXT_SOURCE_RADIUS
#define AL_EXT_SOURCE_RADIUS 1
#define AL_SOURCE_RADIUS 0x1031
#endif
#ifndef AL_SOFT_source_latency
#define AL_SOFT_source_latency 1
#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200
#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201
typedef int64_t ALint64SOFT;
typedef uint64_t ALuint64SOFT;
typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble);
typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble);
typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*);
typedef void (AL_APIENTRY*LPALGETSOURCEDSOFT)(ALuint,ALenum,ALdouble*);
typedef void (AL_APIENTRY*LPALGETSOURCE3DSOFT)(ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*);
typedef void (AL_APIENTRY*LPALGETSOURCEDVSOFT)(ALuint,ALenum,ALdouble*);
typedef void (AL_APIENTRY*LPALSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT);
typedef void (AL_APIENTRY*LPALSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT);
typedef void (AL_APIENTRY*LPALSOURCEI64VSOFT)(ALuint,ALenum,const ALint64SOFT*);
typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*);
typedef void (AL_APIENTRY*LPALGETSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*);
typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*);
#ifdef AL_ALEXT_PROTOTYPES
AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value);
AL_API void AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3);
AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values);
AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value);
AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3);
AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values);
AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value);
AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3);
AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values);
AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value);
AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3);
AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values);
#endif
#endif
#ifndef ALC_EXT_DEFAULT_FILTER_ORDER
#define ALC_EXT_DEFAULT_FILTER_ORDER 1
#define ALC_DEFAULT_FILTER_ORDER 0x1100
#endif
#ifndef AL_SOFT_deferred_updates
#define AL_SOFT_deferred_updates 1
#define AL_DEFERRED_UPDATES_SOFT 0xC002
typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void);
typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void);
AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void);
#endif
#endif
#ifndef AL_SOFT_block_alignment
#define AL_SOFT_block_alignment 1
#define AL_UNPACK_BLOCK_ALIGNMENT_SOFT 0x200C
#define AL_PACK_BLOCK_ALIGNMENT_SOFT 0x200D
#endif
#ifndef AL_SOFT_MSADPCM
#define AL_SOFT_MSADPCM 1
#define AL_FORMAT_MONO_MSADPCM_SOFT 0x1302
#define AL_FORMAT_STEREO_MSADPCM_SOFT 0x1303
#endif
#ifndef AL_SOFT_source_length
#define AL_SOFT_source_length 1
/*#define AL_BYTE_LENGTH_SOFT 0x2009*/
/*#define AL_SAMPLE_LENGTH_SOFT 0x200A*/
/*#define AL_SEC_LENGTH_SOFT 0x200B*/
#endif
#ifndef ALC_SOFT_pause_device
#define ALC_SOFT_pause_device 1
typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device);
typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device);
#ifdef AL_ALEXT_PROTOTYPES
ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device);
ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device);
#endif
#endif
#ifndef AL_EXT_BFORMAT
#define AL_EXT_BFORMAT 1
#define AL_FORMAT_BFORMAT2D_8 0x20021
#define AL_FORMAT_BFORMAT2D_16 0x20022
#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023
#define AL_FORMAT_BFORMAT3D_8 0x20031
#define AL_FORMAT_BFORMAT3D_16 0x20032
#define AL_FORMAT_BFORMAT3D_FLOAT32 0x20033
#endif
#ifndef AL_EXT_MULAW_BFORMAT
#define AL_EXT_MULAW_BFORMAT 1
#define AL_FORMAT_BFORMAT2D_MULAW 0x10031
#define AL_FORMAT_BFORMAT3D_MULAW 0x10032
#endif
#ifndef ALC_SOFT_HRTF
#define ALC_SOFT_HRTF 1
#define ALC_HRTF_SOFT 0x1992
#define ALC_DONT_CARE_SOFT 0x0002
#define ALC_HRTF_STATUS_SOFT 0x1993
#define ALC_HRTF_DISABLED_SOFT 0x0000
#define ALC_HRTF_ENABLED_SOFT 0x0001
#define ALC_HRTF_DENIED_SOFT 0x0002
#define ALC_HRTF_REQUIRED_SOFT 0x0003
#define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004
#define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005
#define ALC_NUM_HRTF_SPECIFIERS_SOFT 0x1994
#define ALC_HRTF_SPECIFIER_SOFT 0x1995
#define ALC_HRTF_ID_SOFT 0x1996
typedef const ALCchar* (ALC_APIENTRY*LPALCGETSTRINGISOFT)(ALCdevice *device, ALCenum paramName, ALCsizei index);
typedef ALCboolean (ALC_APIENTRY*LPALCRESETDEVICESOFT)(ALCdevice *device, const ALCint *attribs);
#ifdef AL_ALEXT_PROTOTYPES
ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index);
ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs);
#endif
#endif
#ifndef AL_SOFT_gain_clamp_ex
#define AL_SOFT_gain_clamp_ex 1
#define AL_GAIN_LIMIT_SOFT 0x200E
#endif
#ifndef AL_SOFT_source_resampler
#define AL_SOFT_source_resampler
#define AL_NUM_RESAMPLERS_SOFT 0x1210
#define AL_DEFAULT_RESAMPLER_SOFT 0x1211
#define AL_SOURCE_RESAMPLER_SOFT 0x1212
#define AL_RESAMPLER_NAME_SOFT 0x1213
typedef const ALchar* (AL_APIENTRY*LPALGETSTRINGISOFT)(ALenum pname, ALsizei index);
#ifdef AL_ALEXT_PROTOTYPES
AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index);
#endif
#endif
#ifndef AL_SOFT_source_spatialize
#define AL_SOFT_source_spatialize
#define AL_SOURCE_SPATIALIZE_SOFT 0x1214
#define AL_AUTO_SOFT 0x0002
#endif
#ifndef ALC_SOFT_output_limiter
#define ALC_SOFT_output_limiter
#define ALC_OUTPUT_LIMITER_SOFT 0x199A
#endif
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,402 @@
/* Reverb presets for EFX */
#ifndef EFX_PRESETS_H
#define EFX_PRESETS_H
#ifndef EFXEAXREVERBPROPERTIES_DEFINED
#define EFXEAXREVERBPROPERTIES_DEFINED
typedef struct {
float flDensity;
float flDiffusion;
float flGain;
float flGainHF;
float flGainLF;
float flDecayTime;
float flDecayHFRatio;
float flDecayLFRatio;
float flReflectionsGain;
float flReflectionsDelay;
float flReflectionsPan[3];
float flLateReverbGain;
float flLateReverbDelay;
float flLateReverbPan[3];
float flEchoTime;
float flEchoDepth;
float flModulationTime;
float flModulationDepth;
float flAirAbsorptionGainHF;
float flHFReference;
float flLFReference;
float flRoomRolloffFactor;
int iDecayHFLimit;
} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
#endif
/* Default Presets */
#define EFX_REVERB_PRESET_GENERIC \
{ 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_PADDEDCELL \
{ 0.1715f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.1700f, 0.1000f, 1.0000f, 0.2500f, 0.0010f, { 0.0000f, 0.0000f, 0.0000f }, 1.2691f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_ROOM \
{ 0.4287f, 1.0000f, 0.3162f, 0.5929f, 1.0000f, 0.4000f, 0.8300f, 1.0000f, 0.1503f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.0629f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_BATHROOM \
{ 0.1715f, 1.0000f, 0.3162f, 0.2512f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.6531f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 3.2734f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_LIVINGROOM \
{ 0.9766f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.5000f, 0.1000f, 1.0000f, 0.2051f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2805f, 0.0040f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_STONEROOM \
{ 1.0000f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 2.3100f, 0.6400f, 1.0000f, 0.4411f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1003f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_AUDITORIUM \
{ 1.0000f, 1.0000f, 0.3162f, 0.5781f, 1.0000f, 4.3200f, 0.5900f, 1.0000f, 0.4032f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7170f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CONCERTHALL \
{ 1.0000f, 1.0000f, 0.3162f, 0.5623f, 1.0000f, 3.9200f, 0.7000f, 1.0000f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.9977f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CAVE \
{ 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 2.9100f, 1.3000f, 1.0000f, 0.5000f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.7063f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_ARENA \
{ 1.0000f, 1.0000f, 0.3162f, 0.4477f, 1.0000f, 7.2400f, 0.3300f, 1.0000f, 0.2612f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.0186f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_HANGAR \
{ 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 10.0500f, 0.2300f, 1.0000f, 0.5000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2560f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CARPETEDHALLWAY \
{ 0.4287f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 0.3000f, 0.1000f, 1.0000f, 0.1215f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.1531f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_HALLWAY \
{ 0.3645f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 1.4900f, 0.5900f, 1.0000f, 0.2458f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.6615f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_STONECORRIDOR \
{ 1.0000f, 1.0000f, 0.3162f, 0.7612f, 1.0000f, 2.7000f, 0.7900f, 1.0000f, 0.2472f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 1.5758f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_ALLEY \
{ 1.0000f, 0.3000f, 0.3162f, 0.7328f, 1.0000f, 1.4900f, 0.8600f, 1.0000f, 0.2500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.9954f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.9500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_FOREST \
{ 1.0000f, 0.3000f, 0.3162f, 0.0224f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.0525f, 0.1620f, { 0.0000f, 0.0000f, 0.0000f }, 0.7682f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CITY \
{ 1.0000f, 0.5000f, 0.3162f, 0.3981f, 1.0000f, 1.4900f, 0.6700f, 1.0000f, 0.0730f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1427f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_MOUNTAINS \
{ 1.0000f, 0.2700f, 0.3162f, 0.0562f, 1.0000f, 1.4900f, 0.2100f, 1.0000f, 0.0407f, 0.3000f, { 0.0000f, 0.0000f, 0.0000f }, 0.1919f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_QUARRY \
{ 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0000f, 0.0610f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.7000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_PLAIN \
{ 1.0000f, 0.2100f, 0.3162f, 0.1000f, 1.0000f, 1.4900f, 0.5000f, 1.0000f, 0.0585f, 0.1790f, { 0.0000f, 0.0000f, 0.0000f }, 0.1089f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_PARKINGLOT \
{ 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 1.6500f, 1.5000f, 1.0000f, 0.2082f, 0.0080f, { 0.0000f, 0.0000f, 0.0000f }, 0.2652f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_SEWERPIPE \
{ 0.3071f, 0.8000f, 0.3162f, 0.3162f, 1.0000f, 2.8100f, 0.1400f, 1.0000f, 1.6387f, 0.0140f, { 0.0000f, 0.0000f, 0.0000f }, 3.2471f, 0.0210f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_UNDERWATER \
{ 0.3645f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 1.4900f, 0.1000f, 1.0000f, 0.5963f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 7.0795f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 1.1800f, 0.3480f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_DRUGGED \
{ 0.4287f, 0.5000f, 0.3162f, 1.0000f, 1.0000f, 8.3900f, 1.3900f, 1.0000f, 0.8760f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 3.1081f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_DIZZY \
{ 0.3645f, 0.6000f, 0.3162f, 0.6310f, 1.0000f, 17.2300f, 0.5600f, 1.0000f, 0.1392f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4937f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.8100f, 0.3100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_PSYCHOTIC \
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
/* Castle Presets */
#define EFX_REVERB_PRESET_CASTLE_SMALLROOM \
{ 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 1.2200f, 0.8300f, 0.3100f, 0.8913f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CASTLE_SHORTPASSAGE \
{ 1.0000f, 0.8900f, 0.3162f, 0.3162f, 0.1000f, 2.3200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CASTLE_MEDIUMROOM \
{ 1.0000f, 0.9300f, 0.3162f, 0.2818f, 0.1000f, 2.0400f, 0.8300f, 0.4600f, 0.6310f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1550f, 0.0300f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CASTLE_LARGEROOM \
{ 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.1259f, 2.5300f, 0.8300f, 0.5000f, 0.4467f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1850f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CASTLE_LONGPASSAGE \
{ 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 3.4200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CASTLE_HALL \
{ 1.0000f, 0.8100f, 0.3162f, 0.2818f, 0.1778f, 3.1400f, 0.7900f, 0.6200f, 0.1778f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CASTLE_CUPBOARD \
{ 1.0000f, 0.8900f, 0.3162f, 0.2818f, 0.1000f, 0.6700f, 0.8700f, 0.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 3.5481f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CASTLE_COURTYARD \
{ 1.0000f, 0.4200f, 0.3162f, 0.4467f, 0.1995f, 2.1300f, 0.6100f, 0.2300f, 0.2239f, 0.1600f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3700f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_CASTLE_ALCOVE \
{ 1.0000f, 0.8900f, 0.3162f, 0.5012f, 0.1000f, 1.6400f, 0.8700f, 0.3100f, 1.0000f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 }
/* Factory Presets */
#define EFX_REVERB_PRESET_FACTORY_SMALLROOM \
{ 0.3645f, 0.8200f, 0.3162f, 0.7943f, 0.5012f, 1.7200f, 0.6500f, 1.3100f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.1190f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_FACTORY_SHORTPASSAGE \
{ 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 2.5300f, 0.6500f, 1.3100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_FACTORY_MEDIUMROOM \
{ 0.4287f, 0.8200f, 0.2512f, 0.7943f, 0.5012f, 2.7600f, 0.6500f, 1.3100f, 0.2818f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1740f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_FACTORY_LARGEROOM \
{ 0.4287f, 0.7500f, 0.2512f, 0.7079f, 0.6310f, 4.2400f, 0.5100f, 1.3100f, 0.1778f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2310f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_FACTORY_LONGPASSAGE \
{ 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 4.0600f, 0.6500f, 1.3100f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_FACTORY_HALL \
{ 0.4287f, 0.7500f, 0.3162f, 0.7079f, 0.6310f, 7.4300f, 0.5100f, 1.3100f, 0.0631f, 0.0730f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_FACTORY_CUPBOARD \
{ 0.3071f, 0.6300f, 0.2512f, 0.7943f, 0.5012f, 0.4900f, 0.6500f, 1.3100f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.1070f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_FACTORY_COURTYARD \
{ 0.3071f, 0.5700f, 0.3162f, 0.3162f, 0.6310f, 2.3200f, 0.2900f, 0.5600f, 0.2239f, 0.1400f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2900f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_FACTORY_ALCOVE \
{ 0.3645f, 0.5900f, 0.2512f, 0.7943f, 0.5012f, 3.1400f, 0.6500f, 1.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1140f, 0.1000f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 }
/* Ice Palace Presets */
#define EFX_REVERB_PRESET_ICEPALACE_SMALLROOM \
{ 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 1.5100f, 1.5300f, 0.2700f, 0.8913f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1640f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_ICEPALACE_SHORTPASSAGE \
{ 1.0000f, 0.7500f, 0.3162f, 0.5623f, 0.2818f, 1.7900f, 1.4600f, 0.2800f, 0.5012f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_ICEPALACE_MEDIUMROOM \
{ 1.0000f, 0.8700f, 0.3162f, 0.5623f, 0.4467f, 2.2200f, 1.5300f, 0.3200f, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_ICEPALACE_LARGEROOM \
{ 1.0000f, 0.8100f, 0.3162f, 0.5623f, 0.4467f, 3.1400f, 1.5300f, 0.3200f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_ICEPALACE_LONGPASSAGE \
{ 1.0000f, 0.7700f, 0.3162f, 0.5623f, 0.3981f, 3.0100f, 1.4600f, 0.2800f, 0.7943f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.0400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_ICEPALACE_HALL \
{ 1.0000f, 0.7600f, 0.3162f, 0.4467f, 0.5623f, 5.4900f, 1.5300f, 0.3800f, 0.1122f, 0.0540f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0520f, { 0.0000f, 0.0000f, 0.0000f }, 0.2260f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_ICEPALACE_CUPBOARD \
{ 1.0000f, 0.8300f, 0.3162f, 0.5012f, 0.2239f, 0.7600f, 1.5300f, 0.2600f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1430f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_ICEPALACE_COURTYARD \
{ 1.0000f, 0.5900f, 0.3162f, 0.2818f, 0.3162f, 2.0400f, 1.2000f, 0.3800f, 0.3162f, 0.1730f, { 0.0000f, 0.0000f, 0.0000f }, 0.3162f, 0.0430f, { 0.0000f, 0.0000f, 0.0000f }, 0.2350f, 0.4800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_ICEPALACE_ALCOVE \
{ 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 2.7600f, 1.4600f, 0.2800f, 1.1220f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1610f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 }
/* Space Station Presets */
#define EFX_REVERB_PRESET_SPACESTATION_SMALLROOM \
{ 0.2109f, 0.7000f, 0.3162f, 0.7079f, 0.8913f, 1.7200f, 0.8200f, 0.5500f, 0.7943f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 0.1880f, 0.2600f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPACESTATION_SHORTPASSAGE \
{ 0.2109f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 3.5700f, 0.5000f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1720f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM \
{ 0.2109f, 0.7500f, 0.3162f, 0.6310f, 0.8913f, 3.0100f, 0.5000f, 0.5500f, 0.3981f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2090f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPACESTATION_LARGEROOM \
{ 0.3645f, 0.8100f, 0.3162f, 0.6310f, 0.8913f, 3.8900f, 0.3800f, 0.6100f, 0.3162f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2330f, 0.2800f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPACESTATION_LONGPASSAGE \
{ 0.4287f, 0.8200f, 0.3162f, 0.6310f, 0.8913f, 4.6200f, 0.6200f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPACESTATION_HALL \
{ 0.4287f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 7.1100f, 0.3800f, 0.6100f, 0.1778f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2500f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPACESTATION_CUPBOARD \
{ 0.1715f, 0.5600f, 0.3162f, 0.7079f, 0.8913f, 0.7900f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1810f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPACESTATION_ALCOVE \
{ 0.2109f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.1600f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1920f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 }
/* Wooden Galleon Presets */
#define EFX_REVERB_PRESET_WOODEN_SMALLROOM \
{ 1.0000f, 1.0000f, 0.3162f, 0.1122f, 0.3162f, 0.7900f, 0.3200f, 0.8700f, 1.0000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_WOODEN_SHORTPASSAGE \
{ 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.7500f, 0.5000f, 0.8700f, 0.8913f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_WOODEN_MEDIUMROOM \
{ 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.2818f, 1.4700f, 0.4200f, 0.8200f, 0.8913f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_WOODEN_LARGEROOM \
{ 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.2818f, 2.6500f, 0.3300f, 0.8200f, 0.8913f, 0.0660f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_WOODEN_LONGPASSAGE \
{ 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.3162f, 1.9900f, 0.4000f, 0.7900f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4467f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_WOODEN_HALL \
{ 1.0000f, 1.0000f, 0.3162f, 0.0794f, 0.2818f, 3.4500f, 0.3000f, 0.8200f, 0.8913f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_WOODEN_CUPBOARD \
{ 1.0000f, 1.0000f, 0.3162f, 0.1413f, 0.3162f, 0.5600f, 0.4600f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_WOODEN_COURTYARD \
{ 1.0000f, 0.6500f, 0.3162f, 0.0794f, 0.3162f, 1.7900f, 0.3500f, 0.7900f, 0.5623f, 0.1230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_WOODEN_ALCOVE \
{ 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.2200f, 0.6200f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 }
/* Sports Presets */
#define EFX_REVERB_PRESET_SPORT_EMPTYSTADIUM \
{ 1.0000f, 1.0000f, 0.3162f, 0.4467f, 0.7943f, 6.2600f, 0.5100f, 1.1000f, 0.0631f, 0.1830f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPORT_SQUASHCOURT \
{ 1.0000f, 0.7500f, 0.3162f, 0.3162f, 0.7943f, 2.2200f, 0.9100f, 1.1600f, 0.4467f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1260f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPORT_SMALLSWIMMINGPOOL \
{ 1.0000f, 0.7000f, 0.3162f, 0.7943f, 0.8913f, 2.7600f, 1.2500f, 1.1400f, 0.6310f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_SPORT_LARGESWIMMINGPOOL \
{ 1.0000f, 0.8200f, 0.3162f, 0.7943f, 1.0000f, 5.4900f, 1.3100f, 1.1400f, 0.4467f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2220f, 0.5500f, 1.1590f, 0.2100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_SPORT_GYMNASIUM \
{ 1.0000f, 0.8100f, 0.3162f, 0.4467f, 0.8913f, 3.1400f, 1.0600f, 1.3500f, 0.3981f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0450f, { 0.0000f, 0.0000f, 0.0000f }, 0.1460f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPORT_FULLSTADIUM \
{ 1.0000f, 1.0000f, 0.3162f, 0.0708f, 0.7943f, 5.2500f, 0.1700f, 0.8000f, 0.1000f, 0.1880f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SPORT_STADIUMTANNOY \
{ 1.0000f, 0.7800f, 0.3162f, 0.5623f, 0.5012f, 2.5300f, 0.8800f, 0.6800f, 0.2818f, 0.2300f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
/* Prefab Presets */
#define EFX_REVERB_PRESET_PREFAB_WORKSHOP \
{ 0.4287f, 1.0000f, 0.3162f, 0.1413f, 0.3981f, 0.7600f, 1.0000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_PREFAB_SCHOOLROOM \
{ 0.4022f, 0.6900f, 0.3162f, 0.6310f, 0.5012f, 0.9800f, 0.4500f, 0.1800f, 1.4125f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_PREFAB_PRACTISEROOM \
{ 0.4022f, 0.8700f, 0.3162f, 0.3981f, 0.5012f, 1.1200f, 0.5600f, 0.1800f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_PREFAB_OUTHOUSE \
{ 1.0000f, 0.8200f, 0.3162f, 0.1122f, 0.1585f, 1.3800f, 0.3800f, 0.3500f, 0.8913f, 0.0240f, { 0.0000f, 0.0000f, -0.0000f }, 0.6310f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.1210f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_PREFAB_CARAVAN \
{ 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.1259f, 0.4300f, 1.5000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
/* Dome and Pipe Presets */
#define EFX_REVERB_PRESET_DOME_TOMB \
{ 1.0000f, 0.7900f, 0.3162f, 0.3548f, 0.2239f, 4.1800f, 0.2100f, 0.1000f, 0.3868f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 1.6788f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_PIPE_SMALL \
{ 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 5.0400f, 0.1000f, 0.1000f, 0.5012f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 2.5119f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_DOME_SAINTPAULS \
{ 1.0000f, 0.8700f, 0.3162f, 0.3548f, 0.2239f, 10.4800f, 0.1900f, 0.1000f, 0.1778f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0420f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_PIPE_LONGTHIN \
{ 0.2560f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 9.2100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_PIPE_LARGE \
{ 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 8.4500f, 0.1000f, 0.1000f, 0.3981f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_PIPE_RESONANT \
{ 0.1373f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 6.8100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 }
/* Outdoors Presets */
#define EFX_REVERB_PRESET_OUTDOORS_BACKYARD \
{ 1.0000f, 0.4500f, 0.3162f, 0.2512f, 0.5012f, 1.1200f, 0.3400f, 0.4600f, 0.4467f, 0.0690f, { 0.0000f, 0.0000f, -0.0000f }, 0.7079f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_OUTDOORS_ROLLINGPLAINS \
{ 1.0000f, 0.0000f, 0.3162f, 0.0112f, 0.6310f, 2.1300f, 0.2100f, 0.4600f, 0.1778f, 0.3000f, { 0.0000f, 0.0000f, -0.0000f }, 0.4467f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_OUTDOORS_DEEPCANYON \
{ 1.0000f, 0.7400f, 0.3162f, 0.1778f, 0.6310f, 3.8900f, 0.2100f, 0.4600f, 0.3162f, 0.2230f, { 0.0000f, 0.0000f, -0.0000f }, 0.3548f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_OUTDOORS_CREEK \
{ 1.0000f, 0.3500f, 0.3162f, 0.1778f, 0.5012f, 2.1300f, 0.2100f, 0.4600f, 0.3981f, 0.1150f, { 0.0000f, 0.0000f, -0.0000f }, 0.1995f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_OUTDOORS_VALLEY \
{ 1.0000f, 0.2800f, 0.3162f, 0.0282f, 0.1585f, 2.8800f, 0.2600f, 0.3500f, 0.1413f, 0.2630f, { 0.0000f, 0.0000f, -0.0000f }, 0.3981f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
/* Mood Presets */
#define EFX_REVERB_PRESET_MOOD_HEAVEN \
{ 1.0000f, 0.9400f, 0.3162f, 0.7943f, 0.4467f, 5.0400f, 1.1200f, 0.5600f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0800f, 2.7420f, 0.0500f, 0.9977f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_MOOD_HELL \
{ 1.0000f, 0.5700f, 0.3162f, 0.3548f, 0.4467f, 3.5700f, 0.4900f, 2.0000f, 0.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1100f, 0.0400f, 2.1090f, 0.5200f, 0.9943f, 5000.0000f, 139.5000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_MOOD_MEMORY \
{ 1.0000f, 0.8500f, 0.3162f, 0.6310f, 0.3548f, 4.0600f, 0.8200f, 0.5600f, 0.0398f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.4740f, 0.4500f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
/* Driving Presets */
#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \
{ 1.0000f, 0.0000f, 0.3162f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \
{ 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_DRIVING_INCAR_RACER \
{ 0.0832f, 0.8000f, 0.3162f, 1.0000f, 0.7943f, 0.1700f, 2.0000f, 0.4100f, 1.7783f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_DRIVING_INCAR_SPORTS \
{ 0.0832f, 0.8000f, 0.3162f, 0.6310f, 1.0000f, 0.1700f, 0.7500f, 0.4100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_DRIVING_INCAR_LUXURY \
{ 0.2560f, 1.0000f, 0.3162f, 0.1000f, 0.5012f, 0.1300f, 0.4100f, 0.4600f, 0.7943f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_DRIVING_FULLGRANDSTAND \
{ 1.0000f, 1.0000f, 0.3162f, 0.2818f, 0.6310f, 3.0100f, 1.3700f, 1.2800f, 0.3548f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.1778f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_DRIVING_EMPTYGRANDSTAND \
{ 1.0000f, 1.0000f, 0.3162f, 1.0000f, 0.7943f, 4.6200f, 1.7500f, 1.4000f, 0.2082f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_DRIVING_TUNNEL \
{ 1.0000f, 0.8100f, 0.3162f, 0.3981f, 0.8913f, 3.4200f, 0.9400f, 1.3100f, 0.7079f, 0.0510f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.0500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 155.3000f, 0.0000f, 0x1 }
/* City Presets */
#define EFX_REVERB_PRESET_CITY_STREETS \
{ 1.0000f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.7900f, 1.1200f, 0.9100f, 0.2818f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 0.1995f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CITY_SUBWAY \
{ 1.0000f, 0.7400f, 0.3162f, 0.7079f, 0.8913f, 3.0100f, 1.2300f, 0.9100f, 0.7079f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CITY_MUSEUM \
{ 1.0000f, 0.8200f, 0.3162f, 0.1778f, 0.1778f, 3.2800f, 1.4000f, 0.5700f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_CITY_LIBRARY \
{ 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.0891f, 2.7600f, 0.8900f, 0.4100f, 0.3548f, 0.0290f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 }
#define EFX_REVERB_PRESET_CITY_UNDERPASS \
{ 1.0000f, 0.8200f, 0.3162f, 0.4467f, 0.8913f, 3.5700f, 1.1200f, 0.9100f, 0.3981f, 0.0590f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1400f, 0.2500f, 0.0000f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CITY_ABANDONED \
{ 1.0000f, 0.6900f, 0.3162f, 0.7943f, 0.8913f, 3.2800f, 1.1700f, 0.9100f, 0.4467f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9966f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
/* Misc. Presets */
#define EFX_REVERB_PRESET_DUSTYROOM \
{ 0.3645f, 0.5600f, 0.3162f, 0.7943f, 0.7079f, 1.7900f, 0.3800f, 0.2100f, 0.5012f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0060f, { 0.0000f, 0.0000f, 0.0000f }, 0.2020f, 0.0500f, 0.2500f, 0.0000f, 0.9886f, 13046.0000f, 163.3000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_CHAPEL \
{ 1.0000f, 0.8400f, 0.3162f, 0.5623f, 1.0000f, 4.6200f, 0.6400f, 1.2300f, 0.4467f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.1100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_SMALLWATERROOM \
{ 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
#endif /* EFX_PRESETS_H */

@ -0,0 +1,761 @@
#ifndef AL_EFX_H
#define AL_EFX_H
#include "alc.h"
#include "al.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ALC_EXT_EFX_NAME "ALC_EXT_EFX"
#define ALC_EFX_MAJOR_VERSION 0x20001
#define ALC_EFX_MINOR_VERSION 0x20002
#define ALC_MAX_AUXILIARY_SENDS 0x20003
/* Listener properties. */
#define AL_METERS_PER_UNIT 0x20004
/* Source properties. */
#define AL_DIRECT_FILTER 0x20005
#define AL_AUXILIARY_SEND_FILTER 0x20006
#define AL_AIR_ABSORPTION_FACTOR 0x20007
#define AL_ROOM_ROLLOFF_FACTOR 0x20008
#define AL_CONE_OUTER_GAINHF 0x20009
#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A
#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B
#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C
/* Effect properties. */
/* Reverb effect parameters */
#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
/* EAX Reverb effect parameters */
#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
/* Chorus effect parameters */
#define AL_CHORUS_WAVEFORM 0x0001
#define AL_CHORUS_PHASE 0x0002
#define AL_CHORUS_RATE 0x0003
#define AL_CHORUS_DEPTH 0x0004
#define AL_CHORUS_FEEDBACK 0x0005
#define AL_CHORUS_DELAY 0x0006
/* Distortion effect parameters */
#define AL_DISTORTION_EDGE 0x0001
#define AL_DISTORTION_GAIN 0x0002
#define AL_DISTORTION_LOWPASS_CUTOFF 0x0003
#define AL_DISTORTION_EQCENTER 0x0004
#define AL_DISTORTION_EQBANDWIDTH 0x0005
/* Echo effect parameters */
#define AL_ECHO_DELAY 0x0001
#define AL_ECHO_LRDELAY 0x0002
#define AL_ECHO_DAMPING 0x0003
#define AL_ECHO_FEEDBACK 0x0004
#define AL_ECHO_SPREAD 0x0005
/* Flanger effect parameters */
#define AL_FLANGER_WAVEFORM 0x0001
#define AL_FLANGER_PHASE 0x0002
#define AL_FLANGER_RATE 0x0003
#define AL_FLANGER_DEPTH 0x0004
#define AL_FLANGER_FEEDBACK 0x0005
#define AL_FLANGER_DELAY 0x0006
/* Frequency shifter effect parameters */
#define AL_FREQUENCY_SHIFTER_FREQUENCY 0x0001
#define AL_FREQUENCY_SHIFTER_LEFT_DIRECTION 0x0002
#define AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION 0x0003
/* Vocal morpher effect parameters */
#define AL_VOCAL_MORPHER_PHONEMEA 0x0001
#define AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING 0x0002
#define AL_VOCAL_MORPHER_PHONEMEB 0x0003
#define AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING 0x0004
#define AL_VOCAL_MORPHER_WAVEFORM 0x0005
#define AL_VOCAL_MORPHER_RATE 0x0006
/* Pitchshifter effect parameters */
#define AL_PITCH_SHIFTER_COARSE_TUNE 0x0001
#define AL_PITCH_SHIFTER_FINE_TUNE 0x0002
/* Ringmodulator effect parameters */
#define AL_RING_MODULATOR_FREQUENCY 0x0001
#define AL_RING_MODULATOR_HIGHPASS_CUTOFF 0x0002
#define AL_RING_MODULATOR_WAVEFORM 0x0003
/* Autowah effect parameters */
#define AL_AUTOWAH_ATTACK_TIME 0x0001
#define AL_AUTOWAH_RELEASE_TIME 0x0002
#define AL_AUTOWAH_RESONANCE 0x0003
#define AL_AUTOWAH_PEAK_GAIN 0x0004
/* Compressor effect parameters */
#define AL_COMPRESSOR_ONOFF 0x0001
/* Equalizer effect parameters */
#define AL_EQUALIZER_LOW_GAIN 0x0001
#define AL_EQUALIZER_LOW_CUTOFF 0x0002
#define AL_EQUALIZER_MID1_GAIN 0x0003
#define AL_EQUALIZER_MID1_CENTER 0x0004
#define AL_EQUALIZER_MID1_WIDTH 0x0005
#define AL_EQUALIZER_MID2_GAIN 0x0006
#define AL_EQUALIZER_MID2_CENTER 0x0007
#define AL_EQUALIZER_MID2_WIDTH 0x0008
#define AL_EQUALIZER_HIGH_GAIN 0x0009
#define AL_EQUALIZER_HIGH_CUTOFF 0x000A
/* Effect type */
#define AL_EFFECT_FIRST_PARAMETER 0x0000
#define AL_EFFECT_LAST_PARAMETER 0x8000
#define AL_EFFECT_TYPE 0x8001
/* Effect types, used with the AL_EFFECT_TYPE property */
#define AL_EFFECT_NULL 0x0000
#define AL_EFFECT_REVERB 0x0001
#define AL_EFFECT_CHORUS 0x0002
#define AL_EFFECT_DISTORTION 0x0003
#define AL_EFFECT_ECHO 0x0004
#define AL_EFFECT_FLANGER 0x0005
#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006
#define AL_EFFECT_VOCAL_MORPHER 0x0007
#define AL_EFFECT_PITCH_SHIFTER 0x0008
#define AL_EFFECT_RING_MODULATOR 0x0009
#define AL_EFFECT_AUTOWAH 0x000A
#define AL_EFFECT_COMPRESSOR 0x000B
#define AL_EFFECT_EQUALIZER 0x000C
#define AL_EFFECT_EAXREVERB 0x8000
/* Auxiliary Effect Slot properties. */
#define AL_EFFECTSLOT_EFFECT 0x0001
#define AL_EFFECTSLOT_GAIN 0x0002
#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003
/* NULL Auxiliary Slot ID to disable a source send. */
#define AL_EFFECTSLOT_NULL 0x0000
/* Filter properties. */
/* Lowpass filter parameters */
#define AL_LOWPASS_GAIN 0x0001
#define AL_LOWPASS_GAINHF 0x0002
/* Highpass filter parameters */
#define AL_HIGHPASS_GAIN 0x0001
#define AL_HIGHPASS_GAINLF 0x0002
/* Bandpass filter parameters */
#define AL_BANDPASS_GAIN 0x0001
#define AL_BANDPASS_GAINLF 0x0002
#define AL_BANDPASS_GAINHF 0x0003
/* Filter type */
#define AL_FILTER_FIRST_PARAMETER 0x0000
#define AL_FILTER_LAST_PARAMETER 0x8000
#define AL_FILTER_TYPE 0x8001
/* Filter types, used with the AL_FILTER_TYPE property */
#define AL_FILTER_NULL 0x0000
#define AL_FILTER_LOWPASS 0x0001
#define AL_FILTER_HIGHPASS 0x0002
#define AL_FILTER_BANDPASS 0x0003
/* Effect object function types. */
typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*);
typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, const ALuint*);
typedef ALboolean (AL_APIENTRY *LPALISEFFECT)(ALuint);
typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint);
typedef void (AL_APIENTRY *LPALEFFECTIV)(ALuint, ALenum, const ALint*);
typedef void (AL_APIENTRY *LPALEFFECTF)(ALuint, ALenum, ALfloat);
typedef void (AL_APIENTRY *LPALEFFECTFV)(ALuint, ALenum, const ALfloat*);
typedef void (AL_APIENTRY *LPALGETEFFECTI)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETEFFECTIV)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETEFFECTF)(ALuint, ALenum, ALfloat*);
typedef void (AL_APIENTRY *LPALGETEFFECTFV)(ALuint, ALenum, ALfloat*);
/* Filter object function types. */
typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*);
typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, const ALuint*);
typedef ALboolean (AL_APIENTRY *LPALISFILTER)(ALuint);
typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint);
typedef void (AL_APIENTRY *LPALFILTERIV)(ALuint, ALenum, const ALint*);
typedef void (AL_APIENTRY *LPALFILTERF)(ALuint, ALenum, ALfloat);
typedef void (AL_APIENTRY *LPALFILTERFV)(ALuint, ALenum, const ALfloat*);
typedef void (AL_APIENTRY *LPALGETFILTERI)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETFILTERIV)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETFILTERF)(ALuint, ALenum, ALfloat*);
typedef void (AL_APIENTRY *LPALGETFILTERFV)(ALuint, ALenum, ALfloat*);
/* Auxiliary Effect Slot object function types. */
typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*);
typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, const ALuint*);
typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint);
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint);
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, const ALint*);
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat);
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, const ALfloat*);
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*);
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects);
AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects);
AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect);
AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue);
AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues);
AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue);
AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue);
AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue);
AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters);
AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters);
AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter);
AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue);
AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues);
AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue);
AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue);
AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue);
AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots);
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots);
AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues);
#endif
/* Filter ranges and defaults. */
/* Lowpass filter */
#define AL_LOWPASS_MIN_GAIN (0.0f)
#define AL_LOWPASS_MAX_GAIN (1.0f)
#define AL_LOWPASS_DEFAULT_GAIN (1.0f)
#define AL_LOWPASS_MIN_GAINHF (0.0f)
#define AL_LOWPASS_MAX_GAINHF (1.0f)
#define AL_LOWPASS_DEFAULT_GAINHF (1.0f)
/* Highpass filter */
#define AL_HIGHPASS_MIN_GAIN (0.0f)
#define AL_HIGHPASS_MAX_GAIN (1.0f)
#define AL_HIGHPASS_DEFAULT_GAIN (1.0f)
#define AL_HIGHPASS_MIN_GAINLF (0.0f)
#define AL_HIGHPASS_MAX_GAINLF (1.0f)
#define AL_HIGHPASS_DEFAULT_GAINLF (1.0f)
/* Bandpass filter */
#define AL_BANDPASS_MIN_GAIN (0.0f)
#define AL_BANDPASS_MAX_GAIN (1.0f)
#define AL_BANDPASS_DEFAULT_GAIN (1.0f)
#define AL_BANDPASS_MIN_GAINHF (0.0f)
#define AL_BANDPASS_MAX_GAINHF (1.0f)
#define AL_BANDPASS_DEFAULT_GAINHF (1.0f)
#define AL_BANDPASS_MIN_GAINLF (0.0f)
#define AL_BANDPASS_MAX_GAINLF (1.0f)
#define AL_BANDPASS_DEFAULT_GAINLF (1.0f)
/* Effect parameter ranges and defaults. */
/* Standard reverb effect */
#define AL_REVERB_MIN_DENSITY (0.0f)
#define AL_REVERB_MAX_DENSITY (1.0f)
#define AL_REVERB_DEFAULT_DENSITY (1.0f)
#define AL_REVERB_MIN_DIFFUSION (0.0f)
#define AL_REVERB_MAX_DIFFUSION (1.0f)
#define AL_REVERB_DEFAULT_DIFFUSION (1.0f)
#define AL_REVERB_MIN_GAIN (0.0f)
#define AL_REVERB_MAX_GAIN (1.0f)
#define AL_REVERB_DEFAULT_GAIN (0.32f)
#define AL_REVERB_MIN_GAINHF (0.0f)
#define AL_REVERB_MAX_GAINHF (1.0f)
#define AL_REVERB_DEFAULT_GAINHF (0.89f)
#define AL_REVERB_MIN_DECAY_TIME (0.1f)
#define AL_REVERB_MAX_DECAY_TIME (20.0f)
#define AL_REVERB_DEFAULT_DECAY_TIME (1.49f)
#define AL_REVERB_MIN_DECAY_HFRATIO (0.1f)
#define AL_REVERB_MAX_DECAY_HFRATIO (2.0f)
#define AL_REVERB_DEFAULT_DECAY_HFRATIO (0.83f)
#define AL_REVERB_MIN_REFLECTIONS_GAIN (0.0f)
#define AL_REVERB_MAX_REFLECTIONS_GAIN (3.16f)
#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
#define AL_REVERB_MIN_REFLECTIONS_DELAY (0.0f)
#define AL_REVERB_MAX_REFLECTIONS_DELAY (0.3f)
#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
#define AL_REVERB_MIN_LATE_REVERB_GAIN (0.0f)
#define AL_REVERB_MAX_LATE_REVERB_GAIN (10.0f)
#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
#define AL_REVERB_MIN_LATE_REVERB_DELAY (0.0f)
#define AL_REVERB_MAX_LATE_REVERB_DELAY (0.1f)
#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_REVERB_MIN_DECAY_HFLIMIT AL_FALSE
#define AL_REVERB_MAX_DECAY_HFLIMIT AL_TRUE
#define AL_REVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE
/* EAX reverb effect */
#define AL_EAXREVERB_MIN_DENSITY (0.0f)
#define AL_EAXREVERB_MAX_DENSITY (1.0f)
#define AL_EAXREVERB_DEFAULT_DENSITY (1.0f)
#define AL_EAXREVERB_MIN_DIFFUSION (0.0f)
#define AL_EAXREVERB_MAX_DIFFUSION (1.0f)
#define AL_EAXREVERB_DEFAULT_DIFFUSION (1.0f)
#define AL_EAXREVERB_MIN_GAIN (0.0f)
#define AL_EAXREVERB_MAX_GAIN (1.0f)
#define AL_EAXREVERB_DEFAULT_GAIN (0.32f)
#define AL_EAXREVERB_MIN_GAINHF (0.0f)
#define AL_EAXREVERB_MAX_GAINHF (1.0f)
#define AL_EAXREVERB_DEFAULT_GAINHF (0.89f)
#define AL_EAXREVERB_MIN_GAINLF (0.0f)
#define AL_EAXREVERB_MAX_GAINLF (1.0f)
#define AL_EAXREVERB_DEFAULT_GAINLF (1.0f)
#define AL_EAXREVERB_MIN_DECAY_TIME (0.1f)
#define AL_EAXREVERB_MAX_DECAY_TIME (20.0f)
#define AL_EAXREVERB_DEFAULT_DECAY_TIME (1.49f)
#define AL_EAXREVERB_MIN_DECAY_HFRATIO (0.1f)
#define AL_EAXREVERB_MAX_DECAY_HFRATIO (2.0f)
#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO (0.83f)
#define AL_EAXREVERB_MIN_DECAY_LFRATIO (0.1f)
#define AL_EAXREVERB_MAX_DECAY_LFRATIO (2.0f)
#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO (1.0f)
#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN (0.0f)
#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN (3.16f)
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY (0.0f)
#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f)
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ (0.0f)
#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN (0.0f)
#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN (10.0f)
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY (0.0f)
#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f)
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ (0.0f)
#define AL_EAXREVERB_MIN_ECHO_TIME (0.075f)
#define AL_EAXREVERB_MAX_ECHO_TIME (0.25f)
#define AL_EAXREVERB_DEFAULT_ECHO_TIME (0.25f)
#define AL_EAXREVERB_MIN_ECHO_DEPTH (0.0f)
#define AL_EAXREVERB_MAX_ECHO_DEPTH (1.0f)
#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH (0.0f)
#define AL_EAXREVERB_MIN_MODULATION_TIME (0.04f)
#define AL_EAXREVERB_MAX_MODULATION_TIME (4.0f)
#define AL_EAXREVERB_DEFAULT_MODULATION_TIME (0.25f)
#define AL_EAXREVERB_MIN_MODULATION_DEPTH (0.0f)
#define AL_EAXREVERB_MAX_MODULATION_DEPTH (1.0f)
#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH (0.0f)
#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
#define AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
#define AL_EAXREVERB_MIN_HFREFERENCE (1000.0f)
#define AL_EAXREVERB_MAX_HFREFERENCE (20000.0f)
#define AL_EAXREVERB_DEFAULT_HFREFERENCE (5000.0f)
#define AL_EAXREVERB_MIN_LFREFERENCE (20.0f)
#define AL_EAXREVERB_MAX_LFREFERENCE (1000.0f)
#define AL_EAXREVERB_DEFAULT_LFREFERENCE (250.0f)
#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
#define AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_EAXREVERB_MIN_DECAY_HFLIMIT AL_FALSE
#define AL_EAXREVERB_MAX_DECAY_HFLIMIT AL_TRUE
#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE
/* Chorus effect */
#define AL_CHORUS_WAVEFORM_SINUSOID (0)
#define AL_CHORUS_WAVEFORM_TRIANGLE (1)
#define AL_CHORUS_MIN_WAVEFORM (0)
#define AL_CHORUS_MAX_WAVEFORM (1)
#define AL_CHORUS_DEFAULT_WAVEFORM (1)
#define AL_CHORUS_MIN_PHASE (-180)
#define AL_CHORUS_MAX_PHASE (180)
#define AL_CHORUS_DEFAULT_PHASE (90)
#define AL_CHORUS_MIN_RATE (0.0f)
#define AL_CHORUS_MAX_RATE (10.0f)
#define AL_CHORUS_DEFAULT_RATE (1.1f)
#define AL_CHORUS_MIN_DEPTH (0.0f)
#define AL_CHORUS_MAX_DEPTH (1.0f)
#define AL_CHORUS_DEFAULT_DEPTH (0.1f)
#define AL_CHORUS_MIN_FEEDBACK (-1.0f)
#define AL_CHORUS_MAX_FEEDBACK (1.0f)
#define AL_CHORUS_DEFAULT_FEEDBACK (0.25f)
#define AL_CHORUS_MIN_DELAY (0.0f)
#define AL_CHORUS_MAX_DELAY (0.016f)
#define AL_CHORUS_DEFAULT_DELAY (0.016f)
/* Distortion effect */
#define AL_DISTORTION_MIN_EDGE (0.0f)
#define AL_DISTORTION_MAX_EDGE (1.0f)
#define AL_DISTORTION_DEFAULT_EDGE (0.2f)
#define AL_DISTORTION_MIN_GAIN (0.01f)
#define AL_DISTORTION_MAX_GAIN (1.0f)
#define AL_DISTORTION_DEFAULT_GAIN (0.05f)
#define AL_DISTORTION_MIN_LOWPASS_CUTOFF (80.0f)
#define AL_DISTORTION_MAX_LOWPASS_CUTOFF (24000.0f)
#define AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF (8000.0f)
#define AL_DISTORTION_MIN_EQCENTER (80.0f)
#define AL_DISTORTION_MAX_EQCENTER (24000.0f)
#define AL_DISTORTION_DEFAULT_EQCENTER (3600.0f)
#define AL_DISTORTION_MIN_EQBANDWIDTH (80.0f)
#define AL_DISTORTION_MAX_EQBANDWIDTH (24000.0f)
#define AL_DISTORTION_DEFAULT_EQBANDWIDTH (3600.0f)
/* Echo effect */
#define AL_ECHO_MIN_DELAY (0.0f)
#define AL_ECHO_MAX_DELAY (0.207f)
#define AL_ECHO_DEFAULT_DELAY (0.1f)
#define AL_ECHO_MIN_LRDELAY (0.0f)
#define AL_ECHO_MAX_LRDELAY (0.404f)
#define AL_ECHO_DEFAULT_LRDELAY (0.1f)
#define AL_ECHO_MIN_DAMPING (0.0f)
#define AL_ECHO_MAX_DAMPING (0.99f)
#define AL_ECHO_DEFAULT_DAMPING (0.5f)
#define AL_ECHO_MIN_FEEDBACK (0.0f)
#define AL_ECHO_MAX_FEEDBACK (1.0f)
#define AL_ECHO_DEFAULT_FEEDBACK (0.5f)
#define AL_ECHO_MIN_SPREAD (-1.0f)
#define AL_ECHO_MAX_SPREAD (1.0f)
#define AL_ECHO_DEFAULT_SPREAD (-1.0f)
/* Flanger effect */
#define AL_FLANGER_WAVEFORM_SINUSOID (0)
#define AL_FLANGER_WAVEFORM_TRIANGLE (1)
#define AL_FLANGER_MIN_WAVEFORM (0)
#define AL_FLANGER_MAX_WAVEFORM (1)
#define AL_FLANGER_DEFAULT_WAVEFORM (1)
#define AL_FLANGER_MIN_PHASE (-180)
#define AL_FLANGER_MAX_PHASE (180)
#define AL_FLANGER_DEFAULT_PHASE (0)
#define AL_FLANGER_MIN_RATE (0.0f)
#define AL_FLANGER_MAX_RATE (10.0f)
#define AL_FLANGER_DEFAULT_RATE (0.27f)
#define AL_FLANGER_MIN_DEPTH (0.0f)
#define AL_FLANGER_MAX_DEPTH (1.0f)
#define AL_FLANGER_DEFAULT_DEPTH (1.0f)
#define AL_FLANGER_MIN_FEEDBACK (-1.0f)
#define AL_FLANGER_MAX_FEEDBACK (1.0f)
#define AL_FLANGER_DEFAULT_FEEDBACK (-0.5f)
#define AL_FLANGER_MIN_DELAY (0.0f)
#define AL_FLANGER_MAX_DELAY (0.004f)
#define AL_FLANGER_DEFAULT_DELAY (0.002f)
/* Frequency shifter effect */
#define AL_FREQUENCY_SHIFTER_MIN_FREQUENCY (0.0f)
#define AL_FREQUENCY_SHIFTER_MAX_FREQUENCY (24000.0f)
#define AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY (0.0f)
#define AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION (0)
#define AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION (2)
#define AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION (0)
#define AL_FREQUENCY_SHIFTER_DIRECTION_DOWN (0)
#define AL_FREQUENCY_SHIFTER_DIRECTION_UP (1)
#define AL_FREQUENCY_SHIFTER_DIRECTION_OFF (2)
#define AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION (0)
#define AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION (2)
#define AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION (0)
/* Vocal morpher effect */
#define AL_VOCAL_MORPHER_MIN_PHONEMEA (0)
#define AL_VOCAL_MORPHER_MAX_PHONEMEA (29)
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA (0)
#define AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING (-24)
#define AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING (24)
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING (0)
#define AL_VOCAL_MORPHER_MIN_PHONEMEB (0)
#define AL_VOCAL_MORPHER_MAX_PHONEMEB (29)
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB (10)
#define AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING (-24)
#define AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING (24)
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING (0)
#define AL_VOCAL_MORPHER_PHONEME_A (0)
#define AL_VOCAL_MORPHER_PHONEME_E (1)
#define AL_VOCAL_MORPHER_PHONEME_I (2)
#define AL_VOCAL_MORPHER_PHONEME_O (3)
#define AL_VOCAL_MORPHER_PHONEME_U (4)
#define AL_VOCAL_MORPHER_PHONEME_AA (5)
#define AL_VOCAL_MORPHER_PHONEME_AE (6)
#define AL_VOCAL_MORPHER_PHONEME_AH (7)
#define AL_VOCAL_MORPHER_PHONEME_AO (8)
#define AL_VOCAL_MORPHER_PHONEME_EH (9)
#define AL_VOCAL_MORPHER_PHONEME_ER (10)
#define AL_VOCAL_MORPHER_PHONEME_IH (11)
#define AL_VOCAL_MORPHER_PHONEME_IY (12)
#define AL_VOCAL_MORPHER_PHONEME_UH (13)
#define AL_VOCAL_MORPHER_PHONEME_UW (14)
#define AL_VOCAL_MORPHER_PHONEME_B (15)
#define AL_VOCAL_MORPHER_PHONEME_D (16)
#define AL_VOCAL_MORPHER_PHONEME_F (17)
#define AL_VOCAL_MORPHER_PHONEME_G (18)
#define AL_VOCAL_MORPHER_PHONEME_J (19)
#define AL_VOCAL_MORPHER_PHONEME_K (20)
#define AL_VOCAL_MORPHER_PHONEME_L (21)
#define AL_VOCAL_MORPHER_PHONEME_M (22)
#define AL_VOCAL_MORPHER_PHONEME_N (23)
#define AL_VOCAL_MORPHER_PHONEME_P (24)
#define AL_VOCAL_MORPHER_PHONEME_R (25)
#define AL_VOCAL_MORPHER_PHONEME_S (26)
#define AL_VOCAL_MORPHER_PHONEME_T (27)
#define AL_VOCAL_MORPHER_PHONEME_V (28)
#define AL_VOCAL_MORPHER_PHONEME_Z (29)
#define AL_VOCAL_MORPHER_WAVEFORM_SINUSOID (0)
#define AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE (1)
#define AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH (2)
#define AL_VOCAL_MORPHER_MIN_WAVEFORM (0)
#define AL_VOCAL_MORPHER_MAX_WAVEFORM (2)
#define AL_VOCAL_MORPHER_DEFAULT_WAVEFORM (0)
#define AL_VOCAL_MORPHER_MIN_RATE (0.0f)
#define AL_VOCAL_MORPHER_MAX_RATE (10.0f)
#define AL_VOCAL_MORPHER_DEFAULT_RATE (1.41f)
/* Pitch shifter effect */
#define AL_PITCH_SHIFTER_MIN_COARSE_TUNE (-12)
#define AL_PITCH_SHIFTER_MAX_COARSE_TUNE (12)
#define AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE (12)
#define AL_PITCH_SHIFTER_MIN_FINE_TUNE (-50)
#define AL_PITCH_SHIFTER_MAX_FINE_TUNE (50)
#define AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE (0)
/* Ring modulator effect */
#define AL_RING_MODULATOR_MIN_FREQUENCY (0.0f)
#define AL_RING_MODULATOR_MAX_FREQUENCY (8000.0f)
#define AL_RING_MODULATOR_DEFAULT_FREQUENCY (440.0f)
#define AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF (0.0f)
#define AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF (24000.0f)
#define AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF (800.0f)
#define AL_RING_MODULATOR_SINUSOID (0)
#define AL_RING_MODULATOR_SAWTOOTH (1)
#define AL_RING_MODULATOR_SQUARE (2)
#define AL_RING_MODULATOR_MIN_WAVEFORM (0)
#define AL_RING_MODULATOR_MAX_WAVEFORM (2)
#define AL_RING_MODULATOR_DEFAULT_WAVEFORM (0)
/* Autowah effect */
#define AL_AUTOWAH_MIN_ATTACK_TIME (0.0001f)
#define AL_AUTOWAH_MAX_ATTACK_TIME (1.0f)
#define AL_AUTOWAH_DEFAULT_ATTACK_TIME (0.06f)
#define AL_AUTOWAH_MIN_RELEASE_TIME (0.0001f)
#define AL_AUTOWAH_MAX_RELEASE_TIME (1.0f)
#define AL_AUTOWAH_DEFAULT_RELEASE_TIME (0.06f)
#define AL_AUTOWAH_MIN_RESONANCE (2.0f)
#define AL_AUTOWAH_MAX_RESONANCE (1000.0f)
#define AL_AUTOWAH_DEFAULT_RESONANCE (1000.0f)
#define AL_AUTOWAH_MIN_PEAK_GAIN (0.00003f)
#define AL_AUTOWAH_MAX_PEAK_GAIN (31621.0f)
#define AL_AUTOWAH_DEFAULT_PEAK_GAIN (11.22f)
/* Compressor effect */
#define AL_COMPRESSOR_MIN_ONOFF (0)
#define AL_COMPRESSOR_MAX_ONOFF (1)
#define AL_COMPRESSOR_DEFAULT_ONOFF (1)
/* Equalizer effect */
#define AL_EQUALIZER_MIN_LOW_GAIN (0.126f)
#define AL_EQUALIZER_MAX_LOW_GAIN (7.943f)
#define AL_EQUALIZER_DEFAULT_LOW_GAIN (1.0f)
#define AL_EQUALIZER_MIN_LOW_CUTOFF (50.0f)
#define AL_EQUALIZER_MAX_LOW_CUTOFF (800.0f)
#define AL_EQUALIZER_DEFAULT_LOW_CUTOFF (200.0f)
#define AL_EQUALIZER_MIN_MID1_GAIN (0.126f)
#define AL_EQUALIZER_MAX_MID1_GAIN (7.943f)
#define AL_EQUALIZER_DEFAULT_MID1_GAIN (1.0f)
#define AL_EQUALIZER_MIN_MID1_CENTER (200.0f)
#define AL_EQUALIZER_MAX_MID1_CENTER (3000.0f)
#define AL_EQUALIZER_DEFAULT_MID1_CENTER (500.0f)
#define AL_EQUALIZER_MIN_MID1_WIDTH (0.01f)
#define AL_EQUALIZER_MAX_MID1_WIDTH (1.0f)
#define AL_EQUALIZER_DEFAULT_MID1_WIDTH (1.0f)
#define AL_EQUALIZER_MIN_MID2_GAIN (0.126f)
#define AL_EQUALIZER_MAX_MID2_GAIN (7.943f)
#define AL_EQUALIZER_DEFAULT_MID2_GAIN (1.0f)
#define AL_EQUALIZER_MIN_MID2_CENTER (1000.0f)
#define AL_EQUALIZER_MAX_MID2_CENTER (8000.0f)
#define AL_EQUALIZER_DEFAULT_MID2_CENTER (3000.0f)
#define AL_EQUALIZER_MIN_MID2_WIDTH (0.01f)
#define AL_EQUALIZER_MAX_MID2_WIDTH (1.0f)
#define AL_EQUALIZER_DEFAULT_MID2_WIDTH (1.0f)
#define AL_EQUALIZER_MIN_HIGH_GAIN (0.126f)
#define AL_EQUALIZER_MAX_HIGH_GAIN (7.943f)
#define AL_EQUALIZER_DEFAULT_HIGH_GAIN (1.0f)
#define AL_EQUALIZER_MIN_HIGH_CUTOFF (4000.0f)
#define AL_EQUALIZER_MAX_HIGH_CUTOFF (16000.0f)
#define AL_EQUALIZER_DEFAULT_HIGH_CUTOFF (6000.0f)
/* Source parameter value ranges and defaults. */
#define AL_MIN_AIR_ABSORPTION_FACTOR (0.0f)
#define AL_MAX_AIR_ABSORPTION_FACTOR (10.0f)
#define AL_DEFAULT_AIR_ABSORPTION_FACTOR (0.0f)
#define AL_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
#define AL_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_MIN_CONE_OUTER_GAINHF (0.0f)
#define AL_MAX_CONE_OUTER_GAINHF (1.0f)
#define AL_DEFAULT_CONE_OUTER_GAINHF (1.0f)
#define AL_MIN_DIRECT_FILTER_GAINHF_AUTO AL_FALSE
#define AL_MAX_DIRECT_FILTER_GAINHF_AUTO AL_TRUE
#define AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO AL_TRUE
#define AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_FALSE
#define AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE
#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE
#define AL_MIN_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_FALSE
#define AL_MAX_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE
#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE
/* Listener parameter value ranges and defaults. */
#define AL_MIN_METERS_PER_UNIT FLT_MIN
#define AL_MAX_METERS_PER_UNIT FLT_MAX
#define AL_DEFAULT_METERS_PER_UNIT (1.0f)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* AL_EFX_H */

@ -37,7 +37,7 @@ namespace MWSound
{
public:
MovieAudioDecoder(Video::VideoState *videoState)
: Video::MovieAudioDecoder(videoState)
: Video::MovieAudioDecoder(videoState), mAudioTrack(nullptr)
{
mDecoderBridge.reset(new MWSoundDecoderBridge(this));
}
@ -85,13 +85,13 @@ namespace MWSound
public:
~MovieAudioDecoder()
{
if(mAudioTrack.get())
if(mAudioTrack)
MWBase::Environment::get().getSoundManager()->stopTrack(mAudioTrack);
mAudioTrack.reset();
mAudioTrack = nullptr;
mDecoderBridge.reset();
}
MWBase::SoundStreamPtr mAudioTrack;
MWBase::SoundStream *mAudioTrack;
std::shared_ptr<MWSoundDecoderBridge> mDecoderBridge;
};
@ -162,8 +162,8 @@ namespace MWSound
decoder->setupFormat();
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
MWBase::SoundStreamPtr sound = sndMgr->playTrack(decoder->mDecoderBridge, MWBase::SoundManager::Play_TypeMovie);
if (!sound.get())
MWBase::SoundStream *sound = sndMgr->playTrack(decoder->mDecoderBridge, MWSound::Type::Movie);
if (!sound)
{
decoder.reset();
return decoder;

File diff suppressed because it is too large Load Diff

@ -8,6 +8,7 @@
#include "alc.h"
#include "al.h"
#include "alext.h"
#include "sound_output.hpp"
@ -15,23 +16,37 @@ namespace MWSound
{
class SoundManager;
class Sound;
class Stream;
class OpenAL_Output : public Sound_Output
{
ALCdevice *mDevice;
ALCcontext *mContext;
struct {
bool EXT_EFX : 1;
bool SOFT_HRTF : 1;
} ALC;
struct {
bool SOFT_source_spatialize : 1;
} AL;
typedef std::deque<ALuint> IDDq;
IDDq mFreeSources;
typedef std::vector<MWBase::SoundPtr> SoundVec;
typedef std::vector<Sound*> SoundVec;
SoundVec mActiveSounds;
typedef std::vector<MWBase::SoundStreamPtr> StreamVec;
typedef std::vector<Stream*> StreamVec;
StreamVec mActiveStreams;
osg::Vec3f mListenerPos;
Environment mListenerEnv;
ALuint mWaterFilter;
ALuint mWaterEffect;
ALuint mDefaultEffect;
ALuint mEffectSlot;
struct StreamThread;
std::unique_ptr<StreamThread> mStreamThread;
@ -45,31 +60,30 @@ namespace MWSound
public:
virtual std::vector<std::string> enumerate();
virtual void init(const std::string &devname=std::string());
virtual bool init(const std::string &devname, const std::string &hrtfname, HrtfMode hrtfmode);
virtual void deinit();
virtual std::vector<std::string> enumerateHrtf();
virtual void enableHrtf(const std::string &hrtfname, bool auto_enable);
virtual void disableHrtf();
virtual void setHrtf(const std::string &hrtfname, HrtfMode hrtfmode);
virtual Sound_Handle loadSound(const std::string &fname);
virtual void unloadSound(Sound_Handle data);
virtual size_t getSoundDataSize(Sound_Handle data) const;
virtual void playSound(MWBase::SoundPtr sound, Sound_Handle data, float offset);
virtual void playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float offset);
virtual void finishSound(MWBase::SoundPtr sound);
virtual bool isSoundPlaying(MWBase::SoundPtr sound);
virtual void updateSound(MWBase::SoundPtr sound);
virtual void streamSound(DecoderPtr decoder, MWBase::SoundStreamPtr sound);
virtual void streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sound, bool getLoudnessData);
virtual void finishStream(MWBase::SoundStreamPtr sound);
virtual double getStreamDelay(MWBase::SoundStreamPtr sound);
virtual double getStreamOffset(MWBase::SoundStreamPtr sound);
virtual float getStreamLoudness(MWBase::SoundStreamPtr sound);
virtual bool isStreamPlaying(MWBase::SoundStreamPtr sound);
virtual void updateStream(MWBase::SoundStreamPtr sound);
virtual bool playSound(Sound *sound, Sound_Handle data, float offset);
virtual bool playSound3D(Sound *sound, Sound_Handle data, float offset);
virtual void finishSound(Sound *sound);
virtual bool isSoundPlaying(Sound *sound);
virtual void updateSound(Sound *sound);
virtual bool streamSound(DecoderPtr decoder, Stream *sound);
virtual bool streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData);
virtual void finishStream(Stream *sound);
virtual double getStreamDelay(Stream *sound);
virtual double getStreamOffset(Stream *sound);
virtual float getStreamLoudness(Stream *sound);
virtual bool isStreamPlaying(Stream *sound);
virtual void updateStream(Stream *sound);
virtual void startUpdate();
virtual void finishUpdate();

@ -7,9 +7,14 @@
namespace MWSound
{
class Sound {
Sound& operator=(const Sound &rhs);
Sound(const Sound &rhs);
// For testing individual PlayMode flags
inline int operator&(int a, PlayMode b) { return a & static_cast<int>(b); }
inline int operator&(PlayMode a, PlayMode b) { return static_cast<int>(a) & static_cast<int>(b); }
class SoundBase {
SoundBase& operator=(const SoundBase&) = delete;
SoundBase(const SoundBase&) = delete;
SoundBase(SoundBase&&) = delete;
osg::Vec3f mPos;
float mVolume; /* NOTE: Real volume = mVolume*mBaseVolume */
@ -47,37 +52,62 @@ namespace MWSound
float getMinDistance() const { return mMinDistance; }
float getMaxDistance() const { return mMaxDistance; }
MWBase::SoundManager::PlayType getPlayType() const
{ return (MWBase::SoundManager::PlayType)(mFlags&MWBase::SoundManager::Play_TypeMask); }
bool getUseEnv() const { return !(mFlags&MWBase::SoundManager::Play_NoEnv); }
bool getIsLooping() const { return mFlags&MWBase::SoundManager::Play_Loop; }
bool getDistanceCull() const { return mFlags&MWBase::SoundManager::Play_RemoveAtDistance; }
MWSound::Type getPlayType() const
{ return static_cast<MWSound::Type>(mFlags&MWSound::Type::Mask); }
bool getUseEnv() const { return !(mFlags&MWSound::PlayMode::NoEnv); }
bool getIsLooping() const { return mFlags&MWSound::PlayMode::Loop; }
bool getDistanceCull() const { return mFlags&MWSound::PlayMode::RemoveAtDistance; }
bool getIs3D() const { return mFlags&Play_3D; }
Sound(const osg::Vec3f& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags)
: mPos(pos), mVolume(vol), mBaseVolume(basevol), mPitch(pitch)
, mMinDistance(mindist), mMaxDistance(maxdist), mFlags(flags)
, mFadeOutTime(0.0f), mHandle(0)
{ }
Sound(float vol, float basevol, float pitch, int flags)
: mPos(0.0f, 0.0f, 0.0f), mVolume(vol), mBaseVolume(basevol), mPitch(pitch)
, mMinDistance(1.0f), mMaxDistance(1000.0f), mFlags(flags)
, mFadeOutTime(0.0f), mHandle(0)
void init(const osg::Vec3f& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags)
{
mPos = pos;
mVolume = vol;
mBaseVolume = basevol;
mPitch = pitch;
mMinDistance = mindist;
mMaxDistance = maxdist;
mFlags = flags;
mFadeOutTime = 0.0f;
mHandle = nullptr;
}
void init(float vol, float basevol, float pitch, int flags)
{
mPos = osg::Vec3f(0.0f, 0.0f, 0.0f);
mVolume = vol;
mBaseVolume = basevol;
mPitch = pitch;
mMinDistance = 1.0f;
mMaxDistance = 1000.0f;
mFlags = flags;
mFadeOutTime = 0.0f;
mHandle = nullptr;
}
SoundBase()
: mPos(0.0f, 0.0f, 0.0f), mVolume(1.0f), mBaseVolume(1.0f), mPitch(1.0f)
, mMinDistance(1.0f), mMaxDistance(1000.0f), mFlags(0), mFadeOutTime(0.0f)
, mHandle(nullptr)
{ }
};
// Same as above, but it's a different type since the output handles them differently
class Stream : public Sound {
Stream& operator=(const Stream &rhs);
Stream(const Stream &rhs);
class Sound : public SoundBase {
Sound& operator=(const Sound&) = delete;
Sound(const Sound&) = delete;
Sound(Sound&&) = delete;
public:
Stream(const osg::Vec3f& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags)
: Sound(pos, vol, basevol, pitch, mindist, maxdist, flags)
{ }
Stream(float vol, float basevol, float pitch, int flags)
: Sound(vol, basevol, pitch, flags)
{ }
Sound() { }
};
class Stream : public SoundBase {
Stream& operator=(const Stream&) = delete;
Stream(const Stream&) = delete;
Stream(Stream&&) = delete;
public:
Stream() { }
};
}

@ -12,42 +12,48 @@ namespace MWSound
class SoundManager;
struct Sound_Decoder;
class Sound;
class Stream;
// An opaque handle for the implementation's sound buffers.
typedef void *Sound_Handle;
// An opaque handle for the implementation's sound instances.
typedef void *Sound_Instance;
enum class HrtfMode {
Disable,
Enable,
Auto
};
class Sound_Output
{
SoundManager &mManager;
virtual std::vector<std::string> enumerate() = 0;
virtual void 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 std::vector<std::string> enumerateHrtf() = 0;
virtual void enableHrtf(const std::string &hrtfname, bool auto_enable) = 0;
virtual void disableHrtf() = 0;
virtual void setHrtf(const std::string &hrtfname, HrtfMode hrtfmode) = 0;
virtual Sound_Handle loadSound(const std::string &fname) = 0;
virtual void unloadSound(Sound_Handle data) = 0;
virtual size_t getSoundDataSize(Sound_Handle data) const = 0;
virtual void playSound(MWBase::SoundPtr sound, Sound_Handle data, float offset) = 0;
virtual void playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float offset) = 0;
virtual void finishSound(MWBase::SoundPtr sound) = 0;
virtual bool isSoundPlaying(MWBase::SoundPtr sound) = 0;
virtual void updateSound(MWBase::SoundPtr sound) = 0;
virtual void streamSound(DecoderPtr decoder, MWBase::SoundStreamPtr sound) = 0;
virtual void streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sound, bool getLoudnessData) = 0;
virtual void finishStream(MWBase::SoundStreamPtr sound) = 0;
virtual double getStreamDelay(MWBase::SoundStreamPtr sound) = 0;
virtual double getStreamOffset(MWBase::SoundStreamPtr sound) = 0;
virtual float getStreamLoudness(MWBase::SoundStreamPtr sound) = 0;
virtual bool isStreamPlaying(MWBase::SoundStreamPtr sound) = 0;
virtual void updateStream(MWBase::SoundStreamPtr sound) = 0;
virtual bool playSound(Sound *sound, Sound_Handle data, float offset) = 0;
virtual bool playSound3D(Sound *sound, Sound_Handle data, float offset) = 0;
virtual void finishSound(Sound *sound) = 0;
virtual bool isSoundPlaying(Sound *sound) = 0;
virtual void updateSound(Sound *sound) = 0;
virtual bool streamSound(DecoderPtr decoder, Stream *sound) = 0;
virtual bool streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData) = 0;
virtual void finishStream(Stream *sound) = 0;
virtual double getStreamDelay(Stream *sound) = 0;
virtual double getStreamOffset(Stream *sound) = 0;
virtual float getStreamLoudness(Stream *sound) = 0;
virtual bool isStreamPlaying(Stream *sound) = 0;
virtual void updateStream(Stream *sound) = 0;
virtual void startUpdate() = 0;
virtual void finishUpdate() = 0;

@ -35,6 +35,9 @@
namespace MWSound
{
// For combining PlayMode and Type flags
inline int operator|(PlayMode a, Type b) { return static_cast<int>(a) | static_cast<int>(b); }
SoundManager::SoundManager(const VFS::Manager* vfs, const std::map<std::string, std::string>& fallbackMap, bool useSound)
: mVFS(vfs)
, mFallback(fallbackMap)
@ -46,11 +49,16 @@ namespace MWSound
, mFootstepsVolume(1.0f)
, mSoundBuffers(new SoundBufferList::element_type())
, mBufferCacheSize(0)
, mSounds(new std::deque<Sound>())
, mStreams(new std::deque<Stream>())
, mMusic(nullptr)
, mListenerUnderwater(false)
, mListenerPos(0,0,0)
, mListenerDir(1,0,0)
, mListenerUp(0,0,1)
, mPausedSoundTypes(0)
, mUnderwaterSound(nullptr)
, mNearWaterSound(nullptr)
{
mMasterVolume = Settings::Manager::getFloat("master volume", "Sound");
mMasterVolume = std::min(std::max(mMasterVolume, 0.0f), 1.0f);
@ -67,8 +75,8 @@ namespace MWSound
mNearWaterPoints = mFallback.getFallbackInt("Water_NearWaterPoints");
mNearWaterIndoorTolerance = mFallback.getFallbackFloat("Water_NearWaterIndoorTolerance");
mNearWaterOutdoorTolerance = mFallback.getFallbackFloat("Water_NearWaterOutdoorTolerance");
mNearWaterIndoorID = mFallback.getFallbackString("Water_NearWaterIndoorID");
mNearWaterOutdoorID = mFallback.getFallbackString("Water_NearWaterOutdoorID");
mNearWaterIndoorID = Misc::StringUtils::lowerCase(mFallback.getFallbackString("Water_NearWaterIndoorID"));
mNearWaterOutdoorID = Misc::StringUtils::lowerCase(mFallback.getFallbackString("Water_NearWaterOutdoorID"));
mBufferCacheMin = std::max(Settings::Manager::getInt("buffer cache min", "Sound"), 1);
mBufferCacheMax = std::max(Settings::Manager::getInt("buffer cache max", "Sound"), 1);
@ -80,43 +88,42 @@ namespace MWSound
std::string hrtfname = Settings::Manager::getString("hrtf", "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 decoder: " << SOUND_IN << std::endl;
try {
std::vector<std::string> names = mOutput->enumerate();
std::cout <<"Enumerated output devices:"<< std::endl;
for(size_t i = 0;i < names.size();i++)
std::cout <<" "<<names[i]<< std::endl;
std::string devname = Settings::Manager::getString("device", "Sound");
try {
mOutput->init(devname);
}
catch(std::exception &e) {
if(devname.empty())
throw;
std::cerr <<"Failed to open device \""<<devname<<"\": " << e.what() << std::endl;
mOutput->init();
Settings::Manager::setString("device", "Sound", "");
}
names = mOutput->enumerateHrtf();
if(!names.empty())
{
std::cout <<"Enumerated HRTF names:"<< std::endl;
for(size_t i = 0;i < names.size();i++)
std::cout <<" "<<names[i]<< std::endl;
}
std::vector<std::string> names = mOutput->enumerate();
std::cout <<"Enumerated output devices:\n";
std::for_each(names.cbegin(), names.cend(),
[](const std::string &name) -> void
{ std::cout <<" "<<name<<"\n"; }
);
std::cout.flush();
if(hrtfstate == 0)
mOutput->disableHrtf();
else if(!hrtfname.empty())
mOutput->enableHrtf(hrtfname, hrtfstate<0);
std::string devname = Settings::Manager::getString("device", "Sound");
bool inited = mOutput->init(devname, hrtfname, hrtfmode);
if(!inited && !devname.empty())
{
std::cerr<< "Failed to initialize device \""<<devname<<"\", trying default" <<std::endl;
inited = mOutput->init(std::string(), hrtfname, hrtfmode);
}
catch(std::exception &e) {
std::cout <<"Sound init failed: "<<e.what()<< std::endl;
if(!inited)
{
std::cerr<< "Failed to initialize default audio device, sound disabled" <<std::endl;
return;
}
names = mOutput->enumerateHrtf();
if(!names.empty())
{
std::cout<< "Enumerated HRTF names:\n";
std::for_each(names.cbegin(), names.cend(),
[](const std::string &name) -> void
{ std::cout<< " "<<name<<"\n"; }
);
std::cout.flush();
}
}
@ -181,8 +188,12 @@ namespace MWSound
Sound_Buffer *SoundManager::lookupSound(const std::string &soundId) const
{
NameBufferMap::const_iterator snd = mBufferNameMap.find(soundId);
if(snd != mBufferNameMap.end()) return snd->second;
return 0;
if(snd != mBufferNameMap.end())
{
Sound_Buffer *sfx = snd->second;
if(sfx->mHandle) return sfx;
}
return nullptr;
}
// Lookup a soundId for its sound data (resource name, local volume,
@ -196,15 +207,17 @@ namespace MWSound
else
{
MWBase::World *world = MWBase::Environment::get().getWorld();
const ESM::Sound *sound = world->getStore().get<ESM::Sound>().find(soundId);
const ESM::Sound *sound = world->getStore().get<ESM::Sound>().search(soundId);
if(!sound) return nullptr;
sfx = insertSound(soundId, sound);
}
if(!sfx->mHandle)
{
sfx->mHandle = mOutput->loadSound(sfx->mResourceName);
mBufferCacheSize += mOutput->getSoundDataSize(sfx->mHandle);
if(!sfx->mHandle) return nullptr;
mBufferCacheSize += mOutput->getSoundDataSize(sfx->mHandle);
if(mBufferCacheSize > mBufferCacheMax)
{
do {
@ -246,7 +259,39 @@ namespace MWSound
return decoder;
}
MWBase::SoundStreamPtr SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal)
Sound *SoundManager::getSoundRef()
{
Sound *ret;
if(!mUnusedSounds.empty())
{
ret = mUnusedSounds.back();
mUnusedSounds.pop_back();
}
else
{
mSounds->emplace_back();
ret = &mSounds->back();
}
return ret;
}
Stream *SoundManager::getStreamRef()
{
Stream *ret;
if(!mUnusedStreams.empty())
{
ret = mUnusedStreams.back();
mUnusedStreams.pop_back();
}
else
{
mStreams->emplace_back();
ret = &mStreams->back();
}
return ret;
}
Stream *SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal)
{
MWBase::World* world = MWBase::Environment::get().getWorld();
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->getFloat();
@ -256,43 +301,48 @@ namespace MWSound
static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f);
static float maxDistance = std::max(fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult, minDistance);
MWBase::SoundStreamPtr sound;
float basevol = volumeFromType(Play_TypeVoice);
bool played;
float basevol = volumeFromType(Type::Voice);
Stream *sound = getStreamRef();
if(playlocal)
{
sound.reset(new Stream(1.0f, basevol, 1.0f, Play_NoEnv|Play_TypeVoice|Play_2D));
mOutput->streamSound(decoder, sound);
sound->init(1.0f, basevol, 1.0f, PlayMode::NoEnv|Type::Voice|Play_2D);
played = mOutput->streamSound(decoder, sound);
}
else
{
sound.reset(new Stream(pos, 1.0f, basevol, 1.0f, minDistance, maxDistance,
Play_Normal|Play_TypeVoice|Play_3D));
mOutput->streamSound3D(decoder, sound, true);
sound->init(pos, 1.0f, basevol, 1.0f, minDistance, maxDistance,
PlayMode::Normal|Type::Voice|Play_3D);
played = mOutput->streamSound3D(decoder, sound, true);
}
if(!played)
{
mUnusedStreams.push_back(sound);
return nullptr;
}
return sound;
}
// Gets the combined volume settings for the given sound type
float SoundManager::volumeFromType(PlayType type) const
float SoundManager::volumeFromType(Type type) const
{
float volume = mMasterVolume;
switch(type)
{
case Play_TypeSfx:
case Type::Sfx:
volume *= mSFXVolume;
break;
case Play_TypeVoice:
case Type::Voice:
volume *= mVoiceVolume;
break;
case Play_TypeFoot:
case Type::Foot:
volume *= mFootstepsVolume;
break;
case Play_TypeMusic:
case Type::Music:
volume *= mMusicVolume;
break;
case Play_TypeMask:
break;
default:
case Type::Movie:
case Type::Mask:
break;
}
return volume;
@ -301,8 +351,11 @@ namespace MWSound
void SoundManager::stopMusic()
{
if(mMusic)
{
mOutput->finishStream(mMusic);
mMusic.reset();
mUnusedStreams.push_back(mMusic);
mMusic = nullptr;
}
}
void SoundManager::streamMusicFull(const std::string& filename)
@ -311,20 +364,16 @@ namespace MWSound
return;
std::cout <<"Playing "<<filename<< std::endl;
mLastPlayedMusic = filename;
try {
stopMusic();
DecoderPtr decoder = getDecoder();
decoder->open(filename);
stopMusic();
mMusic.reset(new Stream(1.0f, volumeFromType(Play_TypeMusic), 1.0f,
Play_NoEnv|Play_TypeMusic|Play_2D));
mOutput->streamSound(decoder, mMusic);
}
catch(std::exception &e) {
std::cout << "Music Error: " << e.what() << "\n";
mMusic.reset();
}
DecoderPtr decoder = getDecoder();
decoder->open(filename);
mMusic = getStreamRef();
mMusic->init(1.0f, volumeFromType(Type::Music), 1.0f,
PlayMode::NoEnv|Type::Music|Play_2D);
mOutput->streamSound(decoder, mMusic);
}
void SoundManager::advanceMusic(const std::string& filename)
@ -411,31 +460,20 @@ namespace MWSound
{
if(!mOutput->isInitialized())
return;
try
{
std::string voicefile = "Sound/"+filename;
mVFS->normalizeFilename(voicefile);
DecoderPtr decoder = loadVoice(voicefile);
std::string voicefile = "Sound/"+filename;
MWBase::World *world = MWBase::Environment::get().getWorld();
const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans();
mVFS->normalizeFilename(voicefile);
DecoderPtr decoder = loadVoice(voicefile);
SaySoundMap::iterator oldIt = mActiveSaySounds.find(ptr);
if (oldIt != mActiveSaySounds.end())
{
mOutput->finishStream(oldIt->second);
mActiveSaySounds.erase(oldIt);
}
MWBase::World *world = MWBase::Environment::get().getWorld();
const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans();
MWBase::SoundStreamPtr sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer()));
stopSay(ptr);
Stream *sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer()));
if(!sound) return;
mActiveSaySounds.insert(std::make_pair(ptr, sound));
}
catch(std::exception &e)
{
std::cout <<"Sound Error: "<<e.what()<< std::endl;
}
mActiveSaySounds.insert(std::make_pair(ptr, sound));
}
float SoundManager::getSaySoundLoudness(const MWWorld::ConstPtr &ptr) const
@ -443,7 +481,7 @@ namespace MWSound
SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr);
if(snditer != mActiveSaySounds.end())
{
MWBase::SoundStreamPtr sound = snditer->second;
Stream *sound = snditer->second;
return mOutput->getStreamLoudness(sound);
}
@ -454,27 +492,17 @@ namespace MWSound
{
if(!mOutput->isInitialized())
return;
try
{
std::string voicefile = "Sound/"+filename;
mVFS->normalizeFilename(voicefile);
DecoderPtr decoder = loadVoice(voicefile);
std::string voicefile = "Sound/"+filename;
SaySoundMap::iterator oldIt = mActiveSaySounds.find(MWWorld::ConstPtr());
if (oldIt != mActiveSaySounds.end())
{
mOutput->finishStream(oldIt->second);
mActiveSaySounds.erase(oldIt);
}
mVFS->normalizeFilename(voicefile);
DecoderPtr decoder = loadVoice(voicefile);
mActiveSaySounds.insert(std::make_pair(MWWorld::ConstPtr(),
playVoice(decoder, osg::Vec3f(), true)));
}
catch(std::exception &e)
{
std::cout <<"Sound Error: "<<e.what()<< std::endl;
}
stopSay(MWWorld::ConstPtr());
Stream *sound = playVoice(decoder, osg::Vec3f(), true);
if(!sound) return;
mActiveSaySounds.insert(std::make_pair(MWWorld::ConstPtr(), sound));
}
bool SoundManager::sayDone(const MWWorld::ConstPtr &ptr) const
@ -495,154 +523,152 @@ namespace MWSound
if(snditer != mActiveSaySounds.end())
{
mOutput->finishStream(snditer->second);
mUnusedStreams.push_back(snditer->second);
mActiveSaySounds.erase(snditer);
}
}
MWBase::SoundStreamPtr SoundManager::playTrack(const DecoderPtr& decoder, PlayType type)
Stream *SoundManager::playTrack(const DecoderPtr& decoder, Type type)
{
MWBase::SoundStreamPtr track;
if(!mOutput->isInitialized())
return track;
try
{
track.reset(new Stream(1.0f, volumeFromType(type), 1.0f, Play_NoEnv|type|Play_2D));
mOutput->streamSound(decoder, track);
return nullptr;
TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), track);
mActiveTracks.insert(iter, track);
}
catch(std::exception &e)
Stream *track = getStreamRef();
track->init(1.0f, volumeFromType(type), 1.0f, PlayMode::NoEnv|type|Play_2D);
if(!mOutput->streamSound(decoder, track))
{
std::cout <<"Sound Error: "<<e.what()<< std::endl;
mUnusedStreams.push_back(track);
return nullptr;
}
mActiveTracks.insert(
std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), track), track
);
return track;
}
void SoundManager::stopTrack(MWBase::SoundStreamPtr stream)
void SoundManager::stopTrack(Stream *stream)
{
mOutput->finishStream(stream);
TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), stream);
if(iter != mActiveTracks.end() && *iter == stream)
mActiveTracks.erase(iter);
mUnusedStreams.push_back(stream);
}
double SoundManager::getTrackTimeDelay(MWBase::SoundStreamPtr stream)
double SoundManager::getTrackTimeDelay(Stream *stream)
{
return mOutput->getStreamDelay(stream);
}
MWBase::SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, PlayType type, PlayMode mode, float offset)
Sound *SoundManager::playSound(const std::string& soundId, float volume, float pitch, Type type, PlayMode mode, float offset)
{
MWBase::SoundPtr sound;
if(!mOutput->isInitialized())
return sound;
try
{
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
float basevol = volumeFromType(type);
return nullptr;
sound.reset(new Sound(volume * sfx->mVolume, basevol, pitch, mode|type|Play_2D));
mOutput->playSound(sound, sfx->mHandle, offset);
if(sfx->mUses++ == 0)
{
SoundList::iterator iter = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), sfx);
if(iter != mUnusedBuffers.end())
mUnusedBuffers.erase(iter);
}
mActiveSounds[MWWorld::ConstPtr()].push_back(std::make_pair(sound, sfx));
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
if(!sfx) return nullptr;
Sound *sound = getSoundRef();
sound->init(volume * sfx->mVolume, volumeFromType(type), pitch, mode|type|Play_2D);
if(!mOutput->playSound(sound, sfx->mHandle, offset))
{
mUnusedSounds.push_back(sound);
return nullptr;
}
catch(std::exception&)
if(sfx->mUses++ == 0)
{
//std::cout <<"Sound Error: "<<e.what()<< std::endl;
sound.reset();
SoundList::iterator iter = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), sfx);
if(iter != mUnusedBuffers.end())
mUnusedBuffers.erase(iter);
}
mActiveSounds[MWWorld::ConstPtr()].push_back(std::make_pair(sound, sfx));
return sound;
}
MWBase::SoundPtr SoundManager::playSound3D(const MWWorld::ConstPtr &ptr, const std::string& soundId,
float volume, float pitch, PlayType type, PlayMode mode, float offset)
Sound *SoundManager::playSound3D(const MWWorld::ConstPtr &ptr, const std::string& soundId,
float volume, float pitch, Type type, PlayMode mode,
float offset)
{
MWBase::SoundPtr sound;
if(!mOutput->isInitialized())
return sound;
try
{
// Look up the sound in the ESM data
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
float basevol = volumeFromType(type);
const ESM::Position &pos = ptr.getRefData().getPosition();
const osg::Vec3f objpos(pos.asVec3());
return nullptr;
if((mode&Play_RemoveAtDistance) && (mListenerPos-objpos).length2() > 2000*2000)
return MWBase::SoundPtr();
// Look up the sound in the ESM data
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
if(!sfx) return nullptr;
// Only one copy of given sound can be played at time on ptr, so stop previous copy
stopSound3D(ptr, soundId);
const osg::Vec3f objpos(ptr.getRefData().getPosition().asVec3());
if((mode&PlayMode::RemoveAtDistance) && (mListenerPos-objpos).length2() > 2000*2000)
return nullptr;
if(!(mode&Play_NoPlayerLocal) && ptr == MWMechanics::getPlayer())
{
sound.reset(new Sound(volume * sfx->mVolume, basevol, pitch, mode|type|Play_2D));
mOutput->playSound(sound, sfx->mHandle, offset);
}
else
{
sound.reset(new Sound(objpos, volume * sfx->mVolume, basevol, pitch,
sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D));
mOutput->playSound3D(sound, sfx->mHandle, offset);
}
if(sfx->mUses++ == 0)
{
SoundList::iterator iter = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), sfx);
if(iter != mUnusedBuffers.end())
mUnusedBuffers.erase(iter);
}
mActiveSounds[ptr].push_back(std::make_pair(sound, sfx));
// Only one copy of given sound can be played at time on ptr, so stop previous copy
stopSound3D(ptr, soundId);
bool played;
Sound *sound = getSoundRef();
if(!(mode&PlayMode::NoPlayerLocal) && ptr == MWMechanics::getPlayer())
{
sound->init(volume * sfx->mVolume, volumeFromType(type), pitch, mode|type|Play_2D);
played = mOutput->playSound(sound, sfx->mHandle, offset);
}
catch(std::exception&)
else
{
//std::cout <<"Sound Error: "<<e.what()<< std::endl;
sound.reset();
sound->init(objpos, volume * sfx->mVolume, volumeFromType(type), pitch,
sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D);
played = mOutput->playSound3D(sound, sfx->mHandle, offset);
}
if(!played)
{
mUnusedSounds.push_back(sound);
return nullptr;
}
if(sfx->mUses++ == 0)
{
SoundList::iterator iter = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), sfx);
if(iter != mUnusedBuffers.end())
mUnusedBuffers.erase(iter);
}
mActiveSounds[ptr].push_back(std::make_pair(sound, sfx));
return sound;
}
MWBase::SoundPtr SoundManager::playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, PlayType type, PlayMode mode, float offset)
Sound *SoundManager::playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, Type type, PlayMode mode,
float offset)
{
MWBase::SoundPtr sound;
if(!mOutput->isInitialized())
return sound;
try
{
// Look up the sound in the ESM data
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
float basevol = volumeFromType(type);
return nullptr;
sound.reset(new Sound(initialPos, volume * sfx->mVolume, basevol, pitch,
sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D));
mOutput->playSound3D(sound, sfx->mHandle, offset);
if(sfx->mUses++ == 0)
{
SoundList::iterator iter = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), sfx);
if(iter != mUnusedBuffers.end())
mUnusedBuffers.erase(iter);
}
mActiveSounds[MWWorld::ConstPtr()].push_back(std::make_pair(sound, sfx));
// Look up the sound in the ESM data
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
if(!sfx) return nullptr;
Sound *sound = getSoundRef();
sound->init(initialPos, volume * sfx->mVolume, volumeFromType(type), pitch,
sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D);
if(!mOutput->playSound3D(sound, sfx->mHandle, offset))
{
mUnusedSounds.push_back(sound);
return nullptr;
}
catch(std::exception &)
if(sfx->mUses++ == 0)
{
//std::cout <<"Sound Error: "<<e.what()<< std::endl;
sound.reset();
SoundList::iterator iter = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), sfx);
if(iter != mUnusedBuffers.end())
mUnusedBuffers.erase(iter);
}
mActiveSounds[MWWorld::ConstPtr()].push_back(std::make_pair(sound, sfx));
return sound;
}
void SoundManager::stopSound(MWBase::SoundPtr sound)
void SoundManager::stopSound(Sound *sound)
{
if (sound.get())
if(sound)
mOutput->finishSound(sound);
}
@ -675,7 +701,7 @@ namespace MWSound
void SoundManager::stopSound(const MWWorld::CellStore *cell)
{
SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end())
for(;snditer != mActiveSounds.end();++snditer)
{
if(snditer->first != MWWorld::ConstPtr() &&
snditer->first != MWMechanics::getPlayer() &&
@ -685,18 +711,14 @@ namespace MWSound
for(;sndidx != snditer->second.end();++sndidx)
mOutput->finishSound(sndidx->first);
}
++snditer;
}
SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
while(sayiter != mActiveSaySounds.end())
for(;sayiter != mActiveSaySounds.end();++sayiter)
{
if(sayiter->first != MWWorld::ConstPtr() &&
sayiter->first != MWMechanics::getPlayer() &&
sayiter->first.getCell() == cell)
{
mOutput->finishStream(sayiter->second);
}
++sayiter;
}
}
@ -752,7 +774,7 @@ namespace MWSound
{
if(mOutput->isInitialized())
{
types &= Play_TypeMask;
types = types & Type::Mask;
mOutput->pauseSounds(types);
mPausedSoundTypes |= types;
}
@ -762,7 +784,7 @@ namespace MWSound
{
if(mOutput->isInitialized())
{
types &= types&Play_TypeMask&mPausedSoundTypes;
types = types & Type::Mask & mPausedSoundTypes;
mOutput->resumeSounds(types);
mPausedSoundTypes &= ~types;
}
@ -799,15 +821,12 @@ namespace MWSound
if(regn == NULL)
return;
std::vector<ESM::Region::SoundRef>::const_iterator soundIter;
if(total == 0)
{
soundIter = regn->mSoundList.begin();
while(soundIter != regn->mSoundList.end())
{
total += (int)soundIter->mChance;
++soundIter;
}
std::for_each(regn->mSoundList.cbegin(), regn->mSoundList.cend(),
[](const ESM::Region::SoundRef &sndref) -> void
{ total += (int)sndref.mChance; }
);
if(total == 0)
return;
}
@ -815,32 +834,36 @@ namespace MWSound
int r = Misc::Rng::rollDice(total);
int pos = 0;
soundIter = regn->mSoundList.begin();
while(soundIter != regn->mSoundList.end())
{
if(r - pos < soundIter->mChance)
std::find_if_not(regn->mSoundList.cbegin(), regn->mSoundList.cend(),
[&pos, r, this](const ESM::Region::SoundRef &sndref) -> bool
{
playSound(soundIter->mSound.toString(), 1.0f, 1.0f);
break;
if(r - pos < sndref.mChance)
{
playSound(sndref.mSound.toString(), 1.0f, 1.0f);
// Played this sound, stop iterating
return false;
}
pos += sndref.mChance;
// Not this sound, keep iterating
return true;
}
pos += soundIter->mChance;
++soundIter;
}
);
}
void SoundManager::updateWaterSound(float /*duration*/)
{
static const ESM::Cell *LastCell;
MWBase::World* world = MWBase::Environment::get().getWorld();
const MWWorld::ConstPtr player = world->getPlayerPtr();
osg::Vec3f pos = player.getRefData().getPosition().asVec3();
const ESM::Cell *curcell = player.getCell()->getCell();
float volume = 0.0f;
const std::string& soundId = player.getCell()->isExterior() ? mNearWaterOutdoorID : mNearWaterIndoorID;
if (!mListenerUnderwater)
{
if (player.getCell()->getCell()->hasWater())
if (curcell->hasWater())
{
float dist = std::abs(player.getCell()->getWaterLevel() - pos.z());
@ -885,38 +908,43 @@ namespace MWSound
if (volume == 0.0f)
{
mOutput->finishSound(mNearWaterSound);
mNearWaterSound.reset();
mNearWaterSound = nullptr;
}
else
{
bool soundIdChanged = false;
Sound_Buffer* sfx = lookupSound(Misc::StringUtils::lowerCase(soundId));
for (SoundMap::const_iterator snditer = mActiveSounds.begin(); snditer != mActiveSounds.end(); ++snditer)
Sound_Buffer *sfx = lookupSound(soundId);
if(LastCell != curcell)
{
for (SoundBufferRefPairList::const_iterator pairiter = snditer->second.begin(); pairiter != snditer->second.end(); ++pairiter)
LastCell = curcell;
SoundMap::const_iterator snditer = mActiveSounds.find(MWWorld::Ptr());
if(snditer != mActiveSounds.end())
{
if (pairiter->first == mNearWaterSound)
{
if (pairiter->second != sfx)
soundIdChanged = true;
break;
}
SoundBufferRefPairList::const_iterator pairiter = std::find_if(
snditer->second.begin(), snditer->second.end(),
[this](const SoundBufferRefPairList::value_type &item) -> bool
{ return mNearWaterSound == item.first; }
);
if (pairiter != snditer->second.end() && pairiter->second != sfx)
soundIdChanged = true;
}
}
if (soundIdChanged)
if(soundIdChanged)
{
mOutput->finishSound(mNearWaterSound);
mNearWaterSound = playSound(soundId, volume, 1.0f, Play_TypeSfx, Play_Loop);
mNearWaterSound = playSound(soundId, volume, 1.0f, Type::Sfx, PlayMode::Loop);
}
else if (sfx)
mNearWaterSound->setVolume(volume * sfx->mVolume);
}
}
else if (volume > 0.0f)
mNearWaterSound = playSound(soundId, volume, 1.0f, Play_TypeSfx, Play_Loop);
{
LastCell = curcell;
mNearWaterSound = playSound(soundId, volume, 1.0f, Type::Sfx, PlayMode::Loop);
}
}
void SoundManager::updateSounds(float duration)
@ -939,7 +967,7 @@ namespace MWSound
else if(mUnderwaterSound)
{
mOutput->finishSound(mUnderwaterSound);
mUnderwaterSound.reset();
mUnderwaterSound = nullptr;
}
mOutput->startUpdate();
@ -956,11 +984,14 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end())
{
MWWorld::ConstPtr ptr = snditer->first;
SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
while(sndidx != snditer->second.end())
{
MWWorld::ConstPtr ptr = snditer->first;
MWBase::SoundPtr sound = sndidx->first;
Sound *sound;
Sound_Buffer *sfx;
std::tie(sound, sfx) = *sndidx;
if(!ptr.isEmpty() && sound->getIs3D())
{
const ESM::Position &pos = ptr.getRefData().getPosition();
@ -977,7 +1008,11 @@ namespace MWSound
if(!mOutput->isSoundPlaying(sound))
{
mOutput->finishSound(sound);
Sound_Buffer *sfx = sndidx->second;
mUnusedSounds.push_back(sound);
if(sound == mUnderwaterSound)
mUnderwaterSound = nullptr;
if(sound == mNearWaterSound)
mNearWaterSound = nullptr;
if(sfx->mUses-- == 1)
mUnusedBuffers.push_front(sfx);
sndidx = snditer->second.erase(sndidx);
@ -991,7 +1026,7 @@ namespace MWSound
}
}
if(snditer->second.empty())
mActiveSounds.erase(snditer++);
snditer = mActiveSounds.erase(snditer);
else
++snditer;
}
@ -1000,7 +1035,7 @@ namespace MWSound
while(sayiter != mActiveSaySounds.end())
{
MWWorld::ConstPtr ptr = sayiter->first;
MWBase::SoundStreamPtr sound = sayiter->second;
Stream *sound = sayiter->second;
if(!ptr.isEmpty() && sound->getIs3D())
{
MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1017,6 +1052,7 @@ namespace MWSound
if(!mOutput->isStreamPlaying(sound))
{
mOutput->finishStream(sound);
mUnusedStreams.push_back(sound);
mActiveSaySounds.erase(sayiter++);
}
else
@ -1031,7 +1067,7 @@ namespace MWSound
TrackList::iterator trkiter = mActiveTracks.begin();
for(;trkiter != mActiveTracks.end();++trkiter)
{
MWBase::SoundStreamPtr sound = *trkiter;
Stream *sound = *trkiter;
if(!mOutput->isStreamPlaying(sound))
{
mOutput->finishStream(sound);
@ -1049,8 +1085,8 @@ namespace MWSound
if(mListenerUnderwater)
{
// Play underwater sound (after updating sounds)
if(!(mUnderwaterSound && mOutput->isSoundPlaying(mUnderwaterSound)))
mUnderwaterSound = playSound("Underwater", 1.0f, 1.0f, Play_TypeSfx, Play_LoopNoEnv);
if(!mUnderwaterSound)
mUnderwaterSound = playSound("Underwater", 1.0f, 1.0f, Type::Sfx, PlayMode::LoopNoEnv);
}
mOutput->finishUpdate();
}
@ -1105,7 +1141,7 @@ namespace MWSound
SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx)
{
MWBase::SoundPtr sound = sndidx->first;
Sound *sound = sndidx->first;
sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateSound(sound);
}
@ -1113,14 +1149,14 @@ namespace MWSound
SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
for(;sayiter != mActiveSaySounds.end();++sayiter)
{
MWBase::SoundStreamPtr sound = sayiter->second;
Stream *sound = sayiter->second;
sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateStream(sound);
}
TrackList::iterator trkiter = mActiveTracks.begin();
for(;trkiter != mActiveTracks.end();++trkiter)
{
MWBase::SoundStreamPtr sound = *trkiter;
Stream *sound = *trkiter;
sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateStream(sound);
}
@ -1146,16 +1182,16 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.find(old);
if(snditer != mActiveSounds.end())
{
SoundBufferRefPairList sndlist = snditer->second;
SoundBufferRefPairList sndlist = std::move(snditer->second);
mActiveSounds.erase(snditer);
mActiveSounds[updated] = sndlist;
mActiveSounds.emplace(updated, std::move(sndlist));
}
SaySoundMap::iterator sayiter = mActiveSaySounds.find(old);
if(sayiter != mActiveSaySounds.end())
{
MWBase::SoundStreamPtr stream = sayiter->second;
Stream *stream = sayiter->second;
mActiveSaySounds.erase(sayiter);
mActiveSaySounds[updated] = stream;
mActiveSaySounds.emplace(updated, stream);
}
}
@ -1233,6 +1269,7 @@ namespace MWSound
for(;sndidx != snditer->second.end();++sndidx)
{
mOutput->finishSound(sndidx->first);
mUnusedSounds.push_back(sndidx->first);
Sound_Buffer *sfx = sndidx->second;
if(sfx->mUses-- == 1)
mUnusedBuffers.push_front(sfx);
@ -1241,14 +1278,20 @@ namespace MWSound
mActiveSounds.clear();
SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
for(;sayiter != mActiveSaySounds.end();++sayiter)
{
mOutput->finishStream(sayiter->second);
mUnusedStreams.push_back(sayiter->second);
}
mActiveSaySounds.clear();
TrackList::iterator trkiter = mActiveTracks.begin();
for(;trkiter != mActiveTracks.end();++trkiter)
{
mOutput->finishStream(*trkiter);
mUnusedStreams.push_back(*trkiter);
}
mActiveTracks.clear();
mUnderwaterSound.reset();
mNearWaterSound.reset();
mUnderwaterSound = nullptr;
mNearWaterSound = nullptr;
stopMusic();
}
}

@ -29,6 +29,7 @@ namespace MWSound
class Sound_Output;
struct Sound_Decoder;
class Sound;
class Stream;
class Sound_Buffer;
enum Environment {
@ -49,7 +50,7 @@ namespace MWSound
std::unique_ptr<Sound_Output> mOutput;
// Caches available music tracks by <playlist name, (sound files) >
std::map<std::string, std::vector<std::string> > mMusicFiles;
std::unordered_map<std::string, std::vector<std::string>> mMusicFiles;
std::unordered_map<std::string, std::vector<int>> mMusicToPlay; // A list with music files not yet played
std::string mLastPlayedMusic; // The music file that was last played
@ -74,25 +75,31 @@ namespace MWSound
size_t mBufferCacheMax;
size_t mBufferCacheSize;
typedef std::map<std::string,Sound_Buffer*> NameBufferMap;
typedef std::unordered_map<std::string,Sound_Buffer*> NameBufferMap;
NameBufferMap mBufferNameMap;
// NOTE: unused buffers are stored in front-newest order.
typedef std::deque<Sound_Buffer*> SoundList;
SoundList mUnusedBuffers;
typedef std::pair<MWBase::SoundPtr,Sound_Buffer*> SoundBufferRefPair;
std::unique_ptr<std::deque<Sound>> mSounds;
std::vector<Sound*> mUnusedSounds;
std::unique_ptr<std::deque<Stream>> mStreams;
std::vector<Stream*> mUnusedStreams;
typedef std::pair<MWBase::Sound*,Sound_Buffer*> SoundBufferRefPair;
typedef std::vector<SoundBufferRefPair> SoundBufferRefPairList;
typedef std::map<MWWorld::ConstPtr,SoundBufferRefPairList> SoundMap;
SoundMap mActiveSounds;
typedef std::map<MWWorld::ConstPtr,MWBase::SoundStreamPtr> SaySoundMap;
typedef std::map<MWWorld::ConstPtr,Stream*> SaySoundMap;
SaySoundMap mActiveSaySounds;
typedef std::vector<MWBase::SoundStreamPtr> TrackList;
typedef std::vector<Stream*> TrackList;
TrackList mActiveTracks;
MWBase::SoundStreamPtr mMusic;
Stream *mMusic;
std::string mCurrentPlaylist;
bool mListenerUnderwater;
@ -102,8 +109,8 @@ namespace MWSound
int mPausedSoundTypes;
MWBase::SoundPtr mUnderwaterSound;
MWBase::SoundPtr mNearWaterSound;
Sound *mUnderwaterSound;
Sound *mNearWaterSound;
Sound_Buffer *insertSound(const std::string &soundId, const ESM::Sound *sound);
@ -113,7 +120,10 @@ namespace MWSound
// returns a decoder to start streaming
DecoderPtr loadVoice(const std::string &voicefile);
MWBase::SoundStreamPtr playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal);
Sound *getSoundRef();
Stream *getStreamRef();
Stream *playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal);
void streamMusicFull(const std::string& filename);
void advanceMusic(const std::string& filename);
@ -125,7 +135,7 @@ namespace MWSound
std::string mNextMusic;
float volumeFromType(PlayType type) const;
float volumeFromType(Type type) const;
SoundManager(const SoundManager &rhs);
SoundManager& operator=(const SoundManager &rhs);
@ -176,33 +186,33 @@ namespace MWSound
/// and get an average loudness value (scale [0,1]) at the current time position.
/// If the actor is not saying anything, returns 0.
virtual MWBase::SoundStreamPtr playTrack(const DecoderPtr& decoder, PlayType type);
virtual Stream *playTrack(const DecoderPtr& decoder, Type type);
///< Play a 2D audio track, using a custom decoder
virtual void stopTrack(MWBase::SoundStreamPtr stream);
virtual void stopTrack(Stream *stream);
///< Stop the given audio track from playing
virtual double getTrackTimeDelay(MWBase::SoundStreamPtr stream);
virtual double getTrackTimeDelay(Stream *stream);
///< Retives the time delay, in seconds, of the audio track (must be a sound
/// returned by \ref playTrack). Only intended to be called by the track
/// decoder's read method.
virtual MWBase::SoundPtr playSound(const std::string& soundId, float volume, float pitch, PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal, float offset=0);
virtual Sound *playSound(const std::string& soundId, float volume, float pitch, Type type=Type::Sfx, PlayMode mode=PlayMode::Normal, float offset=0);
///< Play a sound, independently of 3D-position
///< @param offset Number of seconds into the sound to start playback.
virtual MWBase::SoundPtr playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId,
float volume, float pitch, PlayType type=Play_TypeSfx,
PlayMode mode=Play_Normal, float offset=0);
virtual Sound *playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId,
float volume, float pitch, Type type=Type::Sfx,
PlayMode mode=PlayMode::Normal, float offset=0);
///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified.
///< @param offset Number of seconds into the sound to start playback.
virtual MWBase::SoundPtr playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, PlayType type, PlayMode mode, float offset=0);
virtual Sound *playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, Type type, PlayMode mode, float offset=0);
///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using Sound::setPosition.
///< @param offset Number of seconds into the sound to start playback.
virtual void stopSound(MWBase::SoundPtr sound);
virtual void stopSound(Sound *sound);
///< Stop the given sound from playing
/// @note no-op if \a sound is null
@ -227,10 +237,10 @@ namespace MWSound
virtual bool getSoundPlaying(const MWWorld::ConstPtr &reference, const std::string& soundId) const;
///< Is the given sound currently playing on the given object?
virtual void pauseSounds(int types=Play_TypeMask);
virtual void pauseSounds(int types);
///< Pauses all currently playing sounds, including music.
virtual void resumeSounds(int types=Play_TypeMask);
virtual void resumeSounds(int types);
///< Resumes all previously paused sounds.
virtual void update(float duration);

@ -27,18 +27,18 @@ void MWWorld::Action::execute (const Ptr& actor, bool noSound)
{
if(!mSoundId.empty() && !noSound)
{
MWBase::SoundManager::PlayMode envType = MWBase::SoundManager::Play_Normal;
MWSound::PlayMode envType = MWSound::PlayMode::Normal;
// Action sounds should not have a distortion in GUI mode
// example: take an item or drink a potion underwater
if (actor == MWMechanics::getPlayer() && MWBase::Environment::get().getWindowManager()->isGuiMode())
{
envType = MWBase::SoundManager::Play_NoEnv;
envType = MWSound::PlayMode::NoEnv;
}
if(mKeepSound && actor == MWMechanics::getPlayer())
MWBase::Environment::get().getSoundManager()->playSound(mSoundId, 1.0, 1.0,
MWBase::SoundManager::Play_TypeSfx, envType, mSoundOffset
MWSound::Type::Sfx, envType, mSoundOffset
);
else
{
@ -46,13 +46,11 @@ void MWWorld::Action::execute (const Ptr& actor, bool noSound)
if(mKeepSound)
MWBase::Environment::get().getSoundManager()->playSound3D(
(local ? actor : mTarget).getRefData().getPosition().asVec3(),
mSoundId, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx,
envType, mSoundOffset
mSoundId, 1.0, 1.0, MWSound::Type::Sfx, envType, mSoundOffset
);
else
MWBase::Environment::get().getSoundManager()->playSound3D(local ? actor : mTarget,
mSoundId, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx,
envType, mSoundOffset
mSoundId, 1.0, 1.0, MWSound::Type::Sfx, envType, mSoundOffset
);
}
}

@ -276,6 +276,29 @@ namespace MWWorld
mAutoMove = false;
mForwardBackward = 0;
mTeleported = false;
mAttackingOrSpell = false;
mCurrentCrimeId = -1;
mPaidCrimeId = -1;
mLastKnownExteriorPosition = osg::Vec3f(0,0,0);
for (int i=0; i<ESM::Skill::Length; ++i)
{
mSaveSkills[i].setBase(0);
mSaveSkills[i].setModifier(0);
}
for (int i=0; i<ESM::Attribute::Length; ++i)
{
mSaveAttributes[i].setBase(0);
mSaveAttributes[i].setModifier(0);
}
mMarkedPosition.pos[0] = 0;
mMarkedPosition.pos[1] = 0;
mMarkedPosition.pos[2] = 0;
mMarkedPosition.rot[0] = 0;
mMarkedPosition.rot[1] = 0;
mMarkedPosition.rot[2] = 0;
}
void Player::write (ESM::ESMWriter& writer, Loading::Listener& progress) const

@ -283,7 +283,8 @@ namespace MWWorld
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
for (size_t it = 0; it != state.mSoundIds.size(); it++)
{
MWBase::SoundPtr sound = sndMgr->playSound3D(pos, state.mSoundIds.at(it), 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
MWBase::Sound *sound = sndMgr->playSound3D(pos, state.mSoundIds.at(it), 1.0f, 1.0f,
MWSound::Type::Sfx, MWSound::PlayMode::Loop);
if (sound)
state.mSounds.push_back(sound);
}
@ -377,10 +378,9 @@ namespace MWWorld
MWBase::Environment::get().getWorld()->explodeSpell(pos, it->mEffects, caster, result.mHitObject,
ESM::RT_Target, it->mSpellId, it->mSourceName);
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
for (size_t soundIter = 0; soundIter != it->mSounds.size(); soundIter++)
{
MWBase::Environment::get().getSoundManager()->stopSound(it->mSounds.at(soundIter));
}
sndMgr->stopSound(it->mSounds.at(soundIter));
mParent->removeChild(it->mNode);
@ -581,11 +581,10 @@ namespace MWWorld
createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), true, true, lightDiffuseColor, texture);
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
for (size_t soundIter = 0; soundIter != state.mSoundIds.size(); soundIter++)
{
MWBase::SoundPtr sound = sndMgr->playSound3D(esm.mPosition, state.mSoundIds.at(soundIter), 1.0f, 1.0f,
MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
MWBase::Sound *sound = sndMgr->playSound3D(esm.mPosition, state.mSoundIds.at(soundIter), 1.0f, 1.0f,
MWSound::Type::Sfx, MWSound::PlayMode::Loop);
if (sound)
state.mSounds.push_back(sound);
}

@ -103,7 +103,7 @@ namespace MWWorld
bool mStack;
std::vector<MWBase::SoundPtr> mSounds;
std::vector<MWBase::Sound*> mSounds;
std::vector<std::string> mSoundIds;
};

@ -531,7 +531,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager& rendering, const Fall
, mQueuedWeather(0)
, mRegions()
, mResult()
, mAmbientSound()
, mAmbientSound(nullptr)
, mPlayingSoundID()
{
mTimeSettings.mNightStart = mSunsetTime + mSunsetDuration;
@ -731,19 +731,21 @@ void WeatherManager::update(float duration, bool paused)
{
stopSounds();
if (!mResult.mAmbientLoopSoundID.empty())
mAmbientSound = MWBase::Environment::get().getSoundManager()->playSound(mResult.mAmbientLoopSoundID, mResult.mAmbientSoundVolume, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
mAmbientSound = MWBase::Environment::get().getSoundManager()->playSound(
mResult.mAmbientLoopSoundID, mResult.mAmbientSoundVolume, 1.0,
MWSound::Type::Sfx, MWSound::PlayMode::Loop
);
mPlayingSoundID = mResult.mAmbientLoopSoundID;
}
if (mAmbientSound.get())
else if (mAmbientSound)
mAmbientSound->setVolume(mResult.mAmbientSoundVolume);
}
void WeatherManager::stopSounds()
{
if (mAmbientSound.get())
if (mAmbientSound)
MWBase::Environment::get().getSoundManager()->stopSound(mAmbientSound);
mAmbientSound.reset();
mAmbientSound = nullptr;
mPlayingSoundID.clear();
}

@ -288,7 +288,7 @@ namespace MWWorld
std::map<std::string, RegionWeather> mRegions;
MWRender::WeatherResult mResult;
MWBase::SoundPtr mAmbientSound;
MWBase::Sound *mAmbientSound;
std::string mPlayingSoundID;
void addWeather(const std::string& name,

@ -218,4 +218,89 @@ actually modify the contents of the game.
Subsection to come...
=====================
Adding to an npc
****************
The simplest way is probably to add it to the inventory of a shopkeeper.
An obvious candidate is Arrille in Seyda Neen - he's quick to find in a new game
and he's easy to find in the CS as his name comes early alphabetically.
.. figure:: _static/images/chapter-1/Ring_to_Arrille.png
:alt: Putting the ring into Arrille's inventory
Open the CS and open the *Objects* table (*World**Objects*).
Scroll down to Arrille, or use a filter like !string("ID","arrille").
Open another pane to edit him - either right click and select edit or use the
shortcut (default is shift double-click). Scroll down to the inventory section
and right click to add a new row. Type in the id of the ring (or find it in the
object pane, and drag and drop). Set the number of rings for him to stock - with
a negative number indicating that he will restock again to maintain that level.
However, it's an attractive item, so he will probably wear it rather than sell it.
So set his stock level too high for him to wear them all (3 works, 2 might do).
Another possibilty, again in Seyda Neen making it easy to access, would be for
Fargoth to give it to the player in exchange for his healing ring.
.. figure:: _static/images/chapter-1/Ring_to_Fargoth_1.png
:alt: Editing Fargoth to give ring to player
Open the *Topicinfo* Table (*Characters**Topic Infos*). Use a filter !string(Topic,ring)
and select the row with a response starting with "You found it!". Edit the record,
firstly by adding a bit more to the response, then by adding a line to the script
to give the ring to the player - the same as used earlier in the console
.. code::
player->AddItem "ring_night_vision" 1
.. figure:: _static/images/chapter-1/Ring_to_Fargoth_2.png
:alt: Editing Fargoth to give ring to player
Navigation in the CS
====================
This is probably a suitable place to start talking about how navigation differs from TESCS
in vanilla Morrowind.
There is advice in Scripting for Dummies, the definitive manual for Morrowind Scripting:
"If you give your scripts a common tag, that will make it easier to jump between the
different scripts of your project, e.g. start every script name with AA_Scriptname
this will put them right at the beginning of the list and keep them neatly together."
This is valid for the rather poorer navigation facilities there, but it's not sensible for
the OpenMW CS. Some modders took it further, and started script names and object id with numbers,
typically "1", to bring the items even earlier in the default alphabetical sorts. In fact
the CS won't allow names/ids to start with numbers or to include ".".
There are better options available:
Filtering, which isn't available at all in TESCS - put in a filter like
!string("ID",".*ring.*")
to find all IDs which contain the string "ring"
Sorting, which is available in some parts of TESCS, but not for scripts (other than script names being
sorted in ascending order)- hence the recommendation
Typically the "Modified" column is useful here - most items will have "Base" status, unchanged from
the base game.
"Added" status" will cover those items added in this addon.
"Modified" status will cover items from the base game which have been modified in this addon.
Click on the top of the column to toggle between ascending and descending order - thus between "Added"
and "Modified" at the top. Or put your desired modified status into a filter then sort alpabetically
on a different column.
Checking your new addon
=======================
Launch OpenMW and in the launcher under *Data Files* check your addon, if it's not
already checked. Load a game and make your way to Seyda Neen - or start a new game.
Check whether Arrille has one (or more) for sale, and whether Fargoth give you one
when you return his healing ring.

@ -12,14 +12,14 @@ OpenMW is designed to be able to use all the normal Morrowind mod files such as
Multiple Data Folders
---------------------
The largest difference between OpenMW and Morrowind in terms of data structure is OpenMW's support of multiple data folders. This has many advantages, especially when it comes to unistalling mods and preventing unintentional overwrites of files.
The largest difference between OpenMW and Morrowind in terms of data structure is OpenMW's support of multiple data folders. This has many advantages, especially when it comes to uninstalling mods and preventing unintentional overwrites of files.
.. warning::
Most mods can still be installed into the root OpenMW data folder, but this is not recommended.
To install mods via this new feature:
#. Open ``openmw.cfg`` with your preffered text editor. It is located as described in :doc:`paths` and *not* in your OpenMW root directory.
#. Open ``openmw.cfg`` with your preferred text editor. It is located as described in :doc:`paths` and *not* in your OpenMW root directory.
#. Find or search for ``data=``. This is located very near the bottom of the file.
#. Add a new line below this line and make a new entry of the format ``data="path/to/your/mod"``
#. Make as many of these entries as you need for each mod folder you want to include.

@ -313,11 +313,11 @@ voice volume = 0.8
# Minimum size to use for the sound buffer cache, in MB. When the cache is
# filled, old buffers will be unloaded until it's using no more than this much
# memory. Must be less than or equal to 'buffer cache max'.
buffer cache min = 14
buffer cache min = 56
# Maximum size to use for the sound buffer cache, in MB. The cache can use up
# to this much memory until old buffers get purged.
buffer cache max = 16
buffer cache max = 64
# Specifies whether to enable HRTF processing. Valid values are: -1 = auto,
# 0 = off, 1 = on.

Loading…
Cancel
Save