mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
add effects extension support
This commit is contained in:
parent
3637855581
commit
923c694ab4
2 changed files with 134 additions and 7 deletions
|
|
@ -40,6 +40,20 @@ static bool check_alc_errors(ALCdevice* device, const char* context) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti = nullptr;
|
||||
static LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots = nullptr;
|
||||
static LPALGENEFFECTS alGenEffects = nullptr;
|
||||
static LPALDELETEEFFECTS alDeleteEffects = nullptr;
|
||||
static LPALISEFFECT alIsEffect = nullptr;
|
||||
static LPALEFFECTI alEffecti = nullptr;
|
||||
static LPALEFFECTF alEffectf = nullptr;
|
||||
static LPALGENFILTERS alGenFilters = nullptr;
|
||||
static LPALDELETEFILTERS alDeleteFilters = nullptr;
|
||||
static LPALISFILTER alIsFilter = nullptr;
|
||||
static LPALFILTERI alFilteri = nullptr;
|
||||
static LPALFILTERF alFilterf = nullptr;
|
||||
|
||||
|
||||
ALSound::ALSound(
|
||||
ALAudio* al, uint buffer, const std::shared_ptr<PCM>& pcm, bool keepPCM
|
||||
)
|
||||
|
|
@ -382,6 +396,10 @@ void ALSpeaker::play() {
|
|||
AL_GAIN,
|
||||
volume * p_channel->getVolume()
|
||||
));
|
||||
if (al->useEffects) {
|
||||
AL_CHECK(alSource3i(source, AL_AUXILIARY_SEND_FILTER, al->effectSlots[0], 0, al->filters[0]));
|
||||
//AL_CHECK(alSourcei(source, AL_DIRECT_FILTER, al->filters[0]));
|
||||
}
|
||||
AL_CHECK(alSourcePlay(source));
|
||||
}
|
||||
|
||||
|
|
@ -455,15 +473,14 @@ int ALSpeaker::getPriority() const {
|
|||
return priority;
|
||||
}
|
||||
|
||||
|
||||
bool ALSpeaker::isManuallyStopped() const {
|
||||
return manuallyStopped;
|
||||
}
|
||||
|
||||
static bool alc_enumeration_ext = false;
|
||||
|
||||
ALAudio::ALAudio(ALCdevice* device, ALCcontext* context)
|
||||
: device(device), context(context) {
|
||||
ALAudio::ALAudio(ALCdevice* device, ALCcontext* context, bool useEffects)
|
||||
: device(device), context(context), useEffects(useEffects) {
|
||||
ALCint size;
|
||||
alcGetIntegerv(device, ALC_ATTRIBUTES_SIZE, 1, &size);
|
||||
std::vector<ALCint> attrs(size);
|
||||
|
|
@ -487,6 +504,11 @@ ALAudio::ALAudio(ALCdevice* device, ALCcontext* context)
|
|||
}
|
||||
|
||||
alDopplerFactor(1.0 / 3.0);
|
||||
alGetError();
|
||||
|
||||
if (useEffects) {
|
||||
initEffects();
|
||||
}
|
||||
}
|
||||
|
||||
ALAudio::~ALAudio() {
|
||||
|
|
@ -513,6 +535,58 @@ ALAudio::~ALAudio() {
|
|||
context = nullptr;
|
||||
}
|
||||
|
||||
void ALAudio::initEffects() {
|
||||
for (uint i = 0; i < effectSlots.size(); i++) {
|
||||
alGenAuxiliaryEffectSlots(1, &effectSlots[i]);
|
||||
if (alGetError() != AL_NO_ERROR) {
|
||||
logger.error() << "could not to create aux effect slot #" << i;
|
||||
useEffects = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (uint i = 0; i < effects.size(); i++) {
|
||||
alGenEffects(1, &effects[i]);
|
||||
if (alGetError() != AL_NO_ERROR || !alIsEffect(effects[i])) {
|
||||
logger.error() << "could not to create effect #" << i;
|
||||
useEffects = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (uint i = 0; i < filters.size(); i++) {
|
||||
alGenFilters(1, &filters[i]);
|
||||
if (alGetError() != AL_NO_ERROR || !alIsFilter(filters[i])) {
|
||||
logger.error() << "could not to create filter #" << i;
|
||||
useEffects = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create reverb effect
|
||||
alEffecti(effects[0], AL_EFFECT_TYPE, AL_EFFECT_REVERB);
|
||||
if (alGetError() != AL_NO_ERROR) {
|
||||
logger.error() << "reverb effect is not supported";
|
||||
useEffects = false;
|
||||
return;
|
||||
}
|
||||
alEffectf(effects[0], AL_REVERB_DECAY_TIME, 1.0f);
|
||||
|
||||
// Create lowpass filter
|
||||
alFilteri(filters[0], AL_FILTER_TYPE, AL_FILTER_LOWPASS);
|
||||
if (alGetError() != AL_NO_ERROR) {
|
||||
logger.error() << "lowpass filter is not supported";
|
||||
useEffects = false;
|
||||
return;
|
||||
}
|
||||
alFilterf(filters[0], AL_LOWPASS_GAIN, 1.0f);
|
||||
alFilterf(filters[0], AL_LOWPASS_GAINHF, 0.1f);
|
||||
|
||||
// Attach effect to aux effect slot
|
||||
alAuxiliaryEffectSloti(effectSlots[0], AL_EFFECTSLOT_EFFECT, effects[0]);
|
||||
if (alGetError() == AL_NO_ERROR) {
|
||||
logger.info() << "successfully loaded effect into effect slot";
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Sound> ALAudio::createSound(
|
||||
std::shared_ptr<PCM> pcm, bool keepPCM
|
||||
) {
|
||||
|
|
@ -592,19 +666,62 @@ std::unique_ptr<InputDevice> ALAudio::openInputDevice(
|
|||
);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static bool get_proc_address(const char* name, T& ptr) {
|
||||
ptr = (T) alGetProcAddress(name);
|
||||
return ptr != nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<ALAudio> ALAudio::create() {
|
||||
alc_enumeration_ext = alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT");
|
||||
|
||||
ALCdevice* device = alcOpenDevice(nullptr);
|
||||
if (device == nullptr) return nullptr;
|
||||
if (device == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
bool effects = true;
|
||||
ALint attribs[4] {};
|
||||
if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE) {
|
||||
logger.info() << "AL effects extension present";
|
||||
attribs[0] = ALC_MAX_AUXILIARY_SENDS;
|
||||
attribs[1] = 4;
|
||||
} else {
|
||||
logger.warning() << "AL effects extension is not supported";
|
||||
effects = false;
|
||||
}
|
||||
ALCcontext* context = alcCreateContext(device, nullptr);
|
||||
if (!alcMakeContextCurrent(context)) {
|
||||
alcCloseDevice(device);
|
||||
return nullptr;
|
||||
}
|
||||
AL_CHECK();
|
||||
|
||||
ALCint sends = 0;
|
||||
alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &sends);
|
||||
logger.info() << "device supports " << sends << " aux sends per source";
|
||||
|
||||
if (effects) {
|
||||
bool ok = get_proc_address("alAuxiliaryEffectSloti", alAuxiliaryEffectSloti)
|
||||
&& get_proc_address("alGenAuxiliaryEffectSlots", alGenAuxiliaryEffectSlots)
|
||||
&& get_proc_address("alGenEffects", alGenEffects)
|
||||
&& get_proc_address("alDeleteEffects", alDeleteEffects)
|
||||
&& get_proc_address("alIsEffect", alIsEffect)
|
||||
&& get_proc_address("alEffecti", alEffecti)
|
||||
&& get_proc_address("alEffectf", alEffectf)
|
||||
&& get_proc_address("alGenFilters", alGenFilters)
|
||||
&& get_proc_address("alDeleteFilters", alDeleteFilters)
|
||||
&& get_proc_address("alIsFilter", alIsFilter)
|
||||
&& get_proc_address("alFilteri", alFilteri)
|
||||
&& get_proc_address("alFilterf", alFilterf)
|
||||
;
|
||||
if (!ok) {
|
||||
logger.error() << "could not get effects extension function pointers";
|
||||
effects = false;
|
||||
}
|
||||
}
|
||||
|
||||
logger.info() << "initialized";
|
||||
return std::make_unique<ALAudio>(device, context);
|
||||
return std::make_unique<ALAudio>(device, context, effects);
|
||||
}
|
||||
|
||||
uint ALAudio::getFreeSource() {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -12,9 +13,11 @@
|
|||
#ifdef __APPLE__
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAL/alc.h>
|
||||
#include <OpenAL/alext.h>
|
||||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <AL/alext.h>
|
||||
#endif
|
||||
|
||||
namespace audio {
|
||||
|
|
@ -176,10 +179,17 @@ namespace audio {
|
|||
|
||||
std::vector<uint> allbuffers;
|
||||
std::vector<uint> freebuffers;
|
||||
|
||||
uint maxSources = 256;
|
||||
|
||||
void initEffects();
|
||||
public:
|
||||
ALAudio(ALCdevice* device, ALCcontext* context);
|
||||
std::array<uint, 2> effectSlots;
|
||||
std::array<uint, 2> effects;
|
||||
std::array<uint, 1> filters;
|
||||
|
||||
bool useEffects;
|
||||
|
||||
ALAudio(ALCdevice* device, ALCcontext* context, bool effects);
|
||||
~ALAudio();
|
||||
|
||||
uint getFreeSource();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue