Merged default into minor

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2014-03-12 02:21:27 -03:00
124 changed files with 3248 additions and 1078 deletions
+28 -14
View File
@@ -69,22 +69,25 @@ void Audio::PoolThread::setFinish()
}
Audio::Audio()
: distanceModel(DISTANCE_INVERSE_CLAMPED)
: device(nullptr)
, capture(nullptr)
, context(nullptr)
, pool(nullptr)
, poolThread(nullptr)
, distanceModel(DISTANCE_INVERSE_CLAMPED)
{
// Passing zero for default device.
device = alcOpenDevice(0);
// Passing null for default device.
device = alcOpenDevice(nullptr);
if (device == 0)
if (device == nullptr)
throw love::Exception("Could not open device.");
context = alcCreateContext(device, 0);
context = alcCreateContext(device, nullptr);
if (context == 0)
if (context == nullptr)
throw love::Exception("Could not create context.");
alcMakeContextCurrent(context);
if (alcGetError(device) != ALC_NO_ERROR)
if (!alcMakeContextCurrent(context) || alcGetError(device) != ALC_NO_ERROR)
throw love::Exception("Could not make context current.");
/*std::string captureName(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
@@ -108,7 +111,18 @@ Audio::Audio()
}*/
// pool must be allocated after AL context.
pool = new Pool();
try
{
pool = new Pool();
}
catch (love::Exception &)
{
alcMakeContextCurrent(nullptr);
alcDestroyContext(context);
//if (capture) alcCaptureCloseDevice(capture);
alcCloseDevice(device);
throw;
}
poolThread = new PoolThread(pool);
poolThread->start();
@@ -122,7 +136,7 @@ Audio::~Audio()
delete poolThread;
delete pool;
alcMakeContextCurrent(0);
alcMakeContextCurrent(nullptr);
alcDestroyContext(context);
//if (capture) alcCaptureCloseDevice(capture);
alcCloseDevice(device);
@@ -154,9 +168,9 @@ int Audio::getMaxSources() const
return pool->getMaxSources();
}
void Audio::play(love::audio::Source *source)
bool Audio::play(love::audio::Source *source)
{
source->play();
return source->play();
}
void Audio::stop(love::audio::Source *source)
@@ -281,7 +295,7 @@ bool Audio::canRecord()
Audio::DistanceModel Audio::getDistanceModel() const
{
return this->distanceModel;
return distanceModel;
}
void Audio::setDistanceModel(DistanceModel distanceModel)
+1 -2
View File
@@ -67,8 +67,7 @@ public:
love::audio::Source *newSource(love::sound::SoundData *soundData);
int getSourceCount() const;
int getMaxSources() const;
void play(love::audio::Source *source);
void play();
bool play(love::audio::Source *source);
void stop(love::audio::Source *source);
void stop();
void pause(love::audio::Source *source);
+32 -12
View File
@@ -30,23 +30,45 @@ namespace openal
{
Pool::Pool()
: sources()
, totalSources(0)
, mutex(nullptr)
{
// Clear errors.
alGetError();
// Generate sources.
alGenSources(NUM_SOURCES, sources);
for (int i = 0; i < MAX_SOURCES; i++)
{
alGenSources(1, &sources[i]);
// We might hit an implementation-dependent limit on the total number
// of sources before reaching MAX_SOURCES.
if (alGetError() != AL_NO_ERROR)
break;
totalSources++;
}
if (totalSources < 4)
throw love::Exception("Could not generate sources.");
// Create the mutex.
mutex = thread::newMutex();
if (alGetError() != AL_NO_ERROR)
throw love::Exception("Could not generate sources.");
ALboolean hasext = alIsExtensionPresent("AL_SOFT_direct_channels");
// Make all sources available initially.
for (int i = 0; i < NUM_SOURCES; i++)
for (int i = 0; i < totalSources; i++)
{
#ifdef AL_DIRECT_CHANNELS_SOFT
// Bypassing virtualization of speakers for multi-channel sources in OpenAL Soft.
alSourcei(sources[i], AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
#ifdef AL_SOFT_direct_channels
if (hasext)
{
// Bypass virtualization of speakers for multi-channel sources in OpenAL Soft.
alSourcei(sources[i], AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
}
#endif
available.push(sources[i]);
}
}
@@ -58,7 +80,7 @@ Pool::~Pool()
delete mutex;
// Free all sources.
alDeleteSources(NUM_SOURCES, sources);
alDeleteSources(totalSources, sources);
}
bool Pool::isAvailable() const
@@ -113,7 +135,7 @@ int Pool::getSourceCount() const
int Pool::getMaxSources() const
{
return NUM_SOURCES;
return totalSources;
}
bool Pool::play(Source *source, ALuint &out)
@@ -141,9 +163,7 @@ bool Pool::play(Source *source, ALuint &out)
source->retain();
source->playAtomic();
ok = true;
ok = source->playAtomic();
}
else
{
+8 -3
View File
@@ -36,6 +36,7 @@
#ifdef LOVE_MACOSX_USE_FRAMEWORKS
#include <OpenAL-Soft/alc.h>
#include <OpenAL-Soft/al.h>
#include <OpenAL-Soft/alext.h>
#else
#include <AL/alc.h>
#include <AL/al.h>
@@ -99,11 +100,15 @@ private:
bool findSource(Source *source, ALuint &out);
bool removeSource(Source *source);
// Number of OpenAL sources.
static const int NUM_SOURCES = 64;
// Maximum possible number of OpenAL sources the pool attempts to generate.
static const int MAX_SOURCES = 64;
// OpenAL sources
ALuint sources[NUM_SOURCES];
ALuint sources[MAX_SOURCES];
// Total number of created sources in the pool.
int totalSources;
// A queue of available sources.
std::queue<ALuint> available;
+13 -3
View File
@@ -165,15 +165,16 @@ love::audio::Source *Source::clone()
return new Source(*this);
}
void Source::play()
bool Source::play()
{
if (valid && paused)
{
pool->resume(this);
return;
return true;
}
valid = pool->play(this, source);
return valid;
}
void Source::stop()
@@ -512,7 +513,7 @@ bool Source::isLooping() const
return looping;
}
void Source::playAtomic()
bool Source::playAtomic()
{
if (type == TYPE_STATIC)
{
@@ -539,10 +540,19 @@ void Source::playAtomic()
// of the new one.
reset();
// Clear errors.
alGetError();
alSourcePlay(source);
// alSourcePlay may fail if the system has reached its limit of simultaneous
// playing sources.
bool success = alGetError() == AL_NO_ERROR;
valid = true; //if it fails it will be set to false again
//but this prevents a horrible, horrible bug
return success;
}
void Source::stopAtomic()
+2 -2
View File
@@ -76,7 +76,7 @@ public:
virtual ~Source();
virtual love::audio::Source *clone();
virtual void play();
virtual bool play();
virtual void stop();
virtual void pause();
virtual void resume();
@@ -117,7 +117,7 @@ public:
virtual float getMaxDistance() const;
virtual int getChannels() const;
void playAtomic();
bool playAtomic();
void stopAtomic();
void pauseAtomic();
void resumeAtomic();