mirror of
https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1.git
synced 2026-03-19 22:43:32 +00:00
254 lines
7.2 KiB
C++
Executable File
254 lines
7.2 KiB
C++
Executable File
//#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;
|
|
}
|