Applied the new style guidelines.

Well, sort of. Lot's more to be done, but this is a start.
This commit is contained in:
rude
2012-06-28 23:52:33 +02:00
parent bc4e59ba24
commit 81c38e22d0
302 changed files with 42648 additions and 42081 deletions
+319 -316
View File
@@ -1,316 +1,319 @@
/**
* Copyright (c) 2006-2012 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 source 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 source distribution.
**/
#include "Audio.h"
#include <common/delay.h>
#include <sound/Decoder.h>
namespace love
{
namespace audio
{
namespace openal
{
Audio::PoolThread::PoolThread(Pool* pool)
: pool(pool), finish(false)
{
}
void Audio::PoolThread::main()
{
while (true)
{
{
thread::Lock lock(mutex);
if (finish)
{
return;
}
}
pool->update();
delay(5);
}
}
void Audio::PoolThread::setFinish()
{
thread::Lock lock(mutex);
finish = true;
}
Audio::Audio() : distanceModel(DISTANCE_INVERSE_CLAMPED)
{
// Passing zero for default device.
device = alcOpenDevice(0);
if (device == 0)
throw love::Exception("Could not open device.");
context = alcCreateContext(device, 0);
if (context == 0)
throw love::Exception("Could not create context.");
alcMakeContextCurrent(context);
if (alcGetError(device) != ALC_NO_ERROR)
throw love::Exception("Could not make context current.");
/*std::string captureName(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
const ALCchar * devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
while (*devices)
{
std::string device(devices);
devices += device.size() + 1;
if (device.find("Mic") != std::string::npos || device.find("mic") != std::string::npos)
{
captureName = device;
}
}
capture = alcCaptureOpenDevice(captureName.c_str(), 8000, AL_FORMAT_MONO16, 262144); // about 32 seconds
if (!capture)
{
// We're not going to prevent LOVE from running without a microphone, but we should warn, at least
std::cerr << "Warning, couldn't open capture device! No audio input!" << std::endl;
}*/
// pool must be allocated after AL context.
pool = new Pool();
poolThread = new PoolThread(pool);
poolThread->start();
}
Audio::~Audio()
{
poolThread->setFinish();
poolThread->wait();
delete poolThread;
delete pool;
alcMakeContextCurrent(0);
alcDestroyContext(context);
//if (capture) alcCaptureCloseDevice(capture);
alcCloseDevice(device);
}
const char * Audio::getName() const
{
return "love.audio.openal";
}
love::audio::Source * Audio::newSource(love::sound::Decoder * decoder)
{
return new Source(pool, decoder);
}
love::audio::Source * Audio::newSource(love::sound::SoundData * soundData)
{
return new Source(pool, soundData);
}
int Audio::getNumSources() const
{
return pool->getNumSources();
}
int Audio::getMaxSources() const
{
return pool->getMaxSources();
}
void Audio::play(love::audio::Source * source)
{
source->play();
}
void Audio::stop(love::audio::Source * source)
{
source->stop();
}
void Audio::stop()
{
pool->stop();
}
void Audio::pause(love::audio::Source * source)
{
source->pause();
}
void Audio::pause()
{
pool->pause();
}
void Audio::resume(love::audio::Source * source)
{
source->resume();
}
void Audio::resume()
{
pool->resume();
}
void Audio::rewind(love::audio::Source * source)
{
source->rewind();
}
void Audio::rewind()
{
pool->rewind();
}
void Audio::setVolume(float volume)
{
alListenerf(AL_GAIN, volume);
}
float Audio::getVolume() const
{
ALfloat volume;
alGetListenerf(AL_GAIN, &volume);
return volume;
}
void Audio::getPosition(float * v) const
{
alGetListenerfv(AL_POSITION, v);
}
void Audio::setPosition(float * v)
{
alListenerfv(AL_POSITION, v);
}
void Audio::getOrientation(float * v) const
{
alGetListenerfv(AL_ORIENTATION, v);
}
void Audio::setOrientation(float * v)
{
alListenerfv(AL_ORIENTATION, v);
}
void Audio::getVelocity(float * v) const
{
alGetListenerfv(AL_VELOCITY, v);
}
void Audio::setVelocity(float * v)
{
alListenerfv(AL_VELOCITY, v);
}
void Audio::record()
{
if (!canRecord()) return;
alcCaptureStart(capture);
}
love::sound::SoundData * Audio::getRecordedData()
{
if (!canRecord())
return NULL;
int samplerate = 8000;
ALCint samples;
alcGetIntegerv(capture, ALC_CAPTURE_SAMPLES, 4, &samples);
void * data = malloc(samples * (2/sizeof(char)));
alcCaptureSamples(capture, data, samples);
love::sound::SoundData * sd = new love::sound::SoundData(data, samples, samplerate, 16, 1);
free(data);
return sd;
}
love::sound::SoundData * Audio::stopRecording(bool returnData)
{
if (!canRecord())
return NULL;
love::sound::SoundData * sd = NULL;
if (returnData)
{
sd = getRecordedData();
}
alcCaptureStop(capture);
return sd;
}
bool Audio::canRecord()
{
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
/**
* Copyright (c) 2006-2012 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 source 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 source distribution.
**/
#include "Audio.h"
#include "common/delay.h"
#include "sound/Decoder.h"
namespace love
{
namespace audio
{
namespace openal
{
Audio::PoolThread::PoolThread(Pool *pool)
: pool(pool)
, finish(false)
{
}
void Audio::PoolThread::main()
{
while (true)
{
{
thread::Lock lock(mutex);
if (finish)
{
return;
}
}
pool->update();
delay(5);
}
}
void Audio::PoolThread::setFinish()
{
thread::Lock lock(mutex);
finish = true;
}
Audio::Audio() : distanceModel(DISTANCE_INVERSE_CLAMPED)
{
// Passing zero for default device.
device = alcOpenDevice(0);
if (device == 0)
throw love::Exception("Could not open device.");
context = alcCreateContext(device, 0);
if (context == 0)
throw love::Exception("Could not create context.");
alcMakeContextCurrent(context);
if (alcGetError(device) != ALC_NO_ERROR)
throw love::Exception("Could not make context current.");
/*std::string captureName(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
const ALCchar * devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
while (*devices)
{
std::string device(devices);
devices += device.size() + 1;
if (device.find("Mic") != std::string::npos || device.find("mic") != std::string::npos)
{
captureName = device;
}
}
capture = alcCaptureOpenDevice(captureName.c_str(), 8000, AL_FORMAT_MONO16, 262144); // about 32 seconds
if (!capture)
{
// We're not going to prevent LOVE from running without a microphone, but we should warn, at least
std::cerr << "Warning, couldn't open capture device! No audio input!" << std::endl;
}*/
// pool must be allocated after AL context.
pool = new Pool();
poolThread = new PoolThread(pool);
poolThread->start();
}
Audio::~Audio()
{
poolThread->setFinish();
poolThread->wait();
delete poolThread;
delete pool;
alcMakeContextCurrent(0);
alcDestroyContext(context);
//if (capture) alcCaptureCloseDevice(capture);
alcCloseDevice(device);
}
const char *Audio::getName() const
{
return "love.audio.openal";
}
love::audio::Source *Audio::newSource(love::sound::Decoder *decoder)
{
return new Source(pool, decoder);
}
love::audio::Source *Audio::newSource(love::sound::SoundData *soundData)
{
return new Source(pool, soundData);
}
int Audio::getNumSources() const
{
return pool->getNumSources();
}
int Audio::getMaxSources() const
{
return pool->getMaxSources();
}
void Audio::play(love::audio::Source *source)
{
source->play();
}
void Audio::stop(love::audio::Source *source)
{
source->stop();
}
void Audio::stop()
{
pool->stop();
}
void Audio::pause(love::audio::Source *source)
{
source->pause();
}
void Audio::pause()
{
pool->pause();
}
void Audio::resume(love::audio::Source *source)
{
source->resume();
}
void Audio::resume()
{
pool->resume();
}
void Audio::rewind(love::audio::Source *source)
{
source->rewind();
}
void Audio::rewind()
{
pool->rewind();
}
void Audio::setVolume(float volume)
{
alListenerf(AL_GAIN, volume);
}
float Audio::getVolume() const
{
ALfloat volume;
alGetListenerf(AL_GAIN, &volume);
return volume;
}
void Audio::getPosition(float *v) const
{
alGetListenerfv(AL_POSITION, v);
}
void Audio::setPosition(float *v)
{
alListenerfv(AL_POSITION, v);
}
void Audio::getOrientation(float *v) const
{
alGetListenerfv(AL_ORIENTATION, v);
}
void Audio::setOrientation(float *v)
{
alListenerfv(AL_ORIENTATION, v);
}
void Audio::getVelocity(float *v) const
{
alGetListenerfv(AL_VELOCITY, v);
}
void Audio::setVelocity(float *v)
{
alListenerfv(AL_VELOCITY, v);
}
void Audio::record()
{
if (!canRecord()) return;
alcCaptureStart(capture);
}
love::sound::SoundData *Audio::getRecordedData()
{
if (!canRecord())
return NULL;
int samplerate = 8000;
ALCint samples;
alcGetIntegerv(capture, ALC_CAPTURE_SAMPLES, 4, &samples);
void *data = malloc(samples * (2/sizeof(char)));
alcCaptureSamples(capture, data, samples);
love::sound::SoundData *sd = new love::sound::SoundData(data, samples, samplerate, 16, 1);
free(data);
return sd;
}
love::sound::SoundData *Audio::stopRecording(bool returnData)
{
if (!canRecord())
return NULL;
love::sound::SoundData *sd = NULL;
if (returnData)
{
sd = getRecordedData();
}
alcCaptureStop(capture);
return sd;
}
bool Audio::canRecord()
{
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
+142 -140
View File
@@ -1,140 +1,142 @@
/**
* Copyright (c) 2006-2012 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 source 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 source distribution.
**/
#ifndef LOVE_AUDIO_OPENAL_AUDIO_H
#define LOVE_AUDIO_OPENAL_AUDIO_H
// STD
#include <queue>
#include <map>
#include <iostream>
#include <cmath>
// LOVE
#include <audio/Audio.h>
#include <common/config.h>
#include <sound/SoundData.h>
#include "Source.h"
#include "Pool.h"
#include <thread/threads.h>
// OpenAL
#ifdef LOVE_MACOSX
#include <OpenAL/alc.h>
#include <OpenAL/al.h>
#else
#include <AL/alc.h>
#include <AL/al.h>
#endif
namespace love
{
namespace audio
{
namespace openal
{
class Audio : public love::audio::Audio
{
private:
// The OpenAL device.
ALCdevice * device;
// The OpenAL capture device (microphone).
ALCdevice * capture;
// The OpenAL context.
ALCcontext * context;
// The Pool.
Pool * pool;
class PoolThread: public thread::ThreadBase {
protected:
Pool* pool;
// Set this to true when the thread should finish.
// Main thread will write to this value, and PoolThread
// will read from it.
volatile bool finish;
// finish lock
thread::Mutex mutex;
virtual void main();
public:
PoolThread(Pool* pool);
void setFinish();
};
PoolThread* poolThread;
DistanceModel distanceModel;
public:
Audio();
~Audio();
// Implements Module.
const char * getName() const;
// Implements Audio.
love::audio::Source * newSource(love::sound::Decoder * decoder);
love::audio::Source * newSource(love::sound::SoundData * soundData);
int getNumSources() const;
int getMaxSources() const;
void play(love::audio::Source * source);
void play();
void stop(love::audio::Source * source);
void stop();
void pause(love::audio::Source * source);
void pause();
void resume(love::audio::Source * source);
void resume();
void rewind(love::audio::Source * source);
void rewind();
void setVolume(float volume);
float getVolume() const;
void getPosition(float * v) const;
void setPosition(float * v);
void getOrientation(float * v) const;
void setOrientation(float * v);
void getVelocity(float * v) const;
void setVelocity(float * v);
void record();
love::sound::SoundData * getRecordedData();
love::sound::SoundData * stopRecording(bool returnData);
bool canRecord();
DistanceModel getDistanceModel() const;
void setDistanceModel(DistanceModel distanceModel);
}; // Audio
} // openal
} // audio
} // love
#endif // LOVE_AUDIO_OPENAL_AUDIO_H
/**
* Copyright (c) 2006-2012 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 source 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 source distribution.
**/
#ifndef LOVE_AUDIO_OPENAL_AUDIO_H
#define LOVE_AUDIO_OPENAL_AUDIO_H
// STD
#include <queue>
#include <map>
#include <iostream>
#include <cmath>
// LOVE
#include "audio/Audio.h"
#include "common/config.h"
#include "sound/SoundData.h"
#include "Source.h"
#include "Pool.h"
#include "thread/threads.h"
// OpenAL
#ifdef LOVE_MACOSX
#include <OpenAL/alc.h>
#include <OpenAL/al.h>
#else
#include <AL/alc.h>
#include <AL/al.h>
#endif
namespace love
{
namespace audio
{
namespace openal
{
class Audio : public love::audio::Audio
{
public:
Audio();
~Audio();
// Implements Module.
const char *getName() const;
// Implements Audio.
love::audio::Source *newSource(love::sound::Decoder *decoder);
love::audio::Source *newSource(love::sound::SoundData *soundData);
int getNumSources() const;
int getMaxSources() const;
void play(love::audio::Source *source);
void play();
void stop(love::audio::Source *source);
void stop();
void pause(love::audio::Source *source);
void pause();
void resume(love::audio::Source *source);
void resume();
void rewind(love::audio::Source *source);
void rewind();
void setVolume(float volume);
float getVolume() const;
void getPosition(float *v) const;
void setPosition(float *v);
void getOrientation(float *v) const;
void setOrientation(float *v);
void getVelocity(float *v) const;
void setVelocity(float *v);
void record();
love::sound::SoundData *getRecordedData();
love::sound::SoundData *stopRecording(bool returnData);
bool canRecord();
DistanceModel getDistanceModel() const;
void setDistanceModel(DistanceModel distanceModel);
private:
// The OpenAL device.
ALCdevice *device;
// The OpenAL capture device (microphone).
ALCdevice *capture;
// The OpenAL context.
ALCcontext *context;
// The Pool.
Pool *pool;
class PoolThread: public thread::ThreadBase
{
protected:
Pool *pool;
// Set this to true when the thread should finish.
// Main thread will write to this value, and PoolThread
// will read from it.
volatile bool finish;
// finish lock
thread::Mutex mutex;
virtual void main();
public:
PoolThread(Pool *pool);
void setFinish();
};
PoolThread *poolThread;
DistanceModel distanceModel;
}; // Audio
} // openal
} // audio
} // love
#endif // LOVE_AUDIO_OPENAL_AUDIO_H
+293 -292
View File
@@ -1,292 +1,293 @@
/**
* Copyright (c) 2006-2012 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 source 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 source distribution.
**/
#include "Pool.h"
#include "Source.h"
namespace love
{
namespace audio
{
namespace openal
{
Pool::Pool()
{
// Generate sources.
alGenSources(NUM_SOURCES, sources);
// Create the mutex.
mutex = new thread::Mutex();
if (alGetError() != AL_NO_ERROR)
throw love::Exception("Could not generate sources.");
// Make all sources available initially.
for (int i = 0; i < NUM_SOURCES; 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);
#endif
available.push(sources[i]);
}
}
Pool::~Pool()
{
stop();
delete mutex;
// Free all sources.
alDeleteSources(NUM_SOURCES, sources);
}
bool Pool::isAvailable() const
{
bool has = false;
{
thread::Lock lock(mutex);
has = !available.empty();
}
return has;
}
bool Pool::isPlaying(Source * s)
{
bool p = false;
{
thread::Lock lock(mutex);
for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
{
if (i->first == s)
p = true;
}
}
return p;
}
void Pool::update()
{
thread::Lock lock(mutex);
std::map<Source *, ALuint>::iterator i = playing.begin();
while (i != playing.end())
{
if (!i->first->update())
{
i->first->stopAtomic();
i->first->rewindAtomic();
i->first->release();
available.push(i->second);
playing.erase(i++);
}
else
i++;
}
}
int Pool::getNumSources() const
{
return playing.size();
}
int Pool::getMaxSources() const
{
return NUM_SOURCES;
}
bool Pool::play(Source * source, ALuint & out)
{
bool ok;
out = 0;
thread::Lock lock(mutex);
bool alreadyPlaying = findSource(source, out);
if (!alreadyPlaying)
{
// Try to play.
if (!available.empty())
{
// Get the first available source.
out = available.front();
// Remove it.
available.pop();
// Insert into map of playing sources.
playing.insert(std::pair<Source *, ALuint>(source, out));
source->retain();
source->playAtomic();
ok = true;
}
else
{
ok = false;
}
}
else
{
ok = true;
}
return ok;
}
void Pool::stop()
{
thread::Lock lock(mutex);
for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
{
i->first->stopAtomic();
i->first->release();
available.push(i->second);
}
playing.clear();
}
void Pool::stop(Source * source)
{
thread::Lock lock(mutex);
removeSource(source);
}
void Pool::pause()
{
thread::Lock lock(mutex);
for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
i->first->pauseAtomic();
}
void Pool::pause(Source * source)
{
thread::Lock lock(mutex);
ALuint out;
if (findSource(source, out))
source->pauseAtomic();
}
void Pool::resume()
{
thread::Lock lock(mutex);
for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
i->first->resumeAtomic();
}
void Pool::resume(Source * source)
{
thread::Lock lock(mutex);
ALuint out;
if (findSource(source, out))
source->resumeAtomic();
}
void Pool::rewind()
{
thread::Lock lock(mutex);
for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
i->first->rewindAtomic();
}
// For those times we don't need it backed.
void Pool::softRewind(Source * source)
{
thread::Lock lock(mutex);
source->rewindAtomic();
}
void Pool::rewind(Source * source)
{
thread::Lock lock(mutex);
source->rewindAtomic();
}
void Pool::release(Source * source)
{
ALuint s = findi(source);
if (s != 0)
{
available.push(s);
playing.erase(source);
}
}
void Pool::seek(Source * source, float offset, void * unit)
{
thread::Lock lock(mutex);
return source->seekAtomic(offset, unit);
}
float Pool::tell(Source * source, void * unit)
{
thread::Lock lock(mutex);
return source->tellAtomic(unit);
}
ALuint Pool::findi(const Source * source) const
{
std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
if (i != playing.end())
return i->second;
return 0;
}
bool Pool::findSource(Source * source, ALuint & out)
{
std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
bool found = i != playing.end();
if (found)
out = i->second;
return found;
}
bool Pool::removeSource(Source * source)
{
std::map<Source *, ALuint>::iterator i = playing.find((Source *)source);
if (i != playing.end())
{
source->stopAtomic();
available.push(i->second);
playing.erase(i++);
source->release();
return true;
}
return false;
}
} // openal
} // audio
} // love
/**
* Copyright (c) 2006-2012 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 source 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 source distribution.
**/
#include "Pool.h"
#include "Source.h"
namespace love
{
namespace audio
{
namespace openal
{
Pool::Pool()
{
// Generate sources.
alGenSources(NUM_SOURCES, sources);
// Create the mutex.
mutex = new thread::Mutex();
if (alGetError() != AL_NO_ERROR)
throw love::Exception("Could not generate sources.");
// Make all sources available initially.
for (int i = 0; i < NUM_SOURCES; 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);
#endif
available.push(sources[i]);
}
}
Pool::~Pool()
{
stop();
delete mutex;
// Free all sources.
alDeleteSources(NUM_SOURCES, sources);
}
bool Pool::isAvailable() const
{
bool has = false;
{
thread::Lock lock(mutex);
has = !available.empty();
}
return has;
}
bool Pool::isPlaying(Source *s)
{
bool p = false;
{
thread::Lock lock(mutex);
for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
{
if (i->first == s)
p = true;
}
}
return p;
}
void Pool::update()
{
thread::Lock lock(mutex);
std::map<Source *, ALuint>::iterator i = playing.begin();
while (i != playing.end())
{
if (!i->first->update())
{
i->first->stopAtomic();
i->first->rewindAtomic();
i->first->release();
available.push(i->second);
playing.erase(i++);
}
else
i++;
}
}
int Pool::getNumSources() const
{
return playing.size();
}
int Pool::getMaxSources() const
{
return NUM_SOURCES;
}
bool Pool::play(Source *source, ALuint &out)
{
bool ok;
out = 0;
thread::Lock lock(mutex);
bool alreadyPlaying = findSource(source, out);
if (!alreadyPlaying)
{
// Try to play.
if (!available.empty())
{
// Get the first available source.
out = available.front();
// Remove it.
available.pop();
// Insert into map of playing sources.
playing.insert(std::pair<Source *, ALuint>(source, out));
source->retain();
source->playAtomic();
ok = true;
}
else
{
ok = false;
}
}
else
{
ok = true;
}
return ok;
}
void Pool::stop()
{
thread::Lock lock(mutex);
for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
{
i->first->stopAtomic();
i->first->release();
available.push(i->second);
}
playing.clear();
}
void Pool::stop(Source *source)
{
thread::Lock lock(mutex);
removeSource(source);
}
void Pool::pause()
{
thread::Lock lock(mutex);
for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
i->first->pauseAtomic();
}
void Pool::pause(Source *source)
{
thread::Lock lock(mutex);
ALuint out;
if (findSource(source, out))
source->pauseAtomic();
}
void Pool::resume()
{
thread::Lock lock(mutex);
for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
i->first->resumeAtomic();
}
void Pool::resume(Source *source)
{
thread::Lock lock(mutex);
ALuint out;
if (findSource(source, out))
source->resumeAtomic();
}
void Pool::rewind()
{
thread::Lock lock(mutex);
for (std::map<Source *, ALuint>::iterator i = playing.begin(); i != playing.end(); i++)
i->first->rewindAtomic();
}
// For those times we don't need it backed.
void Pool::softRewind(Source *source)
{
thread::Lock lock(mutex);
source->rewindAtomic();
}
void Pool::rewind(Source *source)
{
thread::Lock lock(mutex);
source->rewindAtomic();
}
void Pool::release(Source *source)
{
ALuint s = findi(source);
if (s != 0)
{
available.push(s);
playing.erase(source);
}
}
void Pool::seek(Source *source, float offset, void *unit)
{
thread::Lock lock(mutex);
return source->seekAtomic(offset, unit);
}
float Pool::tell(Source *source, void *unit)
{
thread::Lock lock(mutex);
return source->tellAtomic(unit);
}
ALuint Pool::findi(const Source *source) const
{
std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
if (i != playing.end())
return i->second;
return 0;
}
bool Pool::findSource(Source *source, ALuint &out)
{
std::map<Source *, ALuint>::const_iterator i = playing.find((Source *)source);
bool found = i != playing.end();
if (found)
out = i->second;
return found;
}
bool Pool::removeSource(Source *source)
{
std::map<Source *, ALuint>::iterator i = playing.find((Source *)source);
if (i != playing.end())
{
source->stopAtomic();
available.push(i->second);
playing.erase(i++);
source->release();
return true;
}
return false;
}
} // openal
} // audio
} // love
+124 -126
View File
@@ -1,126 +1,124 @@
/**
* Copyright (c) 2006-2012 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 source 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 source distribution.
**/
#ifndef LOVE_AUDIO_OPENAL_POOL_H
#define LOVE_AUDIO_OPENAL_POOL_H
// STD
#include <queue>
#include <map>
#include <iostream>
#include <cmath>
// LOVE
#include <common/config.h>
#include <common/Exception.h>
#include <thread/threads.h>
// OpenAL
#ifdef LOVE_MACOSX
#include <OpenAL/alc.h>
#include <OpenAL/al.h>
#else
#include <AL/alc.h>
#include <AL/al.h>
#include <AL/alext.h>
#endif
namespace love
{
namespace audio
{
namespace openal
{
class Source;
class Pool
{
private:
// Number of OpenAL sources.
static const int NUM_SOURCES = 64;
// OpenAL sources
ALuint sources[NUM_SOURCES];
// A queue of available sources.
std::queue<ALuint> available;
// A map of playing sources.
std::map<Source *, ALuint> playing;
// Only one thread can access this object at the same time. This mutex will
// make sure of that.
thread::Mutex* mutex;
public:
Pool();
~Pool();
/**
* Checks whether an OpenAL source is available.
* @return True if at least one is available, false otherwise.
**/
bool isAvailable() const;
/**
* Checks whether a Source is currently in the playing list.
**/
bool isPlaying(Source * s);
void update();
int getNumSources() const;
int getMaxSources() const;
bool play(Source * source, ALuint & out);
void stop();
void stop(Source * source);
void pause();
void pause(Source * source);
void resume();
void resume(Source * source);
void rewind();
void rewind(Source * source);
void softRewind(Source * source);
void seek(Source * source, float offset, void * unit);
float tell(Source * source, void * unit);
private:
/**
* Makes the specified OpenAL source available for use.
* @param source The OpenAL source.
**/
void release(Source * source);
ALuint findi(const Source * source) const;
bool findSource(Source * source, ALuint & out);
bool removeSource(Source * source);
}; // Pool
} // openal
} // audio
} // love
#endif // LOVE_AUDIO_OPENAL_POOL_H
/**
* Copyright (c) 2006-2012 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 source 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 source distribution.
**/
#ifndef LOVE_AUDIO_OPENAL_POOL_H
#define LOVE_AUDIO_OPENAL_POOL_H
// STD
#include <queue>
#include <map>
#include <iostream>
#include <cmath>
// LOVE
#include "common/config.h"
#include "common/Exception.h"
#include "thread/threads.h"
// OpenAL
#ifdef LOVE_MACOSX
#include <OpenAL/alc.h>
#include <OpenAL/al.h>
#else
#include <AL/alc.h>
#include <AL/al.h>
#include <AL/alext.h>
#endif
namespace love
{
namespace audio
{
namespace openal
{
class Source;
class Pool
{
public:
Pool();
~Pool();
/**
* Checks whether an OpenAL source is available.
* @return True if at least one is available, false otherwise.
**/
bool isAvailable() const;
/**
* Checks whether a Source is currently in the playing list.
**/
bool isPlaying(Source *s);
void update();
int getNumSources() const;
int getMaxSources() const;
bool play(Source *source, ALuint &out);
void stop();
void stop(Source *source);
void pause();
void pause(Source *source);
void resume();
void resume(Source *source);
void rewind();
void rewind(Source *source);
void softRewind(Source *source);
void seek(Source *source, float offset, void *unit);
float tell(Source *source, void *unit);
private:
/**
* Makes the specified OpenAL source available for use.
* @param source The OpenAL source.
**/
void release(Source *source);
ALuint findi(const Source *source) const;
bool findSource(Source *source, ALuint &out);
bool removeSource(Source *source);
// Number of OpenAL sources.
static const int NUM_SOURCES = 64;
// OpenAL sources
ALuint sources[NUM_SOURCES];
// A queue of available sources.
std::queue<ALuint> available;
// A map of playing sources.
std::map<Source *, ALuint> playing;
// Only one thread can access this object at the same time. This mutex will
// make sure of that.
thread::Mutex *mutex;
}; // Pool
} // openal
} // audio
} // love
#endif // LOVE_AUDIO_OPENAL_POOL_H
File diff suppressed because it is too large Load Diff
+150 -151
View File
@@ -1,151 +1,150 @@
/**
* Copyright (c) 2006-2012 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 source 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 source distribution.
**/
#ifndef LOVE_AUDIO_OPENAL_SOURCE_H
#define LOVE_AUDIO_OPENAL_SOURCE_H
// LOVE
#include <common/config.h>
#include <common/Object.h>
#include <audio/Source.h>
#include <sound/SoundData.h>
#include <sound/Decoder.h>
// OpenAL
#ifdef LOVE_MACOSX
#include <OpenAL/alc.h>
#include <OpenAL/al.h>
#else
#include <AL/alc.h>
#include <AL/al.h>
#endif
namespace love
{
namespace audio
{
namespace openal
{
class Audio;
class Pool;
class Source : public love::audio::Source
{
private:
Pool * pool;
ALuint source;
bool valid;
static const unsigned int MAX_BUFFERS = 32;
ALuint buffers[MAX_BUFFERS];
float pitch;
float volume;
float position[3];
float velocity[3];
float direction[3];
bool looping;
bool paused;
float minVolume;
float maxVolume;
float referenceDistance;
float rolloffFactor;
float maxDistance;
float offsetSamples;
float offsetSeconds;
love::sound::Decoder * decoder;
unsigned int toLoop;
public:
Source(Pool * pool, love::sound::SoundData * soundData);
Source(Pool * pool, love::sound::Decoder * decoder);
virtual ~Source();
virtual love::audio::Source * copy();
virtual void play();
virtual void stop();
virtual void pause();
virtual void resume();
virtual void rewind();
virtual bool isStopped() const;
virtual bool isPaused() const;
virtual bool isFinished() const;
virtual bool update();
virtual void setPitch(float pitch);
virtual float getPitch() const;
virtual void setVolume(float volume);
virtual float getVolume() const;
virtual void seekAtomic(float offset, void * unit);
virtual void seek(float offset, Unit unit);
virtual float tellAtomic(void * unit) const;
virtual float tell(Unit unit);
virtual void setPosition(float * v);
virtual void getPosition(float * v) const;
virtual void setVelocity(float * v);
virtual void getVelocity(float * v) const;
virtual void setDirection(float * v);
virtual void getDirection(float * v) const;
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();
void pauseAtomic();
void resumeAtomic();
void rewindAtomic();
private:
void reset(ALenum source);
void setFloatv(float * dst, const float * src) const;
/**
* Gets the OpenAL format identifier based on number of
* channels and bits.
* @param channels Either 1 (mono) or 2 (stereo).
* @param bits Either 8-bit samples, or 16-bit samples.
* @return One of AL_FORMAT_*, or 0 if unsupported format.
**/
ALenum getFormat(int channels, int bits) const;
int streamAtomic(ALuint buffer, love::sound::Decoder * d);
}; // Source
} // openal
} // audio
} // love
#endif // LOVE_AUDIO_OPENAL_SOURCE_H
/**
* Copyright (c) 2006-2012 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 source 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 source distribution.
**/
#ifndef LOVE_AUDIO_OPENAL_SOURCE_H
#define LOVE_AUDIO_OPENAL_SOURCE_H
// LOVE
#include "common/config.h"
#include "common/Object.h"
#include "audio/Source.h"
#include "sound/SoundData.h"
#include "sound/Decoder.h"
// OpenAL
#ifdef LOVE_MACOSX
#include <OpenAL/alc.h>
#include <OpenAL/al.h>
#else
#include <AL/alc.h>
#include <AL/al.h>
#endif
namespace love
{
namespace audio
{
namespace openal
{
class Audio;
class Pool;
class Source : public love::audio::Source
{
public:
Source(Pool *pool, love::sound::SoundData *soundData);
Source(Pool *pool, love::sound::Decoder *decoder);
virtual ~Source();
virtual love::audio::Source *copy();
virtual void play();
virtual void stop();
virtual void pause();
virtual void resume();
virtual void rewind();
virtual bool isStopped() const;
virtual bool isPaused() const;
virtual bool isFinished() const;
virtual bool update();
virtual void setPitch(float pitch);
virtual float getPitch() const;
virtual void setVolume(float volume);
virtual float getVolume() const;
virtual void seekAtomic(float offset, void *unit);
virtual void seek(float offset, Unit unit);
virtual float tellAtomic(void *unit) const;
virtual float tell(Unit unit);
virtual void setPosition(float *v);
virtual void getPosition(float *v) const;
virtual void setVelocity(float *v);
virtual void getVelocity(float *v) const;
virtual void setDirection(float *v);
virtual void getDirection(float *v) const;
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();
void pauseAtomic();
void resumeAtomic();
void rewindAtomic();
private:
void reset(ALenum source);
void setFloatv(float *dst, const float *src) const;
/**
* Gets the OpenAL format identifier based on number of
* channels and bits.
* @param channels Either 1 (mono) or 2 (stereo).
* @param bits Either 8-bit samples, or 16-bit samples.
* @return One of AL_FORMAT_*, or 0 if unsupported format.
**/
ALenum getFormat(int channels, int bits) const;
int streamAtomic(ALuint buffer, love::sound::Decoder *d);
Pool *pool;
ALuint source;
bool valid;
static const unsigned int MAX_BUFFERS = 32;
ALuint buffers[MAX_BUFFERS];
float pitch;
float volume;
float position[3];
float velocity[3];
float direction[3];
bool looping;
bool paused;
float minVolume;
float maxVolume;
float referenceDistance;
float rolloffFactor;
float maxDistance;
float offsetSamples;
float offsetSeconds;
love::sound::Decoder *decoder;
unsigned int toLoop;
}; // Source
} // openal
} // audio
} // love
#endif // LOVE_AUDIO_OPENAL_SOURCE_H