mirror of
https://github.com/love2d/love.git
synced 2026-08-16 16:20:42 +02:00
naming updated, Filters patched up
--HG-- branch : minor
This commit is contained in:
@@ -179,18 +179,18 @@ std::vector<StringMap<Effect::Parameter>::Entry> Effect::basicParameters =
|
||||
std::vector<StringMap<Effect::Parameter>::Entry> Effect::reverbParameters =
|
||||
{
|
||||
{"gain", Effect::REVERB_GAIN},
|
||||
{"hfgain", Effect::REVERB_HFGAIN},
|
||||
{"highgain", Effect::REVERB_HFGAIN},
|
||||
{"density", Effect::REVERB_DENSITY},
|
||||
{"diffusion", Effect::REVERB_DIFFUSION},
|
||||
{"decay", Effect::REVERB_DECAY},
|
||||
{"hfdecay", Effect::REVERB_HFDECAY},
|
||||
{"decaytime", Effect::REVERB_DECAY},
|
||||
{"decayhighratio", Effect::REVERB_HFDECAY},
|
||||
{"earlygain", Effect::REVERB_EARLYGAIN},
|
||||
{"earlydelay", Effect::REVERB_EARLYDELAY},
|
||||
{"lategain", Effect::REVERB_LATEGAIN},
|
||||
{"latedelay", Effect::REVERB_LATEDELAY},
|
||||
{"rolloff", Effect::REVERB_ROLLOFF},
|
||||
{"airhfgain", Effect::REVERB_AIRHFGAIN},
|
||||
{"hflimiter", Effect::REVERB_HFLIMITER}
|
||||
{"roomrolloff", Effect::REVERB_ROLLOFF},
|
||||
{"airabsorption", Effect::REVERB_AIRHFGAIN},
|
||||
{"highlimit", Effect::REVERB_HFLIMITER}
|
||||
};
|
||||
|
||||
std::vector<StringMap<Effect::Parameter>::Entry> Effect::chorusParameters =
|
||||
@@ -208,14 +208,14 @@ std::vector<StringMap<Effect::Parameter>::Entry> Effect::distortionParameters =
|
||||
{"gain", Effect::DISTORTION_GAIN},
|
||||
{"edge", Effect::DISTORTION_EDGE},
|
||||
{"lowcut", Effect::DISTORTION_LOWCUT},
|
||||
{"eqcenter", Effect::DISTORTION_EQCENTER},
|
||||
{"eqbandwidth", Effect::DISTORTION_EQBAND}
|
||||
{"center", Effect::DISTORTION_EQCENTER},
|
||||
{"bandwidth", Effect::DISTORTION_EQBAND}
|
||||
};
|
||||
|
||||
std::vector<StringMap<Effect::Parameter>::Entry> Effect::echoParameters =
|
||||
{
|
||||
{"delay", Effect::ECHO_DELAY},
|
||||
{"lrdelay", Effect::ECHO_LRDELAY},
|
||||
{"tapdelay", Effect::ECHO_LRDELAY},
|
||||
{"damping", Effect::ECHO_DAMPING},
|
||||
{"feedback", Effect::ECHO_FEEDBACK},
|
||||
{"spread", Effect::ECHO_SPREAD}
|
||||
@@ -277,12 +277,12 @@ std::vector<StringMap<Effect::Parameter>::Entry> Effect::equalizerParameters =
|
||||
{
|
||||
{"lowgain", Effect::EQUALIZER_LOWGAIN},
|
||||
{"lowcut", Effect::EQUALIZER_LOWCUT},
|
||||
{"mid1gain", Effect::EQUALIZER_MID1GAIN},
|
||||
{"mid1frequency", Effect::EQUALIZER_MID1FREQ},
|
||||
{"mid1bandwidth", Effect::EQUALIZER_MID1BAND},
|
||||
{"mid2gain", Effect::EQUALIZER_MID2GAIN},
|
||||
{"mid2frequency", Effect::EQUALIZER_MID2FREQ},
|
||||
{"mid2bandwidth", Effect::EQUALIZER_MID2BAND},
|
||||
{"lowmidgain", Effect::EQUALIZER_MID1GAIN},
|
||||
{"lowmidfrequency", Effect::EQUALIZER_MID1FREQ},
|
||||
{"lowmidbandwidth", Effect::EQUALIZER_MID1BAND},
|
||||
{"highmidgain", Effect::EQUALIZER_MID2GAIN},
|
||||
{"highmidfrequency", Effect::EQUALIZER_MID2FREQ},
|
||||
{"highmidbandwidth", Effect::EQUALIZER_MID2BAND},
|
||||
{"highgain", Effect::EQUALIZER_HIGHGAIN},
|
||||
{"highcut", Effect::EQUALIZER_HIGHCUT}
|
||||
};
|
||||
|
||||
@@ -48,14 +48,19 @@ bool Filter::getConstant(Type in, const char *&out)
|
||||
return types.find(in, out);
|
||||
}
|
||||
|
||||
int Filter::getParameterCount(Type in)
|
||||
bool Filter::getConstant(const char *in, Parameter &out, Type t)
|
||||
{
|
||||
return parameterCount[in];
|
||||
return parameterNames[t].find(in, out);
|
||||
}
|
||||
|
||||
int Filter::getParameterCount()
|
||||
bool Filter::getConstant(Parameter in, const char *&out, Type t)
|
||||
{
|
||||
return parameterCount[TYPE_MAX_ENUM];
|
||||
return parameterNames[t].find(in, out);
|
||||
}
|
||||
|
||||
Filter::ParameterType Filter::getParameterType(Parameter in)
|
||||
{
|
||||
return parameterTypes[in];
|
||||
}
|
||||
|
||||
StringMap<Filter::Type, Filter::TYPE_MAX_ENUM>::Entry Filter::typeEntries[] =
|
||||
@@ -67,12 +72,44 @@ StringMap<Filter::Type, Filter::TYPE_MAX_ENUM>::Entry Filter::typeEntries[] =
|
||||
|
||||
StringMap<Filter::Type, Filter::TYPE_MAX_ENUM> Filter::types(Filter::typeEntries, sizeof(Filter::typeEntries));
|
||||
|
||||
//all parameters are floats, therefore bare count will suffice
|
||||
std::map<Filter::Type, int> Filter::parameterCount =
|
||||
#define StringMap LazierAndSlowerButEasilyArrayableStringMap2
|
||||
std::vector<StringMap<Filter::Parameter>::Entry> Filter::basicParameters =
|
||||
{
|
||||
{Filter::TYPE_LOWPASS, 1},
|
||||
{Filter::TYPE_HIGHPASS, 1},
|
||||
{Filter::TYPE_BANDPASS, 2},
|
||||
{"type", Filter::FILTER_TYPE},
|
||||
{"volume", Filter::FILTER_VOLUME}
|
||||
};
|
||||
|
||||
std::vector<StringMap<Filter::Parameter>::Entry> Filter::lowpassParameters =
|
||||
{
|
||||
{"highgain", Filter::FILTER_HIGHGAIN}
|
||||
};
|
||||
|
||||
std::vector<StringMap<Filter::Parameter>::Entry> Filter::highpassParameters =
|
||||
{
|
||||
{"lowgain", Filter::FILTER_LOWGAIN}
|
||||
};
|
||||
|
||||
std::vector<StringMap<Filter::Parameter>::Entry> Filter::bandpassParameters =
|
||||
{
|
||||
{"lowgain", Filter::FILTER_LOWGAIN},
|
||||
{"highgain", Filter::FILTER_HIGHGAIN}
|
||||
};
|
||||
|
||||
std::map<Filter::Type, StringMap<Filter::Parameter>> Filter::parameterNames =
|
||||
{
|
||||
{Filter::TYPE_BASIC, Filter::basicParameters},
|
||||
{Filter::TYPE_LOWPASS, Filter::lowpassParameters},
|
||||
{Filter::TYPE_HIGHPASS, Filter::highpassParameters},
|
||||
{Filter::TYPE_BANDPASS, Filter::bandpassParameters},
|
||||
};
|
||||
#undef StringMap
|
||||
|
||||
std::map<Filter::Parameter, Filter::ParameterType> Filter::parameterTypes =
|
||||
{
|
||||
{Filter::FILTER_TYPE, Filter::PARAM_TYPE},
|
||||
{Filter::FILTER_VOLUME, Filter::PARAM_FLOAT},
|
||||
{Filter::FILTER_LOWGAIN, Filter::PARAM_FLOAT},
|
||||
{Filter::FILTER_HIGHGAIN, Filter::PARAM_FLOAT}
|
||||
};
|
||||
|
||||
} //audio
|
||||
|
||||
@@ -25,6 +25,49 @@
|
||||
#include "common/StringMap.h"
|
||||
#include <map>
|
||||
|
||||
template<typename T>
|
||||
class LazierAndSlowerButEasilyArrayableStringMap2
|
||||
{
|
||||
public:
|
||||
struct Entry
|
||||
{
|
||||
const char *key;
|
||||
T value;
|
||||
};
|
||||
LazierAndSlowerButEasilyArrayableStringMap2()
|
||||
{
|
||||
}
|
||||
|
||||
LazierAndSlowerButEasilyArrayableStringMap2(const std::vector<Entry> &entries)
|
||||
{
|
||||
for (auto entry : entries)
|
||||
{
|
||||
forward[entry.key] = entry.value;
|
||||
reverse[entry.value] = entry.key;
|
||||
}
|
||||
}
|
||||
|
||||
bool find(const char *key, T &t)
|
||||
{
|
||||
if (forward.find(key) == forward.end())
|
||||
return false;
|
||||
t = forward[key];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool find(T key, const char *&str)
|
||||
{
|
||||
if (reverse.find(key) == reverse.end())
|
||||
return false;
|
||||
str = reverse[key];
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, T> forward;
|
||||
std::map<T, const char*> reverse;
|
||||
};
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace audio
|
||||
@@ -35,20 +78,40 @@ class Filter
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
TYPE_BASIC,
|
||||
TYPE_LOWPASS,
|
||||
TYPE_HIGHPASS,
|
||||
TYPE_BANDPASS,
|
||||
TYPE_MAX_ENUM
|
||||
};
|
||||
|
||||
enum Parameter
|
||||
{
|
||||
FILTER_TYPE,
|
||||
FILTER_VOLUME,
|
||||
|
||||
FILTER_LOWGAIN,
|
||||
FILTER_HIGHGAIN,
|
||||
|
||||
FILTER_MAX_ENUM
|
||||
};
|
||||
|
||||
enum ParameterType
|
||||
{
|
||||
PARAM_TYPE,
|
||||
PARAM_FLOAT,
|
||||
PARAM_MAX_ENUM
|
||||
};
|
||||
|
||||
Filter();
|
||||
virtual ~Filter();
|
||||
Type getType() const;
|
||||
|
||||
static bool getConstant(const char *in, Type &out);
|
||||
static bool getConstant(Type in, const char *&out);
|
||||
static int getParameterCount(Type in);
|
||||
static int getParameterCount();
|
||||
static bool getConstant(const char *in, Parameter &out, Type t);
|
||||
static bool getConstant(Parameter in, const char *&out, Type t);
|
||||
static ParameterType getParameterType(Parameter in);
|
||||
|
||||
protected:
|
||||
Type type;
|
||||
@@ -56,7 +119,14 @@ protected:
|
||||
private:
|
||||
static StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[];
|
||||
static StringMap<Type, TYPE_MAX_ENUM> types;
|
||||
static std::map<Type, int> parameterCount;
|
||||
#define StringMap LazierAndSlowerButEasilyArrayableStringMap2
|
||||
static std::vector<StringMap<Filter::Parameter>::Entry> basicParameters;
|
||||
static std::vector<StringMap<Filter::Parameter>::Entry> lowpassParameters;
|
||||
static std::vector<StringMap<Filter::Parameter>::Entry> highpassParameters;
|
||||
static std::vector<StringMap<Filter::Parameter>::Entry> bandpassParameters;
|
||||
static std::map<Type, StringMap<Parameter>> parameterNames;
|
||||
#undef StringMap
|
||||
static std::map<Parameter, ParameterType> parameterTypes;
|
||||
};
|
||||
|
||||
} //audio
|
||||
|
||||
@@ -109,14 +109,14 @@ public:
|
||||
|
||||
virtual int getChannels() const = 0;
|
||||
|
||||
virtual bool setFilter(Filter::Type type, std::vector<float> ¶ms) = 0;
|
||||
virtual bool setFilter(std::map<Filter::Parameter, float> ¶ms) = 0;
|
||||
virtual bool setFilter() = 0;
|
||||
virtual bool getFilter(Filter::Type &type, std::vector<float> ¶ms) = 0;
|
||||
virtual bool getFilter(std::map<Filter::Parameter, float> ¶ms) = 0;
|
||||
|
||||
virtual bool setSceneEffect(int slot, int effect) = 0;
|
||||
virtual bool setSceneEffect(int slot, int effect, Filter::Type type, std::vector<float> ¶ms) = 0;
|
||||
virtual bool setSceneEffect(int slot, int effect, std::map<Filter::Parameter, float> ¶ms) = 0;
|
||||
virtual bool setSceneEffect(int slot) = 0;
|
||||
virtual bool getSceneEffect(int slot, int &effect, Filter::Type &type, std::vector<float> ¶ms) = 0;
|
||||
virtual bool getSceneEffect(int slot, int &effect, std::map<Filter::Parameter, float> ¶ms) = 0;
|
||||
|
||||
virtual int getFreeBufferCount() const = 0;
|
||||
virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels) = 0;
|
||||
|
||||
@@ -239,7 +239,7 @@ bool Source::queue(void *, size_t, int, int, int)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Source::setFilter(love::audio::Filter::Type, std::vector<float> &)
|
||||
bool Source::setFilter(std::map<Filter::Parameter, float> &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -249,7 +249,7 @@ bool Source::setFilter()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Source::getFilter(love::audio::Filter::Type &, std::vector<float> &)
|
||||
bool Source::getFilter(std::map<Filter::Parameter, float> &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -259,7 +259,7 @@ bool Source::setSceneEffect(int, int)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Source::setSceneEffect(int, int, love::audio::Filter::Type, std::vector<float> &)
|
||||
bool Source::setSceneEffect(int, int, std::map<Filter::Parameter, float> &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -269,7 +269,7 @@ bool Source::setSceneEffect(int)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Source::getSceneEffect(int, int &, love::audio::Filter::Type &, std::vector<float> &)
|
||||
bool Source::getSceneEffect(int, int &, std::map<Filter::Parameter, float> &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -82,14 +82,14 @@ public:
|
||||
virtual int getFreeBufferCount() const;
|
||||
virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels);
|
||||
|
||||
virtual bool setFilter(love::audio::Filter::Type type, std::vector<float> ¶ms);
|
||||
virtual bool setFilter(std::map<Filter::Parameter, float> ¶ms);
|
||||
virtual bool setFilter();
|
||||
virtual bool getFilter(love::audio::Filter::Type &type, std::vector<float> ¶ms);
|
||||
virtual bool getFilter(std::map<Filter::Parameter, float> ¶ms);
|
||||
|
||||
virtual bool setSceneEffect(int slot, int effect);
|
||||
virtual bool setSceneEffect(int slot, int effect, love::audio::Filter::Type type, std::vector<float> ¶ms);
|
||||
virtual bool setSceneEffect(int slot, int effect, std::map<Filter::Parameter, float> ¶ms);
|
||||
virtual bool setSceneEffect(int slot);
|
||||
virtual bool getSceneEffect(int slot, int &effect, love::audio::Filter::Type &type, std::vector<float> ¶ms);
|
||||
virtual bool getSceneEffect(int slot, int &effect, std::map<Filter::Parameter, float> ¶ms);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ Filter::Filter()
|
||||
Filter::Filter(const Filter &s)
|
||||
: Filter()
|
||||
{
|
||||
setParams(s.getType(), s.getParams());
|
||||
setParams(s.getParams());
|
||||
}
|
||||
|
||||
Filter::~Filter()
|
||||
@@ -85,10 +85,10 @@ ALuint Filter::getFilter() const
|
||||
return filter;
|
||||
}
|
||||
|
||||
bool Filter::setParams(Type type, const std::vector<float> ¶ms)
|
||||
bool Filter::setParams(const std::map<Parameter, float> ¶ms)
|
||||
{
|
||||
this->type = type;
|
||||
this->params = params;
|
||||
type = static_cast<Type>(this->params[FILTER_TYPE]);
|
||||
|
||||
if (!generateFilter())
|
||||
return false;
|
||||
@@ -105,6 +105,7 @@ bool Filter::setParams(Type type, const std::vector<float> ¶ms)
|
||||
case TYPE_BANDPASS:
|
||||
alFilteri(filter, AL_FILTER_TYPE, AL_FILTER_BANDPASS);
|
||||
break;
|
||||
case TYPE_BASIC:
|
||||
case TYPE_MAX_ENUM:
|
||||
break;
|
||||
}
|
||||
@@ -116,25 +117,28 @@ bool Filter::setParams(Type type, const std::vector<float> ¶ms)
|
||||
return false;
|
||||
}
|
||||
|
||||
#define PARAMSTR(i,e,v) filter, AL_ ## e ## _ ## v, clampf(params[(i)], AL_ ## e ## _MIN_ ## v, AL_ ## e ## _MAX_ ## v, AL_ ## e ## _DEFAULT_ ## v)
|
||||
#define clampf(v,l,h) fmax(fmin((v),(h)),(l))
|
||||
#define PARAMSTR(i,e,v) filter,AL_##e##_##v,clampf(getValue(i,AL_##e##_DEFAULT_##v),AL_##e##_MIN_##v,AL_##e##_MAX_##v)
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_LOWPASS:
|
||||
alFilterf(PARAMSTR(0,LOWPASS,GAIN));
|
||||
alFilterf(PARAMSTR(1,LOWPASS,GAINHF));
|
||||
alFilterf(PARAMSTR(FILTER_VOLUME,LOWPASS,GAIN));
|
||||
alFilterf(PARAMSTR(FILTER_HIGHGAIN,LOWPASS,GAINHF));
|
||||
break;
|
||||
case TYPE_HIGHPASS:
|
||||
alFilterf(PARAMSTR(0,HIGHPASS,GAIN));
|
||||
alFilterf(PARAMSTR(1,HIGHPASS,GAINLF));
|
||||
alFilterf(PARAMSTR(FILTER_VOLUME,HIGHPASS,GAIN));
|
||||
alFilterf(PARAMSTR(FILTER_LOWGAIN,HIGHPASS,GAINLF));
|
||||
break;
|
||||
case TYPE_BANDPASS:
|
||||
alFilterf(PARAMSTR(0,BANDPASS,GAIN));
|
||||
alFilterf(PARAMSTR(1,BANDPASS,GAINLF));
|
||||
alFilterf(PARAMSTR(2,BANDPASS,GAINHF));
|
||||
alFilterf(PARAMSTR(FILTER_VOLUME,BANDPASS,GAIN));
|
||||
alFilterf(PARAMSTR(FILTER_LOWGAIN,BANDPASS,GAINLF));
|
||||
alFilterf(PARAMSTR(FILTER_HIGHGAIN,BANDPASS,GAINHF));
|
||||
break;
|
||||
case TYPE_BASIC:
|
||||
case TYPE_MAX_ENUM:
|
||||
break;
|
||||
}
|
||||
#undef clampf
|
||||
#undef PARAMSTR
|
||||
//alGetError();
|
||||
|
||||
@@ -144,18 +148,19 @@ bool Filter::setParams(Type type, const std::vector<float> ¶ms)
|
||||
#endif
|
||||
}
|
||||
|
||||
const std::vector<float> &Filter::getParams() const
|
||||
const std::map<Filter::Parameter, float> &Filter::getParams() const
|
||||
{
|
||||
return params;
|
||||
}
|
||||
|
||||
//clamp values silently to avoid randomly throwing errors due to implementation differences
|
||||
float Filter::clampf(float val, float min, float max, float def)
|
||||
float Filter::getValue(Parameter in, float def) const
|
||||
{
|
||||
if (isnanf(val)) return def;
|
||||
else if (val < min) val = min;
|
||||
else if (val > max) val = max;
|
||||
return val;
|
||||
return params.find(in) == params.end() ? def : params.at(in);
|
||||
}
|
||||
|
||||
int Filter::getValue(Parameter in, int def) const
|
||||
{
|
||||
return params.find(in) == params.end() ? def : static_cast<int>(params.at(in));
|
||||
}
|
||||
|
||||
} //openal
|
||||
|
||||
@@ -61,15 +61,16 @@ public:
|
||||
virtual ~Filter();
|
||||
virtual Filter *clone();
|
||||
ALuint getFilter() const;
|
||||
virtual bool setParams(Type type, const std::vector<float> ¶ms);
|
||||
virtual const std::vector<float> &getParams() const;
|
||||
virtual bool setParams(const std::map<Parameter, float> ¶ms);
|
||||
virtual const std::map<Parameter, float> &getParams() const;
|
||||
|
||||
private:
|
||||
bool generateFilter();
|
||||
void deleteFilter();
|
||||
float clampf(float val, float min, float max, float def);
|
||||
float getValue(Parameter in, float def) const;
|
||||
int getValue(Parameter in, int def) const;
|
||||
ALuint filter = AL_FILTER_NULL;
|
||||
std::vector<float> params;
|
||||
std::map<Parameter, float> params;
|
||||
};
|
||||
|
||||
} //openal
|
||||
|
||||
@@ -1252,12 +1252,12 @@ int Source::getChannels() const
|
||||
return channels;
|
||||
}
|
||||
|
||||
bool Source::setFilter(love::audio::Filter::Type type, std::vector<float> ¶ms)
|
||||
bool Source::setFilter(std::map<Filter::Parameter, float> ¶ms)
|
||||
{
|
||||
if (!directfilter)
|
||||
directfilter = new Filter();
|
||||
|
||||
bool result = directfilter->setParams(type, params);
|
||||
bool result = directfilter->setParams(params);
|
||||
|
||||
#ifdef ALC_EXT_EFX
|
||||
if (valid)
|
||||
@@ -1289,12 +1289,11 @@ bool Source::setFilter()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Source::getFilter(love::audio::Filter::Type &type, std::vector<float> ¶ms)
|
||||
bool Source::getFilter(std::map<Filter::Parameter, float> ¶ms)
|
||||
{
|
||||
if (!directfilter)
|
||||
return false;
|
||||
|
||||
type = directfilter->getType();
|
||||
params = directfilter->getParams();
|
||||
|
||||
return true;
|
||||
@@ -1323,7 +1322,7 @@ bool Source::setSceneEffect(int slot, int effect)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Source::setSceneEffect(int slot, int effect, love::audio::Filter::Type type, std::vector<float> ¶ms)
|
||||
bool Source::setSceneEffect(int slot, int effect, std::map<Filter::Parameter, float> ¶ms)
|
||||
{
|
||||
if (slot < 0 || slot >= (int)sendtargets.size())
|
||||
return false;
|
||||
@@ -1333,7 +1332,7 @@ bool Source::setSceneEffect(int slot, int effect, love::audio::Filter::Type type
|
||||
if (!sendfilters[slot])
|
||||
sendfilters[slot] = new Filter();
|
||||
|
||||
sendfilters[slot]->setParams(type, params);
|
||||
sendfilters[slot]->setParams(params);
|
||||
|
||||
#ifdef ALC_EXT_EFX
|
||||
if (valid)
|
||||
@@ -1368,7 +1367,7 @@ bool Source::setSceneEffect(int slot)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Source::getSceneEffect(int slot, int &effect, love::audio::Filter::Type &type, std::vector<float> ¶ms)
|
||||
bool Source::getSceneEffect(int slot, int &effect, std::map<Filter::Parameter, float> ¶ms)
|
||||
{
|
||||
if (slot < 0 || slot >= (int)sendtargets.size())
|
||||
return false;
|
||||
@@ -1379,10 +1378,7 @@ bool Source::getSceneEffect(int slot, int &effect, love::audio::Filter::Type &ty
|
||||
effect = dynamic_cast<Audio*>(audiomodule())->getSceneEffectIndex(sendtargets[slot]);
|
||||
|
||||
if(sendfilters[slot])
|
||||
{
|
||||
type = sendfilters[slot]->getType();
|
||||
params = sendfilters[slot]->getParams();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -146,14 +146,14 @@ public:
|
||||
virtual float getAirAbsorptionFactor() const;
|
||||
virtual int getChannels() const;
|
||||
|
||||
virtual bool setFilter(love::audio::Filter::Type type, std::vector<float> ¶ms);
|
||||
virtual bool setFilter(std::map<Filter::Parameter, float> ¶ms);
|
||||
virtual bool setFilter();
|
||||
virtual bool getFilter(love::audio::Filter::Type &type, std::vector<float> ¶ms);
|
||||
virtual bool getFilter(std::map<Filter::Parameter, float> ¶ms);
|
||||
|
||||
virtual bool setSceneEffect(int slot, int effect);
|
||||
virtual bool setSceneEffect(int slot, int effect, love::audio::Filter::Type type, std::vector<float> ¶ms);
|
||||
virtual bool setSceneEffect(int slot, int effect, std::map<Filter::Parameter, float> ¶ms);
|
||||
virtual bool setSceneEffect(int slot);
|
||||
virtual bool getSceneEffect(int slot, int &effect, love::audio::Filter::Type &type, std::vector<float> ¶ms);
|
||||
virtual bool getSceneEffect(int slot, int &effect, std::map<Filter::Parameter, float> ¶ms);
|
||||
|
||||
virtual int getFreeBufferCount() const;
|
||||
virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels);
|
||||
|
||||
@@ -396,7 +396,7 @@ int w_setSceneEffect(lua_State *L)
|
||||
case Effect::PARAM_MAX_ENUM:
|
||||
break;
|
||||
}
|
||||
#undef luaL_effecterror
|
||||
#undef luax_effecterror
|
||||
}
|
||||
else
|
||||
luaL_error(L, "Invalid '%s' Effect parameter: %s", typestr, keystr);
|
||||
@@ -505,11 +505,11 @@ static const luaL_Reg functions[] =
|
||||
{ "setDistanceModel", w_setDistanceModel },
|
||||
{ "getDistanceModel", w_getDistanceModel },
|
||||
{ "getRecordingDevices", w_getRecordingDevices },
|
||||
{ "setSceneEffect", w_setSceneEffect },
|
||||
{ "getSceneEffect", w_getSceneEffect },
|
||||
{ "setEffect", w_setSceneEffect },
|
||||
{ "getEffect", w_getSceneEffect },
|
||||
{ "getMaxSceneEffects", w_getMaxSceneEffects },
|
||||
{ "getMaxSourceEffects", w_getMaxSourceEffects },
|
||||
{ "isSceneEffectsSupported", w_isSceneEffectsSupported },
|
||||
{ "isEffectsSupported", w_isSceneEffectsSupported },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -345,88 +345,115 @@ int w_Source_getChannels(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int setFilterReadFilter(lua_State *L, int pos, Filter::Type &type, std::vector<float> ¶ms)
|
||||
int setFilterReadFilter(lua_State *L, int idx, std::map<Filter::Parameter, float> ¶ms)
|
||||
{
|
||||
if (lua_isnoneornil(L, pos))
|
||||
if (lua_gettop(L) < idx || lua_isnoneornil(L, idx))
|
||||
return 0;
|
||||
else if (lua_isstring(L, pos))
|
||||
|
||||
luaL_checktype(L, idx, LUA_TTABLE);
|
||||
|
||||
const char *paramstr = nullptr;
|
||||
|
||||
Filter::getConstant(Filter::FILTER_TYPE, paramstr, Filter::TYPE_BASIC);
|
||||
lua_pushstring(L, paramstr);
|
||||
lua_rawget(L, idx);
|
||||
if (lua_type(L, -1) == LUA_TNIL)
|
||||
return luaL_error(L, "Filter type not specificed.");
|
||||
|
||||
Filter::Type type = Filter::TYPE_MAX_ENUM;
|
||||
const char *typestr = luaL_checkstring(L, -1);
|
||||
if (!Filter::getConstant(typestr, type))
|
||||
return luaL_error(L, "Invalid Filter type: %s", typestr);
|
||||
|
||||
lua_pop(L, 1);
|
||||
params[Filter::FILTER_TYPE] = static_cast<int>(type);
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, idx))
|
||||
{
|
||||
const char *ftypestr = luaL_checkstring(L, pos);
|
||||
if (!Filter::getConstant(ftypestr, type))
|
||||
return luaL_error(L, "Invalid filter type: %s", ftypestr);
|
||||
const char *keystr = luaL_checkstring(L, -2);
|
||||
Filter::Parameter param;
|
||||
|
||||
params.push_back(luaL_checknumber(L, pos + 1));
|
||||
int count = Filter::getParameterCount(type);
|
||||
for (int i = 0; i < count; i++)
|
||||
if(Filter::getConstant(keystr, param, type) || Filter::getConstant(keystr, param, Filter::TYPE_BASIC))
|
||||
{
|
||||
if (lua_isnoneornil(L, i + pos + 2))
|
||||
params.push_back(nanf(""));
|
||||
else
|
||||
params.push_back(luaL_checknumber(L, i + pos + 2));
|
||||
#define luax_effecterror(l,t) luaL_error(l,"Bad parameter type for %s %s: " t " expected, got %s", typestr, keystr, lua_typename(L, -1))
|
||||
switch(Filter::getParameterType(param))
|
||||
{
|
||||
case Filter::PARAM_FLOAT:
|
||||
if (!lua_isnumber(L, -1))
|
||||
return luax_effecterror(L, "number");
|
||||
params[param] = lua_tonumber(L, -1);
|
||||
break;
|
||||
case Filter::PARAM_TYPE:
|
||||
case Filter::PARAM_MAX_ENUM:
|
||||
break;
|
||||
}
|
||||
#undef luax_effecterror
|
||||
}
|
||||
}
|
||||
else if (lua_istable(L, pos))
|
||||
{
|
||||
if (lua_objlen(L, pos) == 0) //empty table also clears filter
|
||||
return 0;
|
||||
else
|
||||
luaL_error(L, "Invalid '%s' Effect parameter: %s", typestr, keystr);
|
||||
|
||||
lua_rawgeti(L, pos, 1);
|
||||
const char *ftypestr = luaL_checkstring(L, -1);
|
||||
if (!Filter::getConstant(ftypestr, type))
|
||||
return luaL_error(L, "Invalid filter type: %s", ftypestr);
|
||||
//remove the value (-1) from stack, keep the key (-2) to feed into lua_next
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, pos, 2);
|
||||
params.push_back(luaL_checknumber(L, -1));
|
||||
lua_pop(L, 1);
|
||||
|
||||
int count = Filter::getParameterCount(type);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
lua_rawgeti(L, pos, i + 3);
|
||||
if (lua_isnoneornil(L, -1))
|
||||
params.push_back(nanf(""));
|
||||
else
|
||||
params.push_back(luaL_checknumber(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
return luax_typerror(L, pos, "filter description");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void getFilterWriteFilter(lua_State *L, std::map<Filter::Parameter, float> ¶ms)
|
||||
{
|
||||
const char *keystr, *valstr;
|
||||
Filter::Type type = static_cast<Filter::Type>((int)params[Filter::FILTER_TYPE]);
|
||||
|
||||
lua_createtable(L, 0, params.size());
|
||||
|
||||
for (auto p : params)
|
||||
{
|
||||
if (!Filter::getConstant(p.first, keystr, type))
|
||||
Filter::getConstant(p.first, keystr, Filter::TYPE_BASIC);
|
||||
|
||||
lua_pushstring(L, keystr);
|
||||
switch (Filter::getParameterType(p.first))
|
||||
{
|
||||
case Filter::PARAM_FLOAT:
|
||||
lua_pushnumber(L, p.second);
|
||||
break;
|
||||
case Filter::PARAM_TYPE:
|
||||
Filter::getConstant(static_cast<Filter::Type>((int)p.second), valstr);
|
||||
lua_pushstring(L, valstr);
|
||||
break;
|
||||
case Filter::PARAM_MAX_ENUM:
|
||||
break;
|
||||
}
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
}
|
||||
|
||||
int w_Source_setFilter(lua_State *L)
|
||||
{
|
||||
Source *t = luax_checksource(L, 1);
|
||||
|
||||
Filter::Type type;
|
||||
std::vector<float> params;
|
||||
std::map<Filter::Parameter, float> params;
|
||||
|
||||
if (setFilterReadFilter(L, 2, type, params))
|
||||
luax_catchexcept(L, [&]() { lua_pushboolean(L, t->setFilter(type, params)); });
|
||||
if (setFilterReadFilter(L, 2, params) == 1)
|
||||
luax_catchexcept(L, [&]() { lua_pushboolean(L, t->setFilter(params)); });
|
||||
else
|
||||
luax_catchexcept(L, [&]() { lua_pushboolean(L, t->setFilter()); });
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Source_getFilter(lua_State *L)
|
||||
{
|
||||
Source *t = luax_checksource(L, 1);
|
||||
Filter::Type type;
|
||||
std::vector<float> params;
|
||||
if (!t->getFilter(type, params))
|
||||
|
||||
std::map<Filter::Parameter, float> params;
|
||||
|
||||
if (!t->getFilter(params))
|
||||
return 0;
|
||||
|
||||
const char *str = nullptr;
|
||||
Filter::getConstant(type, str);
|
||||
lua_pushstring(L, str);
|
||||
|
||||
for (unsigned int i = 0; i < params.size(); i++)
|
||||
lua_pushnumber(L, params[i]);
|
||||
|
||||
return params.size() + 1;
|
||||
getFilterWriteFilter(L, params);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Source_setSceneEffect(lua_State *L)
|
||||
@@ -447,11 +474,10 @@ int w_Source_setSceneEffect(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
Filter::Type type;
|
||||
std::vector<float> params;
|
||||
std::map<Filter::Parameter, float> params;
|
||||
|
||||
if (setFilterReadFilter(L, 4, type, params))
|
||||
luax_catchexcept(L, [&]() { lua_pushboolean(L, t->setSceneEffect(slot, effect, type, params)); });
|
||||
if (setFilterReadFilter(L, 4, params) == 1)
|
||||
luax_catchexcept(L, [&]() { lua_pushboolean(L, t->setSceneEffect(slot, effect, params)); });
|
||||
else
|
||||
luax_catchexcept(L, [&]() { lua_pushboolean(L, t->setSceneEffect(slot, effect)); });
|
||||
return 1;
|
||||
@@ -463,24 +489,16 @@ int w_Source_getSceneEffect(lua_State *L)
|
||||
int slot = luaL_checknumber(L, 2) - 1;
|
||||
|
||||
int effect;
|
||||
Filter::Type type = Filter::TYPE_MAX_ENUM;
|
||||
std::vector<float> params;
|
||||
if (!t->getSceneEffect(slot, effect, type, params))
|
||||
std::map<Filter::Parameter, float> params;
|
||||
if (!t->getSceneEffect(slot, effect, params))
|
||||
return 0;
|
||||
|
||||
lua_pushnumber(L, effect + 1);
|
||||
if(type == Filter::TYPE_MAX_ENUM)
|
||||
if (params.size() == 0)
|
||||
return 1;
|
||||
|
||||
const char *str = nullptr;
|
||||
Filter::getConstant(type, str);
|
||||
if (str)
|
||||
lua_pushstring(L, str);
|
||||
|
||||
for (unsigned int i = 0; i < params.size(); i++)
|
||||
lua_pushnumber(L, params[i]);
|
||||
|
||||
return params.size() + 2;
|
||||
getFilterWriteFilter(L, params);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int w_Source_getFreeBufferCount(lua_State *L)
|
||||
@@ -595,8 +613,8 @@ static const luaL_Reg w_Source_functions[] =
|
||||
|
||||
{ "setFilter", w_Source_setFilter },
|
||||
{ "getFilter", w_Source_getFilter },
|
||||
{ "setSceneEffect", w_Source_setSceneEffect },
|
||||
{ "getSceneEffect", w_Source_getSceneEffect },
|
||||
{ "setEffect", w_Source_setSceneEffect },
|
||||
{ "getEffect", w_Source_getSceneEffect },
|
||||
|
||||
{ "getFreeBufferCount", w_Source_getFreeBufferCount },
|
||||
{ "queue", w_Source_queue },
|
||||
|
||||
Reference in New Issue
Block a user