Merge pull request 2 by Bloutiouf: Sound attenuation by distanceSound

attenuation by distance.

Adds:
love.audio.[gs]etDistanceModel(model-identifier)
Source:[gs]etMinVolume(min-volume)
Source:[gs]etMaxVolume(max-volume)
Source:[gs]etDistance(reference, max)
Source:[gs]etRolloffFactor(rolloff)

Valid Distance models:
"none", "inverse", "inverse clamped", "linear", "linear clamped", "exponent",
"exponent clamped"

Suggestion:
Merge Source:setMinVolume, Source:setMinVolume and Source:setVolume. May be
confusing for lovers though.

May have broken platform/msvc2010/love.vcxproj.filters (had to be modified by
hand without really knowing what I am doing).
This commit is contained in:
vrld
2011-12-29 22:45:51 +01:00
17 changed files with 482 additions and 12 deletions
+51
View File
@@ -0,0 +1,51 @@
/**
* Copyright (c) 2006-2011 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 Audio 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 Audio distribution.
**/
#include "Audio.h"
namespace love
{
namespace audio
{
StringMap<Audio::DistanceModel, Audio::DISTANCE_MAX_ENUM>::Entry Audio::distanceModelEntries[] =
{
{"none", Audio::DISTANCE_NONE},
{"inverse", Audio::DISTANCE_INVERSE},
{"inverse clamped", Audio::DISTANCE_INVERSE_CLAMPED},
{"linear", Audio::DISTANCE_LINEAR},
{"linear clamped", Audio::DISTANCE_LINEAR},
{"exponent", Audio::DISTANCE_EXPONENT},
{"exponent clamped", Audio::DISTANCE_EXPONENT}
};
StringMap<Audio::DistanceModel, Audio::DISTANCE_MAX_ENUM> Audio::distanceModels(Audio::distanceModelEntries, sizeof(Audio::distanceModelEntries));
bool Audio::getConstant(const char * in, DistanceModel & out)
{
return distanceModels.find(in, out);
}
bool Audio::getConstant(DistanceModel in, const char *& out)
{
return distanceModels.find(in, out);
}
} // audio
} // love
+35
View File
@@ -22,6 +22,7 @@
#define LOVE_AUDIO_AUDIO_H
#include <common/Module.h>
#include <common/StringMap.h>
#include "Source.h"
namespace love
@@ -40,6 +41,24 @@ namespace audio
{
public:
/**
* Attenuation by distance.
*/
enum DistanceModel
{
DISTANCE_NONE = 1,
DISTANCE_INVERSE,
DISTANCE_INVERSE_CLAMPED,
DISTANCE_LINEAR,
DISTANCE_LINEAR_CLAMPED,
DISTANCE_EXPONENT,
DISTANCE_EXPONENT_CLAMPED,
DISTANCE_MAX_ENUM
};
static bool getConstant(const char * in, DistanceModel & out);
static bool getConstant(DistanceModel in, const char *& out);
/**
* Destructor.
**/
@@ -191,6 +210,22 @@ namespace audio
**/
virtual bool canRecord() = 0;
/**
* Gets the distance model used for attenuation.
* @return Distance model.
*/
virtual DistanceModel getDistanceModel() const = 0;
/**
* Sets the distance model used for attenuation.
* @param distanceModel Distance model.
*/
virtual void setDistanceModel(DistanceModel distanceModel) = 0;
private:
static StringMap<DistanceModel, DISTANCE_MAX_ENUM>::Entry distanceModelEntries[];
static StringMap<DistanceModel, DISTANCE_MAX_ENUM> distanceModels;
}; // Audio
} // audio
+12
View File
@@ -86,6 +86,18 @@ namespace audio
virtual void setLooping(bool looping) = 0;
virtual bool isLooping() const = 0;
virtual bool isStatic() const = 0;
virtual void setMinVolume(float volume) = 0;
virtual float getMinVolume() const = 0;
virtual void setMaxVolume(float volume) = 0;
virtual float getMaxVolume() const = 0;
virtual void setReferenceDistance(float distance) = 0;
virtual float getReferenceDistance() const = 0;
virtual void setRolloffFactor(float factor) = 0;
virtual float getRolloffFactor() const = 0;
virtual void setMaxDistance(float distance) = 0;
virtual float getMaxDistance() const = 0;
static bool getConstant(const char * in, Type & out);
static bool getConstant(Type in, const char *& out);
+11 -1
View File
@@ -26,7 +26,7 @@ namespace audio
{
namespace null
{
Audio::Audio()
Audio::Audio() : distanceModel(DISTANCE_NONE)
{
}
@@ -151,6 +151,16 @@ namespace null
{
return false;
}
Audio::DistanceModel Audio::getDistanceModel() const
{
return this->distanceModel;
}
void Audio::setDistanceModel(DistanceModel distanceModel)
{
this->distanceModel = distanceModel;
}
} // null
} // audio
+4
View File
@@ -36,6 +36,7 @@ namespace null
{
private:
float volume;
DistanceModel distanceModel;
public:
Audio();
@@ -74,6 +75,9 @@ namespace null
love::sound::SoundData * stopRecording(bool returnData);
bool canRecord();
DistanceModel getDistanceModel() const;
void setDistanceModel(DistanceModel distanceModel);
}; // Audio
} // null
+50
View File
@@ -149,6 +149,56 @@ namespace null
{
return (type == TYPE_STATIC);
}
void Source::setMinVolume(float volume)
{
this->minVolume = volume;
}
float Source::getMinVolume() const
{
return this->minVolume;
}
void Source::setMaxVolume(float volume)
{
this->maxVolume = volume;
}
float Source::getMaxVolume() const
{
return this->maxVolume;
}
void Source::setReferenceDistance(float distance)
{
this->referenceDistance = distance;
}
float Source::getReferenceDistance() const
{
return this->referenceDistance;
}
void Source::setRolloffFactor(float factor)
{
this->rolloffFactor = factor;
}
float Source::getRolloffFactor() const
{
return this->rolloffFactor;
}
void Source::setMaxDistance(float distance)
{
this->maxDistance = distance;
}
float Source::getMaxDistance() const
{
return this->maxDistance;
}
} // null
} // audio
+15
View File
@@ -38,6 +38,11 @@ namespace null
float pitch;
float volume;
bool looping;
float minVolume;
float maxVolume;
float referenceDistance;
float rolloffFactor;
float maxDistance;
public:
Source();
@@ -68,6 +73,16 @@ namespace null
void setLooping(bool looping);
bool isLooping() const;
bool isStatic() const;
virtual void setMinVolume(float volume);
virtual float getMinVolume() const;
virtual void setMaxVolume(float volume);
virtual float getMaxVolume() const;
virtual void setReferenceDistance(float distance);
virtual float getReferenceDistance() const;
virtual void setRolloffFactor(float factor);
virtual float getRolloffFactor() const;
virtual void setMaxDistance(float distance);
virtual float getMaxDistance() const;
}; // Source
+44 -1
View File
@@ -58,7 +58,7 @@ namespace openal
}
Audio::Audio()
Audio::Audio() : distanceModel(DISTANCE_INVERSE_CLAMPED)
{
// Passing zero for default device.
device = alcOpenDevice(0);
@@ -267,7 +267,50 @@ namespace openal
{
return (capture != NULL);
}
Audio::DistanceModel Audio::getDistanceModel() const
{
return this->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;
}
}
} // openal
} // audio
} // love
+5 -1
View File
@@ -89,6 +89,8 @@ namespace openal
PoolThread* poolThread;
DistanceModel distanceModel;
public:
Audio();
@@ -126,7 +128,9 @@ namespace openal
love::sound::SoundData * getRecordedData();
love::sound::SoundData * stopRecording(bool returnData);
bool canRecord();
DistanceModel getDistanceModel() const;
void setDistanceModel(DistanceModel distanceModel);
}; // Audio
} // openal
+132 -4
View File
@@ -24,6 +24,7 @@
// STD
#include <iostream>
#include <float.h>
namespace love
{
@@ -34,8 +35,9 @@ namespace openal
Source::Source(Pool * pool, love::sound::SoundData * soundData)
: love::audio::Source(Source::TYPE_STATIC), pool(pool), valid(false),
pitch(1.0f), volume(1.0f), looping(false), paused(false), offsetSamples(0),
offsetSeconds(0), decoder(0), toLoop(0)
pitch(1.0f), volume(1.0f), looping(false), paused(false), minVolume(0.0f),
maxVolume(1.0f), referenceDistance(1.0f), rolloffFactor(1.0f), maxDistance(FLT_MAX),
offsetSamples(0), offsetSeconds(0), decoder(0), toLoop(0)
{
alGenBuffers(1, buffers);
ALenum fmt = getFormat(soundData->getChannels(), soundData->getBits());
@@ -50,8 +52,9 @@ namespace openal
Source::Source(Pool * pool, love::sound::Decoder * decoder)
: love::audio::Source(Source::TYPE_STREAM), pool(pool), valid(false),
pitch(1.0f), volume(1.0f), looping(false), paused(false), offsetSamples(0),
offsetSeconds(0), decoder(decoder), toLoop(0)
pitch(1.0f), volume(1.0f), looping(false), paused(false), minVolume(0.0f),
maxVolume(1.0f), referenceDistance(1.0f), rolloffFactor(1.0f), maxDistance(FLT_MAX),
offsetSamples(0), offsetSeconds(0), decoder(decoder), toLoop(0)
{
decoder->retain();
alGenBuffers(MAX_BUFFERS, buffers);
@@ -415,6 +418,11 @@ namespace openal
// been without an AL source.
alSourcef(source, AL_PITCH, pitch);
alSourcef(source, AL_GAIN, volume);
alSourcef(source, AL_MIN_GAIN, minVolume);
alSourcef(source, AL_MAX_GAIN, maxVolume);
alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance);
alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor);
alSourcef(source, AL_MAX_DISTANCE, maxDistance);
alSourcePlay(source);
@@ -503,6 +511,11 @@ namespace openal
alSourcefv(source, AL_DIRECTION, direction);
alSourcef(source, AL_PITCH, pitch);
alSourcef(source, AL_GAIN, volume);
alSourcef(source, AL_MIN_GAIN, minVolume);
alSourcef(source, AL_MAX_GAIN, maxVolume);
alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance);
alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor);
alSourcef(source, AL_MAX_DISTANCE, maxDistance);
}
void Source::setFloatv(float * dst, const float * src) const
@@ -564,6 +577,121 @@ namespace openal
{
return (type == TYPE_STATIC);
}
void Source::setMinVolume(float volume)
{
if (valid)
{
alSourcef(source, AL_MIN_GAIN, volume);
}
this->minVolume = volume;
}
float Source::getMinVolume() const
{
if (valid)
{
ALfloat f;
alGetSourcef(source, AL_MIN_GAIN, &f);
return f;
}
// In case the Source isn't playing.
return this->minVolume;
}
void Source::setMaxVolume(float volume)
{
if (valid)
{
alSourcef(source, AL_MAX_GAIN, volume);
}
this->maxVolume = volume;
}
float Source::getMaxVolume() const
{
if (valid)
{
ALfloat f;
alGetSourcef(source, AL_MAX_GAIN, &f);
return f;
}
// In case the Source isn't playing.
return this->maxVolume;
}
void Source::setReferenceDistance(float distance)
{
if (valid)
{
alSourcef(source, AL_REFERENCE_DISTANCE, distance);
}
this->referenceDistance = distance;
}
float Source::getReferenceDistance() const
{
if (valid)
{
ALfloat f;
alGetSourcef(source, AL_REFERENCE_DISTANCE, &f);
return f;
}
// In case the Source isn't playing.
return this->referenceDistance;
}
void Source::setRolloffFactor(float factor)
{
if (valid)
{
alSourcef(source, AL_ROLLOFF_FACTOR, factor);
}
this->rolloffFactor = factor;
}
float Source::getRolloffFactor() const
{
if (valid)
{
ALfloat f;
alGetSourcef(source, AL_ROLLOFF_FACTOR, &f);
return f;
}
// In case the Source isn't playing.
return this->rolloffFactor;
}
void Source::setMaxDistance(float distance)
{
if (valid)
{
alSourcef(source, AL_MAX_DISTANCE, distance);
}
this->maxDistance = distance;
}
float Source::getMaxDistance() const
{
if (valid)
{
ALfloat f;
alGetSourcef(source, AL_MAX_DISTANCE, &f);
return f;
}
// In case the Source isn't playing.
return this->maxDistance;
}
} // openal
} // audio
+15
View File
@@ -63,6 +63,11 @@ namespace openal
float direction[3];
bool looping;
bool paused;
float minVolume;
float maxVolume;
float referenceDistance;
float rolloffFactor;
float maxDistance;
float offsetSamples;
float offsetSeconds;
@@ -103,6 +108,16 @@ namespace openal
void setLooping(bool looping);
bool isLooping() const;
bool isStatic() const;
virtual void setMinVolume(float volume);
virtual float getMinVolume() const;
virtual void setMaxVolume(float volume);
virtual float getMaxVolume() const;
virtual void setReferenceDistance(float distance);
virtual float getReferenceDistance() const;
virtual void setRolloffFactor(float factor);
virtual float getRolloffFactor() const;
virtual void setMaxDistance(float distance);
virtual float getMaxDistance() const;
void playAtomic();
void stopAtomic();
+19
View File
@@ -236,7 +236,24 @@ namespace audio
luax_pushboolean(L, instance->canRecord());
return 1;
}
int w_setDistanceModel(lua_State * L)
{
const char *modelStr = luaL_checkstring(L, 1);
Audio::DistanceModel distanceModel;
Audio::getConstant(modelStr, distanceModel);
instance->setDistanceModel(distanceModel);
return 0;
}
int w_getDistanceModel(lua_State * L)
{
Audio::DistanceModel distanceModel = instance->getDistanceModel();
const char *modelStr;
Audio::getConstant(distanceModel, modelStr);
lua_pushstring(L, modelStr);
return 1;
}
// List of functions to wrap.
static const luaL_Reg functions[] = {
@@ -258,6 +275,8 @@ namespace audio
/*{ "record", w_record },
{ "getRecordedData", w_getRecordedData },
{ "stopRecording", w_stopRecording },*/
{ "setDistanceModel", w_setDistanceModel },
{ "getDistanceModel", w_getDistanceModel },
{ 0, 0 }
};
+2
View File
@@ -50,6 +50,8 @@ namespace audio
int w_getRecordedData(lua_State * L);
int w_stopRecording(lua_State * L);
int w_canRecord(lua_State * L);
int w_setDistanceModel(lua_State * L);
int w_getDistanceModel(lua_State * L);
extern "C" LOVE_EXPORT int luaopen_love_audio(lua_State * L);
} // audio
+70 -1
View File
@@ -211,11 +211,70 @@ namespace audio
int w_Source_isStatic(lua_State * L)
{
Source * t= luax_checksource(L, 1);
Source * t = luax_checksource(L, 1);
luax_pushboolean(L, t->isStatic());
return 1;
}
int w_Source_setMinVolume(lua_State * L)
{
Source * t = luax_checksource(L, 1);
t->setMinVolume((float)luaL_checknumber(L, 2));
return 0;
}
int w_Source_getMinVolume(lua_State * L)
{
Source * t = luax_checksource(L, 1);
lua_pushnumber(L, t->getMinVolume());
return 1;
}
int w_Source_setMaxVolume(lua_State * L)
{
Source * t = luax_checksource(L, 1);
t->setMaxVolume((float)luaL_checknumber(L, 2));
return 0;
}
int w_Source_getMaxVolume(lua_State * L)
{
Source * t = luax_checksource(L, 1);
lua_pushnumber(L, t->getMaxVolume());
return 1;
}
int w_Source_setDistance(lua_State * L)
{
Source * t = luax_checksource(L, 1);
t->setReferenceDistance((float)luaL_checknumber(L, 2));
if (!lua_isnoneornil(L, 3)) // lua_isnoneornil instead of lua_isnumber to throw an error
t->setMaxDistance((float)luaL_checknumber(L, 3)); // in case of invalid argument type
return 0;
}
int w_Source_getDistance(lua_State * L)
{
Source * t = luax_checksource(L, 1);
lua_pushnumber(L, t->getReferenceDistance());
lua_pushnumber(L, t->getMaxDistance());
return 2;
}
int w_Source_setRolloffFactor(lua_State * L)
{
Source * t = luax_checksource(L, 1);
t->setRolloffFactor((float)luaL_checknumber(L, 2));
return 0;
}
int w_Source_getRolloffFactor(lua_State * L)
{
Source * t = luax_checksource(L, 1);
lua_pushnumber(L, t->getRolloffFactor());
return 1;
}
static const luaL_Reg functions[] = {
{ "play", w_Source_play },
{ "stop", w_Source_stop },
@@ -241,6 +300,16 @@ namespace audio
{ "isStopped", w_Source_isStopped },
{ "isPaused", w_Source_isPaused },
{ "isStatic", w_Source_isStatic },
{ "setMinVolume", w_Source_setMinVolume },
{ "getMinVolume", w_Source_getMinVolume },
{ "setMaxVolume", w_Source_setMaxVolume },
{ "getMaxVolume", w_Source_getMaxVolume },
{ "setDistance", w_Source_setDistance },
{ "getDistance", w_Source_setDistance },
{ "setRolloffFactor", w_Source_setRolloffFactor },
{ "getRolloffFactor", w_Source_getRolloffFactor },
{ 0, 0 }
};
+8
View File
@@ -51,6 +51,14 @@ namespace audio
int w_Source_isStopped(lua_State * L);
int w_Source_isPaused(lua_State * L);
int w_Source_isStatic(lua_State * L);
int w_Source_setMinVolume(lua_State * L);
int w_Source_getMinVolume(lua_State * L);
int w_Source_setMaxVolume(lua_State * L);
int w_Source_getMinVolume(lua_State * L);
int w_Source_setDistance(lua_State * L);
int w_Source_getDistance(lua_State * L);
int w_Source_setRolloffFactor(lua_State * L);
int w_Source_getRolloffFactor(lua_State * L);
extern "C" int luaopen_source(lua_State * L);
} // audio