mirror of
https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1.git
synced 2026-03-20 06:53:30 +00:00
the whole game
This commit is contained in:
29
src/platform/audio/SoundSystem.h
Executable file
29
src/platform/audio/SoundSystem.h
Executable file
@@ -0,0 +1,29 @@
|
||||
#ifndef SoundSystem_H__
|
||||
#define SoundSystem_H__
|
||||
|
||||
#include "../../world/level/tile/Tile.h"
|
||||
#include <string>
|
||||
|
||||
class SoundDesc;
|
||||
|
||||
class SoundSystem
|
||||
{
|
||||
public:
|
||||
SoundSystem() {}
|
||||
virtual ~SoundSystem() {}
|
||||
|
||||
virtual bool isAvailable() { return false; }
|
||||
virtual void enable(bool status) {}
|
||||
|
||||
virtual void setListenerPos(float x, float y, float z){}
|
||||
virtual void setListenerAngle(float deg){}
|
||||
|
||||
virtual void load(const std::string& name){}
|
||||
virtual void play(const std::string& name){}
|
||||
virtual void pause(const std::string& name){}
|
||||
virtual void stop(const std::string& name){}
|
||||
|
||||
virtual void playAt(const SoundDesc& desc, float x, float y, float z, float volume, float pitch){}
|
||||
};
|
||||
|
||||
#endif /*SoundSystem_H__ */
|
||||
253
src/platform/audio/SoundSystemAL.cpp
Executable file
253
src/platform/audio/SoundSystemAL.cpp
Executable file
@@ -0,0 +1,253 @@
|
||||
//#include "ios/OpenALSupport.h"
|
||||
#include "SoundSystemAL.h"
|
||||
#include "../../util/Mth.h"
|
||||
#include "../../world/level/tile/Tile.h"
|
||||
#include "../../world/phys/Vec3.h"
|
||||
#include "../../client/sound/Sound.h"
|
||||
|
||||
#include "../log.h"
|
||||
|
||||
static const char* errIdString = 0;
|
||||
|
||||
void checkError() {
|
||||
|
||||
while (1) {
|
||||
ALenum err = alGetError();
|
||||
if(err == AL_NO_ERROR) return;
|
||||
|
||||
LOGI("### SoundSystemAL error: %d ####: %s\n", err, errIdString==0?"(none)":errIdString);
|
||||
}
|
||||
}
|
||||
|
||||
//typedef ALvoid AL_APIENTRY (*alBufferDataStaticProcPtr) (const ALint bid, ALenum format, ALvoid *data, ALsizei size, ALsizei freq);
|
||||
//ALvoid alBufferDataStaticProc(const ALint bid, ALenum format, ALvoid* data, ALsizei size, ALsizei freq)
|
||||
//{
|
||||
// static alBufferDataStaticProcPtr proc = NULL;
|
||||
//
|
||||
// if (proc == NULL) {
|
||||
// proc = (alBufferDataStaticProcPtr) alcGetProcAddress(NULL, (const ALCchar*) "alBufferDataStatic");
|
||||
// }
|
||||
//
|
||||
// if (proc)
|
||||
// proc(bid, format, data, size, freq);
|
||||
//
|
||||
// return;
|
||||
//}
|
||||
//
|
||||
SoundSystemAL::SoundSystemAL()
|
||||
: available(true),
|
||||
context(0),
|
||||
device(0),
|
||||
_rotation(-9999.9f)
|
||||
{
|
||||
_buffers.reserve(64);
|
||||
init();
|
||||
}
|
||||
|
||||
SoundSystemAL::~SoundSystemAL()
|
||||
{
|
||||
alDeleteSources(MaxNumSources, _sources);
|
||||
|
||||
for (int i = 0; i < (int)_buffers.size(); ++i)
|
||||
if (_buffers[i].inited) alDeleteBuffers(1, &_buffers[i].bufferID);
|
||||
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(context);
|
||||
|
||||
// Close the device
|
||||
alcCloseDevice(device);
|
||||
}
|
||||
|
||||
void SoundSystemAL::init()
|
||||
{
|
||||
device = alcOpenDevice(NULL);
|
||||
if(device) {
|
||||
context = alcCreateContext(device, NULL);
|
||||
alcMakeContextCurrent(context);
|
||||
|
||||
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
|
||||
|
||||
alGenSources(MaxNumSources, _sources);
|
||||
for(int index = 0; index < MaxNumSources; index++) {
|
||||
ALuint sourceID = _sources[index];
|
||||
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, 5.0f);
|
||||
alSourcef(sourceID, AL_MAX_DISTANCE, 16.0f);
|
||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, 6.0f);
|
||||
}
|
||||
|
||||
float listenerPos[] = {0, 0, 0};
|
||||
float listenerOri[] = {0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
|
||||
float listenerVel[] = {0, 0, 0};
|
||||
alListenerfv(AL_POSITION, listenerPos);
|
||||
alListenerfv(AL_ORIENTATION, listenerOri);
|
||||
alListenerfv(AL_VELOCITY, listenerVel);
|
||||
|
||||
errIdString = "Init audio";
|
||||
checkError();
|
||||
}
|
||||
}
|
||||
|
||||
void SoundSystemAL::enable(bool status) {
|
||||
LOGI("Enabling? audio: %d (context %p)\n", status, context);
|
||||
if (status) {
|
||||
alcMakeContextCurrent(context);
|
||||
errIdString = "Enable audio";
|
||||
}
|
||||
else {
|
||||
alcMakeContextCurrent(NULL);
|
||||
errIdString = "Disable audio";
|
||||
}
|
||||
|
||||
checkError();
|
||||
}
|
||||
|
||||
void SoundSystemAL::destroy() {}
|
||||
|
||||
void SoundSystemAL::setListenerPos( float x, float y, float z )
|
||||
{
|
||||
// Note: listener position is thought to be 0,0,0 now
|
||||
|
||||
/*
|
||||
if (_listenerPos.x != x || _listenerPos.y != y || _listenerPos.z != z) {
|
||||
_listenerPos.set(x, y, z);
|
||||
alListener3f(AL_POSITION, x, y, z);
|
||||
|
||||
static int _n = 0;
|
||||
if (++_n == 20) {
|
||||
_n = 0;
|
||||
LOGI("Setting position for listener: %f, %f, %f\n", _listenerPos.x, _listenerPos.y, _listenerPos.z);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void SoundSystemAL::setListenerAngle( float deg )
|
||||
{
|
||||
if (_rotation != deg) {
|
||||
_rotation = deg;
|
||||
|
||||
float rad = deg * Mth::DEGRAD;
|
||||
|
||||
static ALfloat orientation[] = {0, 0, 0, 0, 1, 0};
|
||||
orientation[0] = -Mth::sin( rad );
|
||||
orientation[2] = Mth::cos( rad );
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
}
|
||||
}
|
||||
|
||||
void SoundSystemAL::playAt( const SoundDesc& sound, float x, float y, float z, float volume, float pitch )
|
||||
{
|
||||
if (pitch < 0.01f) pitch = 1;
|
||||
|
||||
//LOGI("playing sound '%s' with volume/pitch: %f, %f @ %f, %f, %f\n", sound.name.c_str(), volume, pitch, x, y, z);
|
||||
|
||||
ALuint bufferID;
|
||||
if (!getBufferId(sound, &bufferID)) {
|
||||
errIdString = "Get buffer (failed)";
|
||||
checkError();
|
||||
LOGE("getBufferId returned false!\n");
|
||||
return;
|
||||
}
|
||||
errIdString = "Get buffer";
|
||||
checkError();
|
||||
//LOGI("playing sound %d - '%s' with volume/pitch: %f, %f @ %f, %f, %f\n", bufferID, sound.name.c_str(), volume, pitch, x, y, z);
|
||||
|
||||
int sourceIndex;
|
||||
errIdString = "Get free index";
|
||||
if (!getFreeSourceIndex(&sourceIndex)) {
|
||||
LOGI("No free sound sources left @ SoundSystemAL::playAt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ALuint sourceID = _sources[sourceIndex];
|
||||
checkError();
|
||||
|
||||
alSourcei(sourceID, AL_BUFFER, 0);
|
||||
errIdString = "unbind";
|
||||
checkError();
|
||||
alSourcei(sourceID, AL_BUFFER, bufferID);
|
||||
errIdString = "bind";
|
||||
checkError();
|
||||
|
||||
alSourcef(sourceID, AL_PITCH, pitch);
|
||||
errIdString = "pitch";
|
||||
checkError();
|
||||
alSourcef(sourceID, AL_GAIN, volume);
|
||||
errIdString = "gain";
|
||||
checkError();
|
||||
|
||||
alSourcei(sourceID, AL_LOOPING, AL_FALSE);
|
||||
errIdString = "looping";
|
||||
checkError();
|
||||
alSource3f(sourceID, AL_POSITION, x, y, z);
|
||||
errIdString = "position";
|
||||
checkError();
|
||||
|
||||
alSourcePlay(sourceID);
|
||||
errIdString = "source play";
|
||||
|
||||
checkError();
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void SoundSystemAL::removeStoppedSounds()
|
||||
{
|
||||
}
|
||||
|
||||
bool SoundSystemAL::getFreeSourceIndex(int* sourceIndex) {
|
||||
for (int i = 0; i < MaxNumSources; ++i) {
|
||||
ALint state;
|
||||
alGetSourcei(_sources[i], AL_SOURCE_STATE, &state);
|
||||
if(state != AL_PLAYING) {
|
||||
*sourceIndex = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SoundSystemAL::getBufferId(const SoundDesc& sound, ALuint* buf) {
|
||||
for (int i = 0; i < (int)_buffers.size(); ++i) {
|
||||
// Points to the same data buffer -> sounds equal
|
||||
if (_buffers[i].framePtr == sound.frames) {
|
||||
//LOGI("Found %p for %s!\n", sound.frames, sound.name.c_str());
|
||||
*buf = _buffers[i].bufferID;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sound.isValid()) {
|
||||
LOGE("Err: sound is invalid @ getBufferId! %s\n", sound.name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
ALuint bufferID;
|
||||
alGenBuffers(1, &bufferID);
|
||||
errIdString = "Gen buffer";
|
||||
checkError();
|
||||
|
||||
ALenum format = (sound.byteWidth==2) ?
|
||||
(sound.channels==2? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16)
|
||||
: (sound.channels==2? AL_FORMAT_STEREO8 : AL_FORMAT_MONO8);
|
||||
|
||||
alBufferData(bufferID, format, sound.frames, sound.size, sound.frameRate);
|
||||
//LOGI("Creating %d (%p) from sound: '%s'\n", bufferID, sound.frames, sound.name.c_str());
|
||||
errIdString = "Buffer data";
|
||||
//LOGI("Creating buffer with data: %d (%d), %p, %d, %d\n", format, sound.byteWidth, sound.frames, sound.size, sound.frameRate);
|
||||
checkError();
|
||||
|
||||
//LOGI("Sound ch: %d, fmt: %d, frames: %p, len: %f, fr: %d, sz: %d, numfr: %d\n", sound.channels, format, sound.frames, sound.length(), sound.frameRate, sound.size, sound.numFrames);
|
||||
|
||||
|
||||
Buffer buffer;
|
||||
buffer.inited = true;
|
||||
buffer.framePtr = sound.frames;
|
||||
buffer.bufferID = bufferID;
|
||||
*buf = bufferID;
|
||||
_buffers.push_back(buffer);
|
||||
|
||||
// @huge @attn @note @fix: The original data is free'd
|
||||
sound.destroy();
|
||||
return true;
|
||||
}
|
||||
73
src/platform/audio/SoundSystemAL.h
Executable file
73
src/platform/audio/SoundSystemAL.h
Executable file
@@ -0,0 +1,73 @@
|
||||
#ifndef SoundSystemAL_H__
|
||||
#define SoundSystemAL_H__
|
||||
|
||||
#include "SoundSystem.h"
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
//
|
||||
// NOTE: This class is only the core OpenAL part of the sound engine.
|
||||
// Some audio setup code can still be managed from respective app
|
||||
// setup code (e.g. the main app delegate for iOS).
|
||||
//
|
||||
|
||||
class SoundSystemAL: public SoundSystem
|
||||
{
|
||||
//typedef std::list<SLObjectItf> SoundList;
|
||||
public:
|
||||
SoundSystemAL();
|
||||
~SoundSystemAL();
|
||||
|
||||
virtual void init();
|
||||
virtual void destroy();
|
||||
|
||||
virtual void enable(bool status);
|
||||
|
||||
virtual void setListenerPos(float x, float y, float z);
|
||||
virtual void setListenerAngle(float deg);
|
||||
|
||||
virtual void load(const std::string& name){}
|
||||
virtual void play(const std::string& name){}
|
||||
virtual void pause(const std::string& name){}
|
||||
virtual void stop(const std::string& name){}
|
||||
virtual void playAt(const SoundDesc& sound, float x, float y, float z, float volume, float pitch);
|
||||
|
||||
private:
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer()
|
||||
: inited(false)
|
||||
{}
|
||||
bool inited;
|
||||
ALuint bufferID;
|
||||
char* framePtr;
|
||||
};
|
||||
|
||||
void removeStoppedSounds();
|
||||
|
||||
static const int MaxNumSources = 12;
|
||||
|
||||
//SoundList playingBuffers;
|
||||
|
||||
Vec3 _listenerPos;
|
||||
float _rotation;
|
||||
|
||||
bool available;
|
||||
|
||||
ALCcontext* context;
|
||||
ALCdevice* device;
|
||||
|
||||
ALuint _sources[MaxNumSources];
|
||||
std::vector<Buffer> _buffers;
|
||||
|
||||
bool getFreeSourceIndex(int* src);
|
||||
bool getBufferId(const SoundDesc& sound, ALuint* buf);
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
#endif /*SoundSystemAL_H__ */
|
||||
243
src/platform/audio/SoundSystemSL.cpp
Executable file
243
src/platform/audio/SoundSystemSL.cpp
Executable file
@@ -0,0 +1,243 @@
|
||||
#include "SoundSystemSL.h"
|
||||
#include <SLES/OpenSLES_Platform.h>
|
||||
#include <SLES/OpenSLES_AndroidConfiguration.h>
|
||||
#include "../../util/Mth.h"
|
||||
#include "../../world/level/tile/Tile.h"
|
||||
#include "../../world/phys/Vec3.h"
|
||||
#include "../../client/sound/Sound.h"
|
||||
|
||||
#include "../log.h"
|
||||
|
||||
// Only one engine can be created at once. You CAN (if you really want)
|
||||
// start two games at once, then it will crash without objEngine being static.
|
||||
/*static*/ SLObjectItf SoundSystemSL::objEngine = 0;
|
||||
|
||||
typedef struct t_context {
|
||||
SLObjectItf obj;
|
||||
Mutex* mutex;
|
||||
} t_context;
|
||||
|
||||
Mutex SoundSystemSL::toRemoveMutex;
|
||||
std::vector<SLObjectItf> SoundSystemSL::toRemove;
|
||||
|
||||
SoundSystemSL::SoundSystemSL()
|
||||
: available(true),
|
||||
listener(NULL),
|
||||
numBuffersPlaying(0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
SoundSystemSL::~SoundSystemSL()
|
||||
{
|
||||
toRemoveMutex.unlock();
|
||||
for (SoundList::iterator it = playingBuffers.begin(); it != playingBuffers.end(); ++it)
|
||||
(**it)->Destroy(*it);
|
||||
(*objOutput)->Destroy(objOutput);
|
||||
|
||||
if (SoundSystemSL::objEngine != 0) {
|
||||
(*SoundSystemSL::objEngine)->Destroy(SoundSystemSL::objEngine);
|
||||
SoundSystemSL::objEngine = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundSystemSL::init()
|
||||
{
|
||||
SoundSystemSL::toRemove.clear();
|
||||
SoundSystemSL::toRemove.reserve(MAX_BUFFERS_PLAYING);
|
||||
toRemoveCopy.resize(MAX_BUFFERS_PLAYING);
|
||||
|
||||
SLresult res;
|
||||
const int MAX_NUMBER_INTERFACES = 2;
|
||||
SLboolean required[MAX_NUMBER_INTERFACES];
|
||||
SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
|
||||
|
||||
SLEngineOption EngineOption[] = {(SLuint32)
|
||||
SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE};
|
||||
|
||||
/* Create OpenSL ES (destroy first if needed)*/
|
||||
if (SoundSystemSL::objEngine != 0)
|
||||
(*SoundSystemSL::objEngine)->Destroy(SoundSystemSL::objEngine);
|
||||
|
||||
res = slCreateEngine( &SoundSystemSL::objEngine, 1, EngineOption, 0, NULL, NULL);
|
||||
checkErr(res);
|
||||
|
||||
/* Realizing the SL Engine in synchronous mode. */
|
||||
res = (*SoundSystemSL::objEngine)->Realize(SoundSystemSL::objEngine, SL_BOOLEAN_FALSE);
|
||||
if (checkErr(res)) {
|
||||
available = false;
|
||||
return;
|
||||
}
|
||||
|
||||
(*SoundSystemSL::objEngine)->GetInterface(SoundSystemSL::objEngine, SL_IID_ENGINE, (void*)&engEngine);
|
||||
checkErr(res);
|
||||
|
||||
/* Create Output Mix object to be used by player - no interfaces
|
||||
required */
|
||||
res = (*engEngine)->CreateOutputMix(engEngine, &objOutput, 0, iidArray, required);
|
||||
checkErr(res);
|
||||
|
||||
/* Realizing the Output Mix object in synchronous mode. */
|
||||
res = (*objOutput)->Realize(objOutput, SL_BOOLEAN_FALSE);
|
||||
checkErr(res);
|
||||
}
|
||||
|
||||
void SoundSystemSL::destroy() {}
|
||||
|
||||
void SoundSystemSL::setListenerPos( float x, float y, float z )
|
||||
{
|
||||
if (!listener) {
|
||||
listenerPos = Vec3(x, y, z);
|
||||
return;
|
||||
}
|
||||
|
||||
SLVec3D pos = {1000.0f * x, 1000.0f * y, 1000.0f * z};
|
||||
SLresult res = (*listener)->SetLocationCartesian(listener, &pos);
|
||||
checkErr(res);
|
||||
}
|
||||
|
||||
void SoundSystemSL::setListenerAngle( float deg )
|
||||
{
|
||||
if (!listener) return;
|
||||
|
||||
SLresult res = (*listener)->SetOrientationAngles(listener, deg*1000.0f, 0, 0);
|
||||
checkErr(res);
|
||||
}
|
||||
|
||||
void SoundSystemSL::playAt( const SoundDesc& sound, float x, float y, float z, float volume, float pitch )
|
||||
{
|
||||
removeStoppedSounds();
|
||||
|
||||
if (numBuffersPlaying >= MAX_BUFFERS_PLAYING)
|
||||
return;
|
||||
|
||||
/* Setup the data source structure for the player */
|
||||
SLDataLocator_AndroidSimpleBufferQueue uri = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
|
||||
SLDataFormat_PCM mime = {
|
||||
SL_DATAFORMAT_PCM,
|
||||
sound.channels,
|
||||
sound.frameRate * 1000,
|
||||
sound.byteWidth << 3,
|
||||
sound.byteWidth << 3,
|
||||
sound.channels==1? SL_SPEAKER_FRONT_CENTER :
|
||||
SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
|
||||
SL_BYTEORDER_LITTLEENDIAN
|
||||
};
|
||||
SLDataSource audioSource = {&uri, &mime};
|
||||
SLDataLocator_OutputMix locator_outputmix;
|
||||
SLDataSink audioSink;
|
||||
SLObjectItf player;
|
||||
SLPlayItf playItf;
|
||||
//SL3DLocationItf locationItf;
|
||||
SLVolumeItf volumeItf;
|
||||
|
||||
/* Setup the data sink structure */
|
||||
locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
|
||||
locator_outputmix.outputMix = objOutput;
|
||||
audioSink.pLocator = (void *)&locator_outputmix;
|
||||
audioSink.pFormat = NULL;
|
||||
|
||||
/* Buffer queue-able */
|
||||
static SLboolean required[2];
|
||||
static SLInterfaceID iidArray[2];
|
||||
required[0] = SL_BOOLEAN_TRUE;
|
||||
iidArray[0] = SL_IID_BUFFERQUEUE;
|
||||
required[1] = SL_BOOLEAN_TRUE;
|
||||
iidArray[1] = SL_IID_VOLUME;
|
||||
|
||||
/* Create the 3D player */
|
||||
SLresult res = (*engEngine)->CreateAudioPlayer(engEngine, &player,
|
||||
&audioSource, &audioSink, 2, iidArray, required);
|
||||
//printf("SL: Created audio player\n");
|
||||
checkErr(res);
|
||||
|
||||
/* Realizing the player in synchronous mode. */
|
||||
res = (*player)->Realize(player, SL_BOOLEAN_FALSE);
|
||||
//LOGI("SL: Realize audio player\n");
|
||||
checkErr(res);
|
||||
|
||||
/* Get the play and volume interfaces */
|
||||
res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
|
||||
//LOGI("SL: Get Player interface\n");
|
||||
checkErr(res);
|
||||
|
||||
res = (*player)->GetInterface(player, SL_IID_VOLUME, (void*)&volumeItf);
|
||||
//LOGI("SL: Get Player interface\n");
|
||||
checkErr(res);
|
||||
|
||||
SLmillibel maxVolume;
|
||||
res = (*volumeItf)->GetMaxVolumeLevel(volumeItf, &maxVolume);
|
||||
SLmillibel mbelVolume = maxVolume - 2000 * (1-volume);//Mth::lerp(SL_MILLIBEL_MIN, maxVolume, 0.95f + 0.05f*volume);
|
||||
LOGI("min: %d, max: %d, current: %d (%f)\n", SL_MILLIBEL_MIN, maxVolume, mbelVolume, volume);
|
||||
res = (*volumeItf)->SetVolumeLevel(volumeItf, mbelVolume);
|
||||
checkErr(res);
|
||||
|
||||
SLAndroidSimpleBufferQueueItf buffer1;
|
||||
res = (*player)->GetInterface(player, SL_IID_BUFFERQUEUE, &buffer1);
|
||||
checkErr(res);
|
||||
|
||||
//t_context* context = new t_context(); //{ player, &toRemoveMutex };
|
||||
//context->obj = player;
|
||||
//context->mutex = &toRemoveMutex;
|
||||
res = (*buffer1)->RegisterCallback(buffer1, SoundSystemSL::removePlayer, (void*)player);
|
||||
checkErr(res);
|
||||
|
||||
res = (*buffer1)->Enqueue(buffer1, sound.frames, sound.size);
|
||||
checkErr(res);
|
||||
|
||||
/* Start playing the 3D source */
|
||||
res = (*playItf)->SetPlayState( playItf, SL_PLAYSTATE_PLAYING );
|
||||
//LOGI("SL: Set play state\n");
|
||||
checkErr(res);
|
||||
|
||||
playingBuffers.push_back(player);
|
||||
++numBuffersPlaying;
|
||||
}
|
||||
|
||||
bool SoundSystemSL::checkErr( SLresult res )
|
||||
{
|
||||
if ( res != SL_RESULT_SUCCESS ) {
|
||||
LOGI("OpenSL error: %d\n", res);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
void SoundSystemSL::removeStoppedSounds()
|
||||
{
|
||||
toRemoveMutex.lock();
|
||||
const int numBuffersToRemove = toRemove.size();
|
||||
for (int i = 0; i < numBuffersToRemove; ++i)
|
||||
toRemoveCopy[i] = toRemove[i];
|
||||
SoundSystemSL::toRemove.clear();
|
||||
toRemoveMutex.unlock();
|
||||
|
||||
for (int i = 0; i < numBuffersToRemove; ++i) {
|
||||
SLObjectItf obj = toRemoveCopy[i];
|
||||
|
||||
SoundList::iterator it = playingBuffers.begin();
|
||||
while (it != playingBuffers.end()) {
|
||||
if (*it == obj) {
|
||||
playingBuffers.erase(it);
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
(*obj)->Destroy(obj);
|
||||
--numBuffersPlaying;
|
||||
}
|
||||
}
|
||||
|
||||
void SoundSystemSL::removePlayer( SLAndroidSimpleBufferQueueItf bq, void *context_ )
|
||||
{
|
||||
//t_context* context = (t_context*) context_;
|
||||
//context->mutex->lock();
|
||||
//SoundSystemSL::toRemove.push_back( context->obj );
|
||||
//context->mutex->unlock();
|
||||
//delete context;
|
||||
|
||||
SoundSystemSL::toRemoveMutex.lock();
|
||||
SoundSystemSL::toRemove.push_back( (SLObjectItf) context_ );
|
||||
SoundSystemSL::toRemoveMutex.unlock();
|
||||
}
|
||||
79
src/platform/audio/SoundSystemSL.h
Executable file
79
src/platform/audio/SoundSystemSL.h
Executable file
@@ -0,0 +1,79 @@
|
||||
#ifndef SoundSystemSL_H__
|
||||
#define SoundSystemSL_H__
|
||||
|
||||
#include "SoundSystem.h"
|
||||
#include <SLES/OpenSLES.h>
|
||||
#include <SLES/OpenSLES_Android.h>
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <pthread.h>
|
||||
class Mutex {
|
||||
pthread_mutex_t _mutex;
|
||||
public:
|
||||
Mutex() { pthread_mutex_init(&_mutex, NULL); }
|
||||
~Mutex() { pthread_mutex_destroy(&_mutex); }
|
||||
void lock() { pthread_mutex_lock(&_mutex); }
|
||||
void unlock() { pthread_mutex_unlock(&_mutex); }
|
||||
};
|
||||
#else
|
||||
class Mutex {
|
||||
public:
|
||||
Mutex() {}
|
||||
void lock() {}
|
||||
void unlock() {};
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
class SoundSystemSL: public SoundSystem
|
||||
{
|
||||
typedef std::list<SLObjectItf> SoundList;
|
||||
public:
|
||||
SoundSystemSL();
|
||||
~SoundSystemSL();
|
||||
|
||||
virtual void init();
|
||||
virtual void destroy();
|
||||
|
||||
virtual void setListenerPos(float x, float y, float z);
|
||||
virtual void setListenerAngle(float deg);
|
||||
|
||||
virtual void load(const std::string& name){}
|
||||
virtual void play(const std::string& name){}
|
||||
virtual void pause(const std::string& name){}
|
||||
virtual void stop(const std::string& name){}
|
||||
virtual void playAt(const SoundDesc& sound, float x, float y, float z, float volume, float pitch);
|
||||
|
||||
private:
|
||||
bool checkErr( SLresult res );
|
||||
|
||||
void removeStoppedSounds();
|
||||
|
||||
SoundList playingBuffers;
|
||||
|
||||
static SLObjectItf objEngine;
|
||||
SLEngineItf engEngine;
|
||||
|
||||
SLObjectItf objListener;
|
||||
SL3DLocationItf listener;
|
||||
|
||||
SLObjectItf objOutput;
|
||||
|
||||
Vec3 listenerPos;
|
||||
int numBuffersPlaying;
|
||||
|
||||
bool available;
|
||||
std::vector<SLObjectItf> toRemoveCopy;
|
||||
|
||||
static Mutex toRemoveMutex;
|
||||
static std::vector<SLObjectItf> toRemove;
|
||||
static const int MAX_BUFFERS_PLAYING = 4;
|
||||
|
||||
public:
|
||||
static void removePlayer(SLAndroidSimpleBufferQueueItf bq, void *context);
|
||||
};
|
||||
|
||||
#endif /*SoundSystemSL_H__ */
|
||||
Reference in New Issue
Block a user