Browse Source

Added Source:setCone(innerAngle, outerAngle, outerVolume). Resolves issue #643.

When combined with Source:setDirection (and Source:setPosition or love.audio.setPosition), the cone parameters allow for directional sound output from a Source.
Alex Szpakowski 12 years ago
parent
commit
13ea750454

+ 3 - 0
src/modules/audio/Source.h

@@ -80,6 +80,9 @@ public:
 	virtual void setDirection(float *v) = 0;
 	virtual void getDirection(float *v) const = 0;
 
+	virtual void setCone(float innerAngle, float outerAngle, float outerVolume) = 0;
+	virtual void getCone(float &innerAngle, float &outerAngle, float &outerVolume) const = 0;
+
 	virtual void setRelativePosition(bool relative) = 0;
 	virtual bool hasRelativePosition() const = 0;
 

+ 14 - 0
src/modules/audio/null/Source.cpp

@@ -135,6 +135,20 @@ void Source::getDirection(float *) const
 {
 }
 
+void Source::setCone(float innerAngle, float outerAngle, float outerVolume)
+{
+	coneInnerAngle = innerAngle;
+	coneOuterAngle = outerAngle;
+	coneOuterVolume = outerVolume;
+}
+
+void Source::getCone(float &innerAngle, float &outerAngle, float &outerVolume) const
+{
+	innerAngle = coneInnerAngle;
+	outerAngle = coneOuterAngle;
+	outerVolume = coneOuterVolume;
+}
+
 void Source::setRelativePosition(bool relative)
 {
 	relativePosition = relative;

+ 5 - 0
src/modules/audio/null/Source.h

@@ -60,6 +60,8 @@ public:
 	virtual void getVelocity(float *v) const;
 	virtual void setDirection(float *v);
 	virtual void getDirection(float *v) const;
+	virtual void setCone(float innerAngle, float outerAngle, float outerVolume);
+	virtual void getCone(float &innerAngle, float &outerAngle, float &outerVolume) const;
 	virtual void setRelativePosition(bool relative);
 	virtual bool hasRelativePosition() const;
 	void setLooping(bool looping);
@@ -80,6 +82,9 @@ private:
 
 	float pitch;
 	float volume;
+	float coneInnerAngle;
+	float coneOuterAngle;
+	float coneOuterVolume;
 	bool relativePosition;
 	bool looping;
 	float minVolume;

+ 27 - 1
src/modules/audio/openal/Source.cpp

@@ -19,8 +19,8 @@
  **/
 
 #include "Source.h"
-
 #include "Pool.h"
+#include "common/math.h"
 
 // STD
 #include <iostream>
@@ -47,6 +47,7 @@ Source::Source(Pool *pool, love::sound::SoundData *soundData)
 	, referenceDistance(1.0f)
 	, rolloffFactor(1.0f)
 	, maxDistance(FLT_MAX)
+	, cone()
 	, offsetSamples(0)
 	, offsetSeconds(0)
 	, decoder(0)
@@ -77,6 +78,7 @@ Source::Source(Pool *pool, love::sound::Decoder *decoder)
 	, referenceDistance(1.0f)
 	, rolloffFactor(1.0f)
 	, maxDistance(FLT_MAX)
+	, cone()
 	, offsetSamples(0)
 	, offsetSeconds(0)
 	, decoder(decoder)
@@ -404,6 +406,27 @@ void Source::getDirection(float *v) const
 		setFloatv(v, direction);
 }
 
