Browse Source

naming updated, Filters patched up

--HG--
branch : minor
Raidho 8 years ago
parent
commit
94b4d2bdef

+ 15 - 15
src/modules/audio/Effect.cpp

@@ -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}
 };

+ 46 - 9
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<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 =
+{
+	{"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::TYPE_LOWPASS, 1},
-	{Filter::TYPE_HIGHPASS, 1},
-	{Filter::TYPE_BANDPASS, 2},
+	{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

+ 73 - 3
src/modules/audio/Filter.h

@@ -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

+ 4 - 4
src/modules/audio/Source.h

@@ -109,14 +109,14 @@ public:
 
 	virtual int getChannels() const = 0;
 
-	virtual bool setFilter(Filter::Type type, std::vector<float> &params) = 0;
+	virtual bool setFilter(std::map<Filter::Parameter, float> &params) = 0;
 	virtual bool setFilter() = 0;
-	virtual bool getFilter(Filter::Type &type, std::vector<float> &params) = 0;
+	virtual bool getFilter(std::map<Filter::Parameter, float> &params) = 0;
 
 	virtual bool setSceneEffect(int slot, int effect) = 0;
-	virtual bool setSceneEffect(int slot, int effect, Filter::Type type, std::vector<float> &params) = 0;
+	virtual bool setSceneEffect(int slot, int effect, std::map<Filter::Parameter, float> &params) = 0;
 	virtual bool setSceneEffect(int slot) = 0;
-	virtual bool getSceneEffect(int slot, int &effect, Filter::Type &type, std::vector<float> &params) = 0;
+	virtual bool getSceneEffect(int slot, int &effect, std::map<Filter::Parameter, float> &params) = 0;
 
 	virtual int getFreeBufferCount() const = 0;
 	virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels) = 0;

+ 4 - 4
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<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;
 }

+ 4 - 4
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<float> &params);
+	virtual bool setFilter(std::map<Filter::Parameter, float> &params);
 	virtual bool setFilter();
-	virtual bool getFilter(love::audio::Filter::Type &type, std::vector<float> &params);
+	virtual bool getFilter(std::map<Filter::Parameter, float> &params);
 
 	virtual bool setSceneEffect(int slot, int effect);
-	virtual bool setSceneEffect(int slot, int effect, love::audio::Filter::Type type, std::vector<float> &params);
+	virtual bool setSceneEffect(int slot, int effect, std::map<Filter::Parameter, float> &params);
 	virtual bool setSceneEffect(int slot);
-	virtual bool getSceneEffect(int slot, int &effect, love::audio::Filter::Type &type, std::vector<float> &params);
+	virtual bool getSceneEffect(int slot, int &effect, std::map<Filter::Parameter, float> &params);
 
 private:
 

+ 23 - 18
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<float> &params)
+bool Filter::setParams(const std::map<Parameter, float> &params)
 {
-	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> &params)
 	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> &params)
 		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> &params)
 	#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

+ 5 - 4
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<float> &params);
-	virtual const std::vector<float> &getParams() const;
+	virtual bool setParams(const std::map<Parameter, float> &params);
+	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

+ 6 - 10
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<float> &params)
+bool Source::setFilter(std::map<Filter::Parameter, float> &params)
 {
 	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> &params)
+bool Source::getFilter(std::map<Filter::Parameter, float> &params)
 {
 	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> &params)
+bool Source::setSceneEffect(int slot, int effect, std::map<Filter::Parameter, float> &params)
 {
 	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> &params)
+bool Source::getSceneEffect(int slot, int &effect, std::map<Filter::Parameter, float> &params)
 {
 	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;
 }

+ 4 - 4
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<float> &params);
+	virtual bool setFilter(std::map<Filter::Parameter, float> &params);
 	virtual bool setFilter();
-	virtual bool getFilter(love::audio::Filter::Type &type, std::vector<float> &params);
+	virtual bool getFilter(std::map<Filter::Parameter, float> &params);
 
 	virtual bool setSceneEffect(int slot, int effect);
-	virtual bool setSceneEffect(int slot, int effect, love::audio::Filter::Type type, std::vector<float> &params);
+	virtual bool setSceneEffect(int slot, int effect, std::map<Filter::Parameter, float> &params);
 	virtual bool setSceneEffect(int slot);
-	virtual bool getSceneEffect(int slot, int &effect, love::audio::Filter::Type &type, std::vector<float> &params);
+	virtual bool getSceneEffect(int slot, int &effect, std::map<Filter::Parameter, float> &params);
 
 	virtual int getFreeBufferCount() const;
 	virtual bool queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels);

+ 4 - 4
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 }
 };
 

+ 88 - 70
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<float> &params)
+int setFilterReadFilter(lua_State *L, int idx, std::map<Filter::Parameter, float> &params)
 {
-	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);
+	return 1;
+}
+
+void getFilterWriteFilter(lua_State *L, std::map<Filter::Parameter, float> &params)
+{
+	const char *keystr, *valstr;
+	Filter::Type type = static_cast<Filter::Type>((int)params[Filter::FILTER_TYPE]);
+
+	lua_createtable(L, 0, params.size());
 
-		int count = Filter::getParameterCount(type);
-		for (int i = 0; i < count; i++)
+	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))
 		{
-			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);
+		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);
 	}
-	else
-		return luax_typerror(L, pos, "filter description");
-
-	return 1;
 }
 
 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))
-		return 0;
 
-	const char *str = nullptr;
-	Filter::getConstant(type, str);
-	lua_pushstring(L, str);
+	std::map<Filter::Parameter, float> params;
 
-	for (unsigned int i = 0; i < params.size(); i++)
-		lua_pushnumber(L, params[i]);
+	if (!t->getFilter(params))
+		return 0;
 
-	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 },