mirror of
https://github.com/love2d/love.git
synced 2026-08-17 02:58:31 +02:00
Applied the new style guidelines.
Well, sort of. Lot's more to be done, but this is a start.
This commit is contained in:
+319
-316
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
+724
-698
File diff suppressed because it is too large
Load Diff
+150
-151
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user