+void Source::setCone(float innerAngle, float outerAngle, float outerVolume)
+{
+	cone.innerAngle = LOVE_TODEG(innerAngle);
+	cone.outerAngle = LOVE_TODEG(outerAngle);
+	cone.outerVolume = outerVolume;
+
+	if (valid)
+	{
+		alSourcei(source, AL_CONE_INNER_ANGLE, cone.innerAngle);
+		alSourcei(source, AL_CONE_OUTER_ANGLE, cone.outerAngle);
+		alSourcef(source, AL_CONE_OUTER_GAIN, cone.outerVolume);
+	}
+}
+
+void Source::getCone(float &innerAngle, float &outerAngle, float &outerVolume) const
+{
+	innerAngle = LOVE_TORAD(cone.innerAngle);
+	outerAngle = LOVE_TORAD(cone.outerAngle);
+	outerVolume = cone.outerVolume;
+}
+
 void Source::setRelativePosition(bool relative)
 {
 	if (valid)
@@ -551,6 +574,9 @@ void Source::reset()
 	alSourcef(source, AL_MAX_DISTANCE, maxDistance);
 	alSourcei(source, AL_LOOPING, isStatic() && isLooping() ? AL_TRUE : AL_FALSE);
 	alSourcei(source, AL_SOURCE_RELATIVE, relativePosition ? AL_TRUE : AL_FALSE);
+	alSourcei(source, AL_CONE_INNER_ANGLE, cone.innerAngle);
+	alSourcei(source, AL_CONE_OUTER_ANGLE, cone.outerAngle);
+	alSourcef(source, AL_CONE_OUTER_GAIN, cone.outerVolume);
 }
 
 void Source::setFloatv(float *dst, const float *src) const

+ 15 - 0
src/modules/audio/openal/Source.h

@@ -78,6 +78,8 @@ public:
 	virtual void getVelocity(float *v) const;
 	virtual void setDirection(float *v);
 	virtual void getDirection(float *v) const;
+	virtual void setCone(float innerAngle, float outerAngle, float outerVolume);
+	virtual void getCone(float &innerAngle, float &outerAngle, float &outerVolume) const;
 	virtual void setRelativePosition(bool relative);
 	virtual bool hasRelativePosition() const;
 	void setLooping(bool looping);
@@ -137,6 +139,19 @@ private:
 	float rolloffFactor;
 	float maxDistance;
 
+	struct Cone
+	{
+		int innerAngle; // degrees
+		int outerAngle; // degrees
+		float outerVolume;
+
+		Cone()
+			: innerAngle(360)
+			, outerAngle(360)
+			, outerVolume(0.0f)
+		{}
+	} cone;
+
 	float offsetSamples;
 	float offsetSeconds;
 

+ 23 - 0
src/modules/audio/wrap_Source.cpp

@@ -190,6 +190,27 @@ int w_Source_getDirection(lua_State *L)
 	return 3;
 }
 
+int w_Source_setCone(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float innerAngle = (float) luaL_checknumber(L, 2);
+	float outerAngle = (float) luaL_checknumber(L, 3);
+	float outerVolume = (float) luaL_optnumber(L, 4, 0.0);
+	t->setCone(innerAngle, outerAngle, outerVolume);
+	return 0;
+}
+
+int w_Source_getCone(lua_State *L)
+{
+	Source *t = luax_checksource(L, 1);
+	float innerAngle, outerAngle, outerVolume;
+	t->getCone(innerAngle, outerAngle, outerVolume);
+	lua_pushnumber(L, innerAngle);
+	lua_pushnumber(L, outerAngle);
+	lua_pushnumber(L, outerVolume);
+	return 3;
+}
+
 int w_Source_setRelativePosition(lua_State *L)
 {
 	Source *t = luax_checksource(L, 1);
@@ -336,6 +357,8 @@ static const luaL_Reg functions[] =
 	{ "getVelocity", w_Source_getVelocity },
 	{ "setDirection", w_Source_setDirection },
 	{ "getDirection", w_Source_getDirection },
+	{ "setCone", w_Source_setCone },
+	{ "getCone", w_Source_getCone },
 
 	{ "setRelativePosition", w_Source_setRelativePosition },
 	{ "hasRelativePosition", w_Source_hasRelativePosition },

+ 2 - 0
src/modules/audio/wrap_Source.h

@@ -47,6 +47,8 @@ int w_Source_setVelocity(lua_State *L);
 int w_Source_getVelocity(lua_State *L);
 int w_Source_setDirection(lua_State *L);
 int w_Source_getDirection(lua_State *L);
+int w_Source_setCone(lua_State *L);
+int w_Source_getCone(lua_State *L);
 int w_Source_setRelativePosition(lua_State *L);
 int w_Source_hasRelativePosition(lua_State *L);
 int w_Source_setLooping(lua_State *L);