diff --git a/platform/msvc2010/love.vcxproj b/platform/msvc2010/love.vcxproj index 49969a5d4..7e283f82d 100644 --- a/platform/msvc2010/love.vcxproj +++ b/platform/msvc2010/love.vcxproj @@ -111,6 +111,7 @@ false + @@ -536,6 +537,7 @@ opengl32.lib;glu32.lib;DevIL.lib;freetype244MT.lib;libmpg123.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;lua.lib;modplug.lib;OpenAL32.lib;physfs.lib;SDL.lib;SDLmain.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) lib Windows + /FORCE:MULTIPLE %(AdditionalOptions) diff --git a/platform/msvc2010/love.vcxproj.filters b/platform/msvc2010/love.vcxproj.filters index 1853cc290..10195ac16 100644 --- a/platform/msvc2010/love.vcxproj.filters +++ b/platform/msvc2010/love.vcxproj.filters @@ -292,9 +292,6 @@ modules\joystick\sdl - - modules\sound - modules\sound @@ -736,12 +733,18 @@ common + + modules\sound + modules\window modules\window\sdl + + modules\audio + @@ -1333,4 +1336,4 @@ - \ No newline at end of file + diff --git a/src/modules/audio/Audio.cpp b/src/modules/audio/Audio.cpp new file mode 100644 index 000000000..14a658592 --- /dev/null +++ b/src/modules/audio/Audio.cpp @@ -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::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::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 diff --git a/src/modules/audio/Audio.h b/src/modules/audio/Audio.h index 22dcbfe7f..32e881337 100644 --- a/src/modules/audio/Audio.h +++ b/src/modules/audio/Audio.h @@ -22,6 +22,7 @@ #define LOVE_AUDIO_AUDIO_H #include +#include #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::Entry distanceModelEntries[]; + static StringMap distanceModels; }; // Audio } // audio diff --git a/src/modules/audio/Source.h b/src/modules/audio/Source.h index e03bc5212..d9446492d 100644 --- a/src/modules/audio/Source.h +++ b/src/modules/audio/Source.h @@ -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); diff --git a/src/modules/audio/null/Audio.cpp b/src/modules/audio/null/Audio.cpp index f14d3f1da..26278e039 100644 --- a/src/modules/audio/null/Audio.cpp +++ b/src/modules/audio/null/Audio.cpp @@ -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 diff --git a/src/modules/audio/null/Audio.h b/src/modules/audio/null/Audio.h index 3ccc75689..f573f6595 100644 --- a/src/modules/audio/null/Audio.h +++ b/src/modules/audio/null/Audio.h @@ -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 diff --git a/src/modules/audio/null/Source.cpp b/src/modules/audio/null/Source.cpp index 731262bc2..866ea79cf 100644 --- a/src/modules/audio/null/Source.cpp +++ b/src/modules/audio/null/Source.cpp @@ -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 diff --git a/src/modules/audio/null/Source.h b/src/modules/audio/null/Source.h index e8ec211a1..04e1b4535 100644 --- a/src/modules/audio/null/Source.h +++ b/src/modules/audio/null/Source.h @@ -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 diff --git a/src/modules/audio/openal/Audio.cpp b/src/modules/audio/openal/Audio.cpp index f40be6bf7..0b11b6dc8 100644 --- a/src/modules/audio/openal/Audio.cpp +++ b/src/modules/audio/openal/Audio.cpp @@ -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 diff --git a/src/modules/audio/openal/Audio.h b/src/modules/audio/openal/Audio.h index e4cfa3da2..4c063d20a 100644 --- a/src/modules/audio/openal/Audio.h +++ b/src/modules/audio/openal/Audio.h @@ -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 diff --git a/src/modules/audio/openal/Source.cpp b/src/modules/audio/openal/Source.cpp index 923420f7f..842c52464 100644 --- a/src/modules/audio/openal/Source.cpp +++ b/src/modules/audio/openal/Source.cpp @@ -24,6 +24,7 @@ // STD #include +#include 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 diff --git a/src/modules/audio/openal/Source.h b/src/modules/audio/openal/Source.h index c819d1033..3df084dcf 100644 --- a/src/modules/audio/openal/Source.h +++ b/src/modules/audio/openal/Source.h @@ -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(); diff --git a/src/modules/audio/wrap_Audio.cpp b/src/modules/audio/wrap_Audio.cpp index 5fce1a421..f2752b924 100644 --- a/src/modules/audio/wrap_Audio.cpp +++ b/src/modules/audio/wrap_Audio.cpp @@ -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 } }; diff --git a/src/modules/audio/wrap_Audio.h b/src/modules/audio/wrap_Audio.h index 437018c1d..b26409c1c 100644 --- a/src/modules/audio/wrap_Audio.h +++ b/src/modules/audio/wrap_Audio.h @@ -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 diff --git a/src/modules/audio/wrap_Source.cpp b/src/modules/audio/wrap_Source.cpp index 4c4a9597f..697816f6a 100644 --- a/src/modules/audio/wrap_Source.cpp +++ b/src/modules/audio/wrap_Source.cpp @@ -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 } }; diff --git a/src/modules/audio/wrap_Source.h b/src/modules/audio/wrap_Source.h index 6deee0cf0..278a66d62 100644 --- a/src/modules/audio/wrap_Source.h +++ b/src/modules/audio/wrap_Source.h @@ -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