123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733 |
- /**
- * Copyright (c) 2006-2020 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
- #include "Audio.h"
- #include "common/delay.h"
- #include "RecordingDevice.h"
- #include "sound/Decoder.h"
- #include <cstdlib>
- #include <iostream>
- #ifdef LOVE_IOS
- #include "common/ios.h"
- #endif
- namespace love
- {
- namespace audio
- {
- namespace openal
- {
- Audio::PoolThread::PoolThread(Pool *pool)
- : pool(pool)
- , finish(false)
- {
- threadName = "AudioPool";
- }
- Audio::PoolThread::~PoolThread()
- {
- }
- void Audio::PoolThread::threadFunction()
- {
- while (true)
- {
- {
- thread::Lock lock(mutex);
- if (finish)
- {
- return;
- }
- }
- pool->update();
- sleep(5);
- }
- }
- void Audio::PoolThread::setFinish()
- {
- thread::Lock lock(mutex);
- finish = true;
- }
- ALenum Audio::getFormat(int bitDepth, int channels)
- {
- if (bitDepth != 8 && bitDepth != 16)
- return AL_NONE;
- if (channels == 1)
- return bitDepth == 8 ? AL_FORMAT_MONO8 : AL_FORMAT_MONO16;
- else if (channels == 2)
- return bitDepth == 8 ? AL_FORMAT_STEREO8 : AL_FORMAT_STEREO16;
- #ifdef AL_EXT_MCFORMATS
- else if (alIsExtensionPresent("AL_EXT_MCFORMATS"))
- {
- if (channels == 6)
- return bitDepth == 8 ? AL_FORMAT_51CHN8 : AL_FORMAT_51CHN16;
- else if (channels == 8)
- return bitDepth == 8 ? AL_FORMAT_71CHN8 : AL_FORMAT_71CHN16;
- }
- #endif
- return AL_NONE;
- }
- Audio::Audio()
- : device(nullptr)
- , context(nullptr)
- , pool(nullptr)
- , poolThread(nullptr)
- , distanceModel(DISTANCE_INVERSE_CLAMPED)
- {
- #if defined(LOVE_LINUX)
- // Temporarly block signals, as the thread inherits this mask
- love::thread::disableSignals();
- #endif
- // Before opening new device, check if recording
- // is requested.
- if (getRequestRecordingPermission())
- {
- if (!hasRecordingPermission())
- // Request recording permission on some OSes.
- requestRecordingPermission();
- }
- // Passing null for default device.
- device = alcOpenDevice(nullptr);
- if (device == nullptr)
- throw love::Exception("Could not open device.");
- #ifdef ALC_EXT_EFX
- ALint attribs[4] = { ALC_MAX_AUXILIARY_SENDS, MAX_SOURCE_EFFECTS, 0, 0 };
- #else
- ALint *attribs = nullptr;
- #endif
- context = alcCreateContext(device, attribs);
- if (context == nullptr)
- throw love::Exception("Could not create context.");
- if (!alcMakeContextCurrent(context) || alcGetError(device) != ALC_NO_ERROR)
- throw love::Exception("Could not make context current.");
- #if defined(LOVE_LINUX)
- love::thread::reenableSignals();
- #endif
- #ifdef ALC_EXT_EFX
- initializeEFX();
- alcGetIntegerv(device, ALC_MAX_AUXILIARY_SENDS, 1, &MAX_SOURCE_EFFECTS);
- alGetError();
- if (alGenAuxiliaryEffectSlots)
- {
- for (int i = 0; i < MAX_SCENE_EFFECTS; i++)
- {
- ALuint slot;
- alGenAuxiliaryEffectSlots(1, &slot);
- if (alGetError() == AL_NO_ERROR)
- slotlist.push(slot);
- else
- {
- MAX_SCENE_EFFECTS = i;
- break;
- }
- }
- }
- else
- MAX_SCENE_EFFECTS = MAX_SOURCE_EFFECTS = 0;
- #else
- MAX_SCENE_EFFECTS = MAX_SOURCE_EFFECTS = 0;
- #endif
- try
- {
- pool = new Pool();
- }
- catch (love::Exception &)
- {
- for (auto c : capture)
- delete c;
- #ifdef ALC_EXT_EFX
- if (alDeleteAuxiliaryEffectSlots)
- {
- while (!slotlist.empty())
- {
- alDeleteAuxiliaryEffectSlots(1, &slotlist.top());
- slotlist.pop();
- }
- }
- #endif
- alcMakeContextCurrent(nullptr);
- alcDestroyContext(context);
- alcCloseDevice(device);
- throw;
- }
- poolThread = new PoolThread(pool);
- poolThread->start();
-
- #ifdef LOVE_IOS
- love::ios::initAudioSessionInterruptionHandler();
- #endif
-
- }
- Audio::~Audio()
- {
- #ifdef LOVE_IOS
- love::ios::destroyAudioSessionInterruptionHandler();
- #endif
- poolThread->setFinish();
- poolThread->wait();
- delete poolThread;
- delete pool;
- for (auto c : capture)
- delete c;
- #ifdef ALC_EXT_EFX
- for (auto e : effectmap)
- {
- delete e.second.effect;
- slotlist.push(e.second.slot);
- }
- if (alDeleteAuxiliaryEffectSlots)
- {
- while (!slotlist.empty())
- {
- alDeleteAuxiliaryEffectSlots(1, &slotlist.top());
- slotlist.pop();
- }
- }
- #endif
- alcMakeContextCurrent(nullptr);
- alcDestroyContext(context);
- alcCloseDevice(device);
- }
- const char *Audio::getName() const
- {
- return "love.audio.openal";
- }
- love::audio::Source *Audio::newSource(love::sound::Decoder *decoder)
- {
- return new Source(pool, decoder);
- }
- love::audio::Source *Audio::newSource(love::sound::SoundData *soundData)
- {
- return new Source(pool, soundData);
- }
- love::audio::Source *Audio::newSource(int sampleRate, int bitDepth, int channels, int buffers)
- {
- return new Source(pool, sampleRate, bitDepth, channels, buffers);
- }
- int Audio::getActiveSourceCount() const
- {
- return pool->getActiveSourceCount();
- }
- int Audio::getMaxSources() const
- {
- return pool->getMaxSources();
- }
- bool Audio::play(love::audio::Source *source)
- {
- return source->play();
- }
- bool Audio::play(const std::vector<love::audio::Source*> &sources)
- {
- return Source::play(sources);
- }
- void Audio::stop(love::audio::Source *source)
- {
- source->stop();
- }
- void Audio::stop(const std::vector<love::audio::Source*> &sources)
- {
- return Source::stop(sources);
- }
- void Audio::stop()
- {
- return Source::stop(pool);
- }
- void Audio::pause(love::audio::Source *source)
- {
- source->pause();
- }
- void Audio::pause(const std::vector<love::audio::Source*> &sources)
- {
- return Source::pause(sources);
- }
- std::vector<love::audio::Source*> Audio::pause()
- {
- return Source::pause(pool);
- }
- void Audio::pauseContext()
- {
- alcMakeContextCurrent(nullptr);
- }
- void Audio::resumeContext()
- {
- if (context && alcGetCurrentContext() != context)
- alcMakeContextCurrent(context);
- }
- void Audio::setVolume(float volume)
- {
- alListenerf(AL_GAIN, volume);
- }
- float Audio::getVolume() const
- {
- ALfloat volume;
- alGetListenerf(AL_GAIN, &volume);
- return volume;
- }
- void Audio::getPosition(float *v) const
- {
- alGetListenerfv(AL_POSITION, v);
- }
- void Audio::setPosition(float *v)
- {
- alListenerfv(AL_POSITION, v);
- }
- void Audio::getOrientation(float *v) const
- {
- alGetListenerfv(AL_ORIENTATION, v);
- }
- void Audio::setOrientation(float *v)
- {
- alListenerfv(AL_ORIENTATION, v);
- }
- void Audio::getVelocity(float *v) const
- {
- alGetListenerfv(AL_VELOCITY, v);
- }
- void Audio::setVelocity(float *v)
- {
- alListenerfv(AL_VELOCITY, v);
- }
- void Audio::setDopplerScale(float scale)
- {
- if (scale >= 0.0f)
- alDopplerFactor(scale);
- }
- float Audio::getDopplerScale() const
- {
- return alGetFloat(AL_DOPPLER_FACTOR);
- }
- /*
- void Audio::setMeter(float scale)
- {
- if (scale >= 0.0f)
- {
- metersPerUnit = scale;
- #ifdef ALC_EXT_EFX
- alListenerf(AL_METERS_PER_UNIT, scale);
- #endif
- }
- }
- float Audio::getMeter() const
- {
- return metersPerUnit;
- }
- */
- Audio::DistanceModel Audio::getDistanceModel() const
- {
- return distanceModel;
- }
- void Audio::setDistanceModel(DistanceModel distanceModel)
- {
- this->distanceModel = distanceModel;
- switch (distanceModel)
- {
- case DISTANCE_NONE:
- alDistanceModel(AL_NONE);
- break;
- case DISTANCE_INVERSE:
- alDistanceModel(AL_INVERSE_DISTANCE);
- break;
- case DISTANCE_INVERSE_CLAMPED:
- alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
- break;
- case DISTANCE_LINEAR:
- alDistanceModel(AL_LINEAR_DISTANCE);
- break;
- case DISTANCE_LINEAR_CLAMPED:
- alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
- break;
- case DISTANCE_EXPONENT:
- alDistanceModel(AL_EXPONENT_DISTANCE);
- break;
- case DISTANCE_EXPONENT_CLAMPED:
- alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
- break;
- default:
- break;
- }
- }
- const std::vector<love::audio::RecordingDevice*> &Audio::getRecordingDevices()
- {
- std::vector<std::string> devnames;
- std::vector<love::audio::RecordingDevice*> devices;
- // If recording permission is not granted, inform user about it
- // and return empty list.
- if (!hasRecordingPermission() && getRequestRecordingPermission())
- {
- showRecordingPermissionMissingDialog();
- capture.clear();
- return capture;
- }
- std::string defaultname(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
- //no device name obtained from AL, fallback to reading from device
- if (defaultname.length() == 0)
- {
- //use some safe basic parameters - 8 kHz, 8 bits, 1 channel
- ALCdevice *defaultdevice = alcCaptureOpenDevice(NULL, 8000, AL_FORMAT_MONO8, 1024);
- if (alGetError() == AL_NO_ERROR)
- {
- defaultname = alcGetString(defaultdevice, ALC_CAPTURE_DEVICE_SPECIFIER);
- alcCaptureCloseDevice(defaultdevice);
- }
- else
- {
- //failed to open default recording device - bail, return empty list
- capture.clear();
- return capture;
- }
- }
- devnames.reserve(capture.size());
- devnames.push_back(defaultname);
- //find devices name list
- const ALCchar *devstr = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
- size_t offset = 0;
- while (true)
- {
- if (devstr[offset] == '\0')
- break;
- std::string str((ALCchar*)&devstr[offset]);
- if (str != defaultname)
- devnames.push_back(str);
- offset += str.length() + 1;
- }
- devices.reserve(devnames.size());
- //build ordered list of devices
- for (int i = 0; i < (int) devnames.size(); i++)
- {
- devices.push_back(nullptr);
- auto d = devices.end() - 1;
- for (auto c : capture)
- if (devnames[i] == c->getName())
- *d = c;
- if (*d == nullptr)
- *d = new RecordingDevice(devnames[i].c_str());
- else
- (*d)->retain();
- }
- for (auto c : capture)
- c->release();
- capture.clear();
- capture.reserve(devices.size());
- //this needs to be executed in specific order
- for (unsigned int i = 0; i < devnames.size(); i++)
- capture.push_back(devices[i]);
- return capture;
- }
- bool Audio::setEffect(const char *name, std::map<Effect::Parameter, float> ¶ms)
- {
- Effect *effect;
- ALuint slot;
- auto iter = effectmap.find(name);
- if (iter == effectmap.end())
- {
- //new effect needed but no more slots
- if (effectmap.size() >= (unsigned int)MAX_SCENE_EFFECTS)
- return false;
- effect = new Effect();
- slot = slotlist.top();
- slotlist.pop();
- effectmap[name] = {effect, slot};
- }
- else
- {
- effect = iter->second.effect;
- slot = iter->second.slot;
- }
- bool result = effect->setParams(params);
- #ifdef ALC_EXT_EFX
- if (alAuxiliaryEffectSloti)
- {
- if (result)
- {
- auto iter = params.find(Effect::EFFECT_VOLUME);
- if (iter != params.end())
- alAuxiliaryEffectSlotf(slot, AL_EFFECTSLOT_GAIN, iter->second);
- alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, effect->getEffect());
- }
- else
- alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL);
- alGetError();
- }
- #endif
- return result;
- }
- bool Audio::unsetEffect(const char *name)
- {
- auto iter = effectmap.find(name);
- if (iter == effectmap.end())
- return false;
- Effect *effect = iter->second.effect;
- ALuint slot = iter->second.slot;
- #ifdef ALC_EXT_EFX
- if (alAuxiliaryEffectSloti)
- alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL);
- #endif
- delete effect;
- effectmap.erase(iter);
- slotlist.push(slot);
- return true;
- }
- bool Audio::getEffect(const char *name, std::map<Effect::Parameter, float> ¶ms)
- {
- auto iter = effectmap.find(name);
- if (iter == effectmap.end())
- return false;
- params = iter->second.effect->getParams();
- return true;
- }
- bool Audio::getActiveEffects(std::vector<std::string> &list) const
- {
- if (effectmap.empty())
- return false;
- list.reserve(effectmap.size());
- for (auto i : effectmap)
- list.push_back(i.first);
- return true;
- }
- int Audio::getMaxSceneEffects() const
- {
- return MAX_SCENE_EFFECTS;
- }
- int Audio::getMaxSourceEffects() const
- {
- return MAX_SOURCE_EFFECTS;
- }
- bool Audio::isEFXsupported() const
- {
- #ifdef ALC_EXT_EFX
- return (alGenEffects != nullptr);
- #else
- return false;
- #endif
- }
- bool Audio::getEffectID(const char *name, ALuint &id)
- {
- auto iter = effectmap.find(name);
- if (iter == effectmap.end())
- return false;
- id = iter->second.slot;
- return true;
- }
- #ifdef ALC_EXT_EFX
- LPALGENEFFECTS alGenEffects = nullptr;
- LPALDELETEEFFECTS alDeleteEffects = nullptr;
- LPALISEFFECT alIsEffect = nullptr;
- LPALEFFECTI alEffecti = nullptr;
- LPALEFFECTIV alEffectiv = nullptr;
- LPALEFFECTF alEffectf = nullptr;
- LPALEFFECTFV alEffectfv = nullptr;
- LPALGETEFFECTI alGetEffecti = nullptr;
- LPALGETEFFECTIV alGetEffectiv = nullptr;
- LPALGETEFFECTF alGetEffectf = nullptr;
- LPALGETEFFECTFV alGetEffectfv = nullptr;
- LPALGENFILTERS alGenFilters = nullptr;
- LPALDELETEFILTERS alDeleteFilters = nullptr;
- LPALISFILTER alIsFilter = nullptr;
- LPALFILTERI alFilteri = nullptr;
- LPALFILTERIV alFilteriv = nullptr;
- LPALFILTERF alFilterf = nullptr;
- LPALFILTERFV alFilterfv = nullptr;
- LPALGETFILTERI alGetFilteri = nullptr;
- LPALGETFILTERIV alGetFilteriv = nullptr;
- LPALGETFILTERF alGetFilterf = nullptr;
- LPALGETFILTERFV alGetFilterfv = nullptr;
- LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots = nullptr;
- LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots = nullptr;
- LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot = nullptr;
- LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti = nullptr;
- LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv = nullptr;
- LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf = nullptr;
- LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv = nullptr;
- LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti = nullptr;
- LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv = nullptr;
- LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf = nullptr;
- LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv = nullptr;
- #endif
- void Audio::initializeEFX()
- {
- #ifdef ALC_EXT_EFX
- if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_FALSE)
- return;
- alGenEffects = (LPALGENEFFECTS)alGetProcAddress("alGenEffects");
- alDeleteEffects = (LPALDELETEEFFECTS)alGetProcAddress("alDeleteEffects");
- alIsEffect = (LPALISEFFECT)alGetProcAddress("alIsEffect");
- alEffecti = (LPALEFFECTI)alGetProcAddress("alEffecti");
- alEffectiv = (LPALEFFECTIV)alGetProcAddress("alEffectiv");
- alEffectf = (LPALEFFECTF)alGetProcAddress("alEffectf");
- alEffectfv = (LPALEFFECTFV)alGetProcAddress("alEffectfv");
- alGetEffecti = (LPALGETEFFECTI)alGetProcAddress("alGetEffecti");
- alGetEffectiv = (LPALGETEFFECTIV)alGetProcAddress("alGetEffectiv");
- alGetEffectf = (LPALGETEFFECTF)alGetProcAddress("alGetEffectf");
- alGetEffectfv = (LPALGETEFFECTFV)alGetProcAddress("alGetEffectfv");
- alGenFilters = (LPALGENFILTERS)alGetProcAddress("alGenFilters");
- alDeleteFilters = (LPALDELETEFILTERS)alGetProcAddress("alDeleteFilters");
- alIsFilter = (LPALISFILTER)alGetProcAddress("alIsFilter");
- alFilteri = (LPALFILTERI)alGetProcAddress("alFilteri");
- alFilteriv = (LPALFILTERIV)alGetProcAddress("alFilteriv");
- alFilterf = (LPALFILTERF)alGetProcAddress("alFilterf");
- alFilterfv = (LPALFILTERFV)alGetProcAddress("alFilterfv");
- alGetFilteri = (LPALGETFILTERI)alGetProcAddress("alGetFilteri");
- alGetFilteriv = (LPALGETFILTERIV)alGetProcAddress("alGetFilteriv");
- alGetFilterf = (LPALGETFILTERF)alGetProcAddress("alGetFilterf");
- alGetFilterfv = (LPALGETFILTERFV)alGetProcAddress("alGetFilterfv");
- alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)alGetProcAddress("alGenAuxiliaryEffectSlots");
- alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)alGetProcAddress("alDeleteAuxiliaryEffectSlots");
- alIsAuxiliaryEffectSlot = (LPALISAUXILIARYEFFECTSLOT)alGetProcAddress("alIsAuxiliaryEffectSlot");
- alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)alGetProcAddress("alAuxiliaryEffectSloti");
- alAuxiliaryEffectSlotiv = (LPALAUXILIARYEFFECTSLOTIV)alGetProcAddress("alAuxiliaryEffectSlotiv");
- alAuxiliaryEffectSlotf = (LPALAUXILIARYEFFECTSLOTF)alGetProcAddress("alAuxiliaryEffectSlotf");
- alAuxiliaryEffectSlotfv = (LPALAUXILIARYEFFECTSLOTFV)alGetProcAddress("alAuxiliaryEffectSlotfv");
- alGetAuxiliaryEffectSloti = (LPALGETAUXILIARYEFFECTSLOTI)alGetProcAddress("alGetAuxiliaryEffectSloti");
- alGetAuxiliaryEffectSlotiv = (LPALGETAUXILIARYEFFECTSLOTIV)alGetProcAddress("alGetAuxiliaryEffectSlotiv");
- alGetAuxiliaryEffectSlotf = (LPALGETAUXILIARYEFFECTSLOTF)alGetProcAddress("alGetAuxiliaryEffectSlotf");
- alGetAuxiliaryEffectSlotfv = (LPALGETAUXILIARYEFFECTSLOTFV)alGetProcAddress("alGetAuxiliaryEffectSlotfv");
- //failed to initialize functions, revert to nullptr
- if (!alGenEffects || !alDeleteEffects || !alIsEffect ||
- !alGenFilters || !alDeleteFilters || !alIsFilter ||
- !alGenAuxiliaryEffectSlots || !alDeleteAuxiliaryEffectSlots || !alIsAuxiliaryEffectSlot ||
- !alEffecti || !alEffectiv || !alEffectf || !alEffectfv ||
- !alGetEffecti || !alGetEffectiv || !alGetEffectf || !alGetEffectfv ||
- !alFilteri || !alFilteriv || !alFilterf || !alFilterfv ||
- !alGetFilteri || !alGetFilteriv || !alGetFilterf || !alGetFilterfv ||
- !alAuxiliaryEffectSloti || !alAuxiliaryEffectSlotiv || !alAuxiliaryEffectSlotf || !alAuxiliaryEffectSlotfv ||
- !alGetAuxiliaryEffectSloti || !alGetAuxiliaryEffectSlotiv || !alGetAuxiliaryEffectSlotf || !alGetAuxiliaryEffectSlotfv)
- {
- alGenEffects = nullptr; alDeleteEffects = nullptr; alIsEffect = nullptr;
- alEffecti = nullptr; alEffectiv = nullptr; alEffectf = nullptr; alEffectfv = nullptr;
- alGetEffecti = nullptr; alGetEffectiv = nullptr; alGetEffectf = nullptr; alGetEffectfv = nullptr;
- alGenFilters = nullptr; alDeleteFilters = nullptr; alIsFilter = nullptr;
- alFilteri = nullptr; alFilteriv = nullptr; alFilterf = nullptr; alFilterfv = nullptr;
- alGetFilteri = nullptr; alGetFilteriv = nullptr; alGetFilterf = nullptr; alGetFilterfv = nullptr;
- alGenAuxiliaryEffectSlots = nullptr; alDeleteAuxiliaryEffectSlots = nullptr; alIsAuxiliaryEffectSlot = nullptr;
- alAuxiliaryEffectSloti = nullptr; alAuxiliaryEffectSlotiv = nullptr;
- alAuxiliaryEffectSlotf = nullptr; alAuxiliaryEffectSlotfv = nullptr;
- alGetAuxiliaryEffectSloti = nullptr; alGetAuxiliaryEffectSlotiv = nullptr;
- alGetAuxiliaryEffectSlotf = nullptr; alGetAuxiliaryEffectSlotfv = nullptr;
- }
- #endif
- }
- } // openal
- } // audio
- } // love
|