mirror of
https://github.com/celisej567/mcpe.git
synced 2026-09-23 20:09:46 +03:00
* OpenAL adjustments and improvements mk.1 Seperated SoundSystemAl from the sdl section and into platform/openal. Made PlatformDefinitions.hpp require a "USE_OPENAL" definition instead of "USE_SDL" definition for OpenAL Added SoundSystemAl.cpp and SoundSystemAL.hpp files to the actual solution file so it can be compiled properly. Made the SoundSystemAl use headers from thirdparty/OpenAL/include folder. Made the SoundSystemAl use #pragma comment(lib, "OpenAL32.lib") to include the library if needed without adding it to the linker input value in the solution file. Added thirdparty/OpenAL/libs/Win64/thirdparty/OpenAL/libs/Win32 to the additional libraries so that it can find the OpenAL32.lib library. * OpenAL adjustments and improvements mk.2 Removed specific USE_SDL preprocessor definitions related to OpenAL which were unhelpful/unneeded for multi-platform use. Made the OpenAl sound system inherit from the SoundSystem class and implement the functions properly without requiring a custom update function. Fixed an error that would happen when closing the game related to OpenAl closing the sound device. Removed unnecessary is_ui check in OpenAL sound system, UI sounds work just fine without it. Adjusted rolloff factor, not sure if this is just placebo but it felt a bit better? * Update sdl/CMakeLists.txt for new OpenAL stuff * CMakeLists name fix * Minor fixes for SDL compatibility * Added check for absolute zero position Made the OpenAL sound system consider any sound that is at absolute zero non-spatial Also removed unneeded ORIGINAL_CODE check in SoundSystem.hpp and SoundSystem.cpp * Fixed OpenAL popping strangeness OpenAL apparently makes weird popping noises when the gain of a sound is below 0, so I added a check to see if the distance is too far (for the new updated settings) I did some graphing and the previous settings for OpenAL were limiting the sound distance to 8 blocks (which was causing popping when sounds were between 8-16 blocks away as the gain was 0 or below) so I changed the rolloff factor to 1.0f to make sounds falloff at 16 blocks instead which seems reasonable/like the original intention. * Minor Fix to solution additional includes * Forgot an sdl compat change
324 lines
6.1 KiB
C++
324 lines
6.1 KiB
C++
#include "SoundSystemAL.hpp"
|
|
|
|
#include "client/common/Utils.hpp"
|
|
|
|
SoundSystemAL::SoundSystemAL()
|
|
{
|
|
device = alcOpenDevice(NULL);
|
|
if (!device)
|
|
{
|
|
LogMsg("Unable To Load Audio Engine");
|
|
return;
|
|
}
|
|
|
|
// Create Context
|
|
context = alcCreateContext(device, NULL);
|
|
ALCenum err = alcGetError(device);
|
|
if (err != ALC_NO_ERROR)
|
|
{
|
|
LogMsg("Unable To Open Audio Context: %s", alcGetString(device, err));
|
|
return;
|
|
}
|
|
|
|
// Select Context
|
|
alcMakeContextCurrent(context);
|
|
err = alcGetError(device);
|
|
if (err != ALC_NO_ERROR)
|
|
{
|
|
LogMsg("Unable To Select Audio Context: %s", alcGetString(device, err));
|
|
return;
|
|
}
|
|
|
|
// Set Distance Model
|
|
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
|
|
|
|
// Mark As Loaded
|
|
loaded = true;
|
|
}
|
|
|
|
SoundSystemAL::~SoundSystemAL()
|
|
{
|
|
if (!loaded)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Delete Audio Sources
|
|
delete_sources();
|
|
|
|
// Delete Audio Buffers
|
|
delete_buffers();
|
|
|
|
// Deselect Context
|
|
alcMakeContextCurrent(NULL);
|
|
ALCenum err = alcGetError(device);
|
|
if (err != ALC_NO_ERROR)
|
|
{
|
|
LogMsg("Unable To Deselect Audio Context: %s", alcGetString(device, err));
|
|
}
|
|
|
|
// Destroy Context
|
|
alcDestroyContext(context);
|
|
err = alcGetError(device);
|
|
if (err != ALC_NO_ERROR)
|
|
{
|
|
LogMsg("Unable To Destroy Audio Context: %s", alcGetString(device, err));
|
|
}
|
|
|
|
// Close Device
|
|
alcCloseDevice(device);
|
|
// Can't check for error because device is closed
|
|
/*err = alcGetError(device);
|
|
if (err != ALC_NO_ERROR)
|
|
{
|
|
LogMsg("Unable To Close Audio Device: %s", alcGetString(device, err));
|
|
}*/
|
|
}
|
|
|
|
// Error Checking
|
|
#define AL_ERROR_CHECK() AL_ERROR_CHECK_MANUAL(alGetError())
|
|
#define AL_ERROR_CHECK_MANUAL(val) \
|
|
{ \
|
|
ALenum __err = val; \
|
|
if (__err != AL_NO_ERROR) \
|
|
{ \
|
|
LogMsg("(%s:%i) OpenAL Error: %s", __FILE__, __LINE__, alGetString(__err)); \
|
|
exit(EXIT_FAILURE); \
|
|
} \
|
|
}
|
|
|
|
// Delete Sources
|
|
void SoundSystemAL::delete_sources()
|
|
{
|
|
if (loaded)
|
|
{
|
|
for (ALuint source : idle_sources)
|
|
{
|
|
alDeleteSources(1, &source);
|
|
AL_ERROR_CHECK();
|
|
}
|
|
for (ALuint source : sources)
|
|
{
|
|
alDeleteSources(1, &source);
|
|
AL_ERROR_CHECK();
|
|
}
|
|
}
|
|
idle_sources.clear();
|
|
sources.clear();
|
|
}
|
|
|
|
// Delete Buffers
|
|
void SoundSystemAL::delete_buffers()
|
|
{
|
|
if (loaded)
|
|
{
|
|
for (auto &it : buffers)
|
|
{
|
|
if (it.second && alIsBuffer(it.second))
|
|
{
|
|
alDeleteBuffers(1, &it.second);
|
|
AL_ERROR_CHECK();
|
|
}
|
|
}
|
|
}
|
|
buffers.clear();
|
|
}
|
|
|
|
// Get Buffer
|
|
ALuint SoundSystemAL::get_buffer(const SoundDesc& sound)
|
|
{
|
|
if (buffers.count(sound.m_pData) > 0)
|
|
{
|
|
return buffers[sound.m_pData];
|
|
}
|
|
else
|
|
{
|
|
// Sound Format
|
|
ALenum format = AL_NONE;
|
|
if (sound.m_header.m_channels == 1)
|
|
{
|
|
format = sound.m_header.m_bytes_per_sample == 2 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8;
|
|
}
|
|
else if (sound.m_header.m_channels == 2)
|
|
{
|
|
format = sound.m_header.m_bytes_per_sample == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO8;
|
|
}
|
|
|
|
// Sound Data Size
|
|
int size = sound.m_header.m_channels * sound.m_header.m_length * sound.m_header.m_bytes_per_sample;
|
|
|
|
// Create Buffer
|
|
ALuint buffer;
|
|
alGenBuffers(1, &buffer);
|
|
AL_ERROR_CHECK();
|
|
alBufferData(buffer, format, sound.m_pData, size, sound.m_header.m_sample_rate);
|
|
AL_ERROR_CHECK();
|
|
|
|
// Store
|
|
buffers[sound.m_pData] = buffer;
|
|
return buffer;
|
|
}
|
|
}
|
|
|
|
bool SoundSystemAL::isAvailable()
|
|
{
|
|
return loaded;
|
|
}
|
|
|
|
void SoundSystemAL::setListenerPos(float x, float y, float z)
|
|
{
|
|
// Update Listener Position
|
|
alListener3f(AL_POSITION, x, y, z);
|
|
AL_ERROR_CHECK();
|
|
lastListenerPos = Vec3(x, y, z);
|
|
update();
|
|
}
|
|
|
|
void SoundSystemAL::setListenerAngle(float yaw, float pitch)
|
|
{
|
|
// Update Listener Orientation
|
|
float radian_yaw = yaw * (M_PI / 180);
|
|
ALfloat orientation[] = { -sinf(radian_yaw), 0.0f, cosf(radian_yaw), 0.0f, 1.0f, 0.0f };
|
|
alListenerfv(AL_ORIENTATION, orientation);
|
|
AL_ERROR_CHECK();
|
|
}
|
|
|
|
void SoundSystemAL::update()
|
|
{
|
|
// Check
|
|
if (!loaded)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Update Listener Volume
|
|
float volume = 1;
|
|
alListenerf(AL_GAIN, volume);
|
|
AL_ERROR_CHECK();
|
|
|
|
// Clear Finished Sources
|
|
std::vector<ALuint>::iterator it = sources.begin();
|
|
while (it != sources.end())
|
|
{
|
|
ALuint source = *it;
|
|
bool remove = false;
|
|
// Check
|
|
if (source && alIsSource(source))
|
|
{
|
|
// Is Valid Source
|
|
ALint source_state;
|
|
alGetSourcei(source, AL_SOURCE_STATE, &source_state);
|
|
AL_ERROR_CHECK();
|
|
if (source_state != AL_PLAYING)
|
|
{
|
|
// Finished Playing
|
|
remove = true;
|
|
if (idle_sources.size() < MAX_IDLE_SOURCES)
|
|
{
|
|
idle_sources.push_back(source);
|
|
}
|
|
else
|
|
{
|
|
alDeleteSources(1, &source);
|
|
AL_ERROR_CHECK();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Not A Source
|
|
remove = true;
|
|
}
|
|
// Remove If Needed
|
|
if (remove) {
|
|
it = sources.erase(it);
|
|
}
|
|
else
|
|
{
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SoundSystemAL::playAt(const SoundDesc& sound, float x, float y, float z, float volume, float pitch)
|
|
{
|
|
// Check
|
|
if (!loaded)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (volume <= 0.0f)
|
|
return;
|
|
|
|
float distance = Vec3(x, y, z).distanceTo(lastListenerPos);
|
|
if (distance >= MAX_DISTANCE)
|
|
return;
|
|
|
|
// Load Sound
|
|
ALuint buffer = get_buffer(sound);
|
|
if (!buffer)
|
|
return;
|
|
|
|
// Get Source
|
|
ALuint al_source;
|
|
if (idle_sources.size() > 0)
|
|
{
|
|
// Use Idle Source
|
|
al_source = idle_sources.back();
|
|
idle_sources.pop_back();
|
|
}
|
|
else
|
|
{
|
|
// Create Source
|
|
alGenSources(1, &al_source);
|
|
// Special Out-Of-Memory Handling
|
|
{
|
|
ALenum err = alGetError();
|
|
if (err == AL_OUT_OF_MEMORY)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
AL_ERROR_CHECK_MANUAL(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool isUi = AL_FALSE;
|
|
if (x == 0 && y == 0 && z == 0)
|
|
isUi = AL_TRUE;
|
|
|
|
// Set Properties
|
|
alSourcef(al_source, AL_PITCH, pitch);
|
|
AL_ERROR_CHECK();
|
|
alSourcef(al_source, AL_GAIN, volume);
|
|
AL_ERROR_CHECK();
|
|
alSource3f(al_source, AL_POSITION, x, y, z);
|
|
AL_ERROR_CHECK();
|
|
alSource3f(al_source, AL_VELOCITY, 0, 0, 0);
|
|
AL_ERROR_CHECK();
|
|
alSourcei(al_source, AL_LOOPING, AL_FALSE);
|
|
AL_ERROR_CHECK();
|
|
alSourcei(al_source, AL_SOURCE_RELATIVE, isUi);
|
|
AL_ERROR_CHECK();
|
|
|
|
// Set Attenuation
|
|
alSourcef(al_source, AL_MAX_DISTANCE, MAX_DISTANCE);
|
|
AL_ERROR_CHECK();
|
|
alSourcef(al_source, AL_ROLLOFF_FACTOR, 1.0f);
|
|
AL_ERROR_CHECK();
|
|
alSourcef(al_source, AL_REFERENCE_DISTANCE, 5.0f);
|
|
AL_ERROR_CHECK();
|
|
|
|
// Set Buffer
|
|
alSourcei(al_source, AL_BUFFER, buffer);
|
|
AL_ERROR_CHECK();
|
|
|
|
// Play
|
|
alSourcePlay(al_source);
|
|
AL_ERROR_CHECK();
|
|
sources.push_back(al_source);
|
|
}
|