diff --git a/src/modules/audio/Effect.cpp b/src/modules/audio/Effect.cpp index c824cfdf4..e4e6f20a2 100644 --- a/src/modules/audio/Effect.cpp +++ b/src/modules/audio/Effect.cpp @@ -179,18 +179,18 @@ std::vector::Entry> Effect::basicParameters = std::vector::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::Entry> Effect::chorusParameters = @@ -208,14 +208,14 @@ std::vector::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::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::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} }; diff --git a/src/modules/audio/Filter.cpp b/src/modules/audio/Filter.cpp index 0a1915343..f1af53b0a 100644 --- a/src/modules/audio/Filter.cpp +++ b/src/modules/audio/Filter.cpp @@ -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::Entry Filter::typeEntries[] = @@ -67,12 +72,44 @@ StringMap::Entry Filter::typeEntries[] = StringMap Filter::types(Filter::typeEntries, sizeof(Filter::typeEntries)); -//all parameters are floats, therefore bare count will suffice -std::map Filter::parameterCount = +#define StringMap LazierAndSlowerButEasilyArrayableStringMap2 +std::vector::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::Entry> Filter::lowpassParameters = +{ + {"highgain", Filter::FILTER_HIGHGAIN} +}; + +std::vector::Entry> Filter::highpassParameters = +{ + {"lowgain", Filter::FILTER_LOWGAIN} +}; + +std::vector::Entry> Filter::bandpassParameters = +{ + {"lowgain", Filter::FILTER_LOWGAIN}, + {"highgain", Filter::FILTER_HIGHGAIN} +}; + +std::map> 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::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 diff --git a/src/modules/audio/Filter.h b/src/modules/audio/Filter.h index 82a2e743b..d18eb265d 100644 --- a/src/modules/audio/Filter.h +++ b/src/modules/audio/Filter.h @@ -25,6 +25,49 @@ #include "common/StringMap.h" #include +template +class LazierAndSlowerButEasilyArrayableStringMap2 +{ +public: + struct Entry + { + const char *key; + T value; + }; + LazierAndSlowerButEasilyArrayableStringMap2() + { + } + + LazierAndSlowerButEasilyArrayableStringMap2(const std::vector &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 forward; + std::map 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::Entry typeEntries[]; static StringMap types; - static std::map parameterCount; +#define StringMap LazierAndSlowerButEasilyArrayableStringMap2 + static std::vector::Entry> basicParameters; + static std::vector::Entry> lowpassParameters; + static std::vector::Entry> highpassParameters; + static std::vector::Entry> bandpassParameters; + static std::map> parameterNames; +#undef StringMap + static std::map parameterTypes; }; } //audio diff --git a/src/modules/audio/Source.h b/src/modules/audio/Source.h index d80420c04..c8edc35f9 100644 --- a/src/modules/audio/Source.h +++ b/src/modules/audio/Source.h @@ -109,14 +109,14 @@ public: virtual int getChannels() const = 0; - virtual bool setFilter(Filter::Type type, std::vector ¶ms) = 0; + virtual bool setFilter(std::map ¶ms) = 0; virtual bool setFilter() = 0; - virtual bool getFilter(Filter::Type &type, std::vector ¶ms) = 0; + virtual bool getFilter(std::map ¶ms) = 0; virtual bool setSceneEffect(int slot, int effect) = 0; - virtual bool setSceneEffect(int slot, int effect, Filter::Type type, std::vector ¶ms) = 0; + virtual bool setSceneEffect(int slot, int effect, std::map ¶ms) = 0; virtual bool setSceneEffect(int slot) = 0; - virtual bool getSceneEffect(int slot, int &effect, Filter::Type &type, std::vector ¶ms) = 0; + virtual bool getSceneEffect(int slot, int &effect, std::map ¶ms) = 0; virtual int getFreeBufferCount() const = 0; virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels) = 0; diff --git a/src/modules/audio/null/Source.cpp b/src/modules/audio/null/Source.cpp index bb7725c1b..b97f73fbe 100644 --- a/src/modules/audio/null/Source.cpp +++ b/src/modules/audio/null/Source.cpp @@ -239,7 +239,7 @@ bool Source::queue(void *, size_t, int, int, int) return false; } -bool Source::setFilter(love::audio::Filter::Type, std::vector &) +bool Source::setFilter(std::map &) { return false; } @@ -249,7 +249,7 @@ bool Source::setFilter() return false; } -bool Source::getFilter(love::audio::Filter::Type &, std::vector &) +bool Source::getFilter(std::map &) { return false; } @@ -259,7 +259,7 @@ bool Source::setSceneEffect(int, int) return false; } -bool Source::setSceneEffect(int, int, love::audio::Filter::Type, std::vector &) +bool Source::setSceneEffect(int, int, std::map &) { return false; } @@ -269,7 +269,7 @@ bool Source::setSceneEffect(int) return false; } -bool Source::getSceneEffect(int, int &, love::audio::Filter::Type &, std::vector &) +bool Source::getSceneEffect(int, int &, std::map &) { return false; } diff --git a/src/modules/audio/null/Source.h b/src/modules/audio/null/Source.h index be8041d48..fbd04edcb 100644 --- a/src/modules/audio/null/Source.h +++ b/src/modules/audio/null/Source.h @@ -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 ¶ms); + virtual bool setFilter(std::map ¶ms); virtual bool setFilter(); - virtual bool getFilter(love::audio::Filter::Type &type, std::vector ¶ms); + virtual bool getFilter(std::map ¶ms); virtual bool setSceneEffect(int slot, int effect); - virtual bool setSceneEffect(int slot, int effect, love::audio::Filter::Type type, std::vector ¶ms); + virtual bool setSceneEffect(int slot, int effect, std::map ¶ms); virtual bool setSceneEffect(int slot); - virtual bool getSceneEffect(int slot, int &effect, love::audio::Filter::Type &type, std::vector ¶ms); + virtual bool getSceneEffect(int slot, int &effect, std::map ¶ms); private: diff --git a/src/modules/audio/openal/Filter.cpp b/src/modules/audio/openal/Filter.cpp index 0a2e8dde4..a7bfc9978 100644 --- a/src/modules/audio/openal/Filter.cpp +++ b/src/modules/audio/openal/Filter.cpp @@ -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 ¶ms) +bool Filter::setParams(const std::map ¶ms) { - this->type = type; this->params = params; + type = static_cast(this->params[FILTER_TYPE]); if (!generateFilter()) return false; @@ -105,6 +105,7 @@ bool Filter::setParams(Type type, const std::vector ¶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 ¶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 ¶ms) #endif } -const std::vector &Filter::getParams() const +const std::map &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(params.at(in)); } } //openal diff --git a/src/modules/audio/openal/Filter.h b/src/modules/audio/openal/Filter.h index 0d80288b7..5f885b736 100644 --- a/src/modules/audio/openal/Filter.h +++ b/src/modules/audio/openal/Filter.h @@ -61,15 +61,16 @@ public: virtual ~Filter(); virtual Filter *clone(); ALuint getFilter() const; - virtual bool setParams(Type type, const std::vector ¶ms); - virtual const std::vector &getParams() const; + virtual bool setParams(const std::map ¶ms); + virtual const std::map &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 params; + std::map params; }; } //openal diff --git a/src/modules/audio/openal/Source.cpp b/src/modules/audio/openal/Source.cpp index 44e97f97e..1832ed277 100644 --- a/src/modules/audio/openal/Source.cpp +++ b/src/modules/audio/openal/Source.cpp @@ -1252,12 +1252,12 @@ int Source::getChannels() const return channels; } -bool Source::setFilter(love::audio::Filter::Type type, std::vector ¶ms) +bool Source::setFilter(std::map ¶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 ¶ms) +bool Source::getFilter(std::map ¶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 ¶ms) +bool Source::setSceneEffect(int slot, int effect, std::map ¶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 ¶ms) +bool Source::getSceneEffect(int slot, int &effect, std::map ¶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(audiomodule())->getSceneEffectIndex(sendtargets[slot]); if(sendfilters[slot]) - { - type = sendfilters[slot]->getType(); params = sendfilters[slot]->getParams(); - } return true; } diff --git a/src/modules/audio/openal/Source.h b/src/modules/audio/openal/Source.h index 08b0ff626..93d247b69 100644 --- a/src/modules/audio/openal/Source.h +++ b/src/modules/audio/openal/Source.h @@ -146,14 +146,14 @@ public: virtual float getAirAbsorptionFactor() const; virtual int getChannels() const; - virtual bool setFilter(love::audio::Filter::Type type, std::vector ¶ms); + virtual bool setFilter(std::map ¶ms); virtual bool setFilter(); - virtual bool getFilter(love::audio::Filter::Type &type, std::vector ¶ms); + virtual bool getFilter(std::map ¶ms); virtual bool setSceneEffect(int slot, int effect); - virtual bool setSceneEffect(int slot, int effect, love::audio::Filter::Type type, std::vector ¶ms); + virtual bool setSceneEffect(int slot, int effect, std::map ¶ms); virtual bool setSceneEffect(int slot); - virtual bool getSceneEffect(int slot, int &effect, love::audio::Filter::Type &type, std::vector ¶ms); + virtual bool getSceneEffect(int slot, int &effect, std::map ¶ms); virtual int getFreeBufferCount() const; virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels); diff --git a/src/modules/audio/wrap_Audio.cpp b/src/modules/audio/wrap_Audio.cpp index ec4e10516..9b8cb4398 100644 --- a/src/modules/audio/wrap_Audio.cpp +++ b/src/modules/audio/wrap_Audio.cpp @@ -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 } }; diff --git a/src/modules/audio/wrap_Source.cpp b/src/modules/audio/wrap_Source.cpp index 4b8bee8ff..2e0c58dbe 100644 --- a/src/modules/audio/wrap_Source.cpp +++ b/src/modules/audio/wrap_Source.cpp @@ -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 ¶ms) +int setFilterReadFilter(lua_State *L, int idx, std::map ¶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(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 ¶ms) +{ + const char *keystr, *valstr; + Filter::Type type = static_cast((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((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 params; + std::map 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 params; - if (!t->getFilter(type, params)) + + std::map 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 params; + std::map 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 params; - if (!t->getSceneEffect(slot, effect, type, params)) + std::map 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 },