diff --git a/media-layer/core/src/audio/api.cpp b/media-layer/core/src/audio/api.cpp index c8dc2d1..60d5aee 100644 --- a/media-layer/core/src/audio/api.cpp +++ b/media-layer/core/src/audio/api.cpp @@ -8,6 +8,7 @@ #include "file.h" #include "engine.h" +#include "api.h" // Store Audio Sources static std::vector &get_sources() { @@ -15,6 +16,13 @@ static std::vector &get_sources() { return sources; } +// Store Idle Audio Sources +#define MAX_IDLE_SOURCES 50 +static std::vector &get_idle_sources() { + static std::vector sources; + return sources; +} + // Error Checking #define AL_ERROR_CHECK() AL_ERROR_CHECK_MANUAL(alGetError()) #define AL_ERROR_CHECK_MANUAL(val) \ @@ -25,6 +33,22 @@ static std::vector &get_sources() { } \ } +// Delete Sources +void _media_audio_delete_sources() { + if (_media_audio_is_loaded()) { + for (ALuint source : get_idle_sources()) { + alDeleteSources(1, &source); + AL_ERROR_CHECK(); + } + for (ALuint source : get_sources()) { + alDeleteSources(1, &source); + AL_ERROR_CHECK(); + } + } + get_idle_sources().clear(); + get_sources().clear(); +} + // Update Listener void media_audio_update(float volume, float x, float y, float z, float yaw) { // Check @@ -57,8 +81,12 @@ void media_audio_update(float volume, float x, float y, float z, float yaw) { if (source_state != AL_PLAYING) { // Finished Playing remove = true; - alDeleteSources(1, &source); - AL_ERROR_CHECK(); + if (get_idle_sources().size() < MAX_IDLE_SOURCES) { + get_idle_sources().push_back(source); + } else { + alDeleteSources(1, &source); + AL_ERROR_CHECK(); + } } } else { // Not A Source @@ -81,16 +109,23 @@ void media_audio_play(const char *source, const char *name, float x, float y, fl // Load Sound ALuint buffer = _media_audio_get_buffer(source, name); if (volume > 0.0f && buffer) { - // Create Source + // Get Source ALuint al_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); + if (get_idle_sources().size() > 0) { + // Use Idle Source + al_source = get_idle_sources().back(); + get_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); + } } } diff --git a/media-layer/core/src/audio/api.h b/media-layer/core/src/audio/api.h new file mode 100644 index 0000000..8bcb90f --- /dev/null +++ b/media-layer/core/src/audio/api.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((visibility("internal"))) void _media_audio_delete_sources(); + +#ifdef __cplusplus +} +#endif diff --git a/media-layer/core/src/audio/engine.c b/media-layer/core/src/audio/engine.c index bc3a930..e663b29 100644 --- a/media-layer/core/src/audio/engine.c +++ b/media-layer/core/src/audio/engine.c @@ -6,6 +6,7 @@ #include "engine.h" #include "file.h" +#include "api.h" // Store Device static ALCdevice *device = NULL; @@ -55,6 +56,9 @@ void _media_audio_init() { // De-Init void _media_audio_cleanup() { if (_media_audio_is_loaded()) { + // Delete Audio Sources + _media_audio_delete_sources(); + // Delete Audio Buffers _media_audio_delete_buffers();