From 4ece0d79210c0f0351c16a0611f40308ceb8efb0 Mon Sep 17 00:00:00 2001 From: bmdhacks Date: Thu, 13 Feb 2025 16:01:47 -0800 Subject: Streaming Audio Problem: The current implementation reads the entire sound file in to memory in order to play it. For OGG background music, this uses 91 Megs of RAM by injesting all ogg songs as well as all wav assets. Solution: Change StarAudio to play the asset from a file handle and stream it off the disk. This results in a massive savings of RAM and doesn't really affect audio quality unless you're doing massive disk operations such as compiling Starbound. --- source/core/StarIODeviceCallbacks.cpp | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 source/core/StarIODeviceCallbacks.cpp (limited to 'source/core/StarIODeviceCallbacks.cpp') diff --git a/source/core/StarIODeviceCallbacks.cpp b/source/core/StarIODeviceCallbacks.cpp new file mode 100644 index 0000000..ca8b692 --- /dev/null +++ b/source/core/StarIODeviceCallbacks.cpp @@ -0,0 +1,39 @@ +#include "StarIODeviceCallbacks.hpp" +#include "vorbis/vorbisfile.h" + +namespace Star { + +IODeviceCallbacks::IODeviceCallbacks(IODevicePtr device) + : m_device(std::move(device)) { + if (!m_device->isOpen()) + m_device->open(IOMode::Read); +} + +IODevicePtr const& IODeviceCallbacks::device() const { + return m_device; +} + +size_t IODeviceCallbacks::readFunc(void* ptr, size_t size, size_t nmemb, void* datasource) { + auto* callbacks = static_cast(datasource); + return callbacks->m_device->read((char*)ptr, size * nmemb) / size; +} + +int IODeviceCallbacks::seekFunc(void* datasource, ogg_int64_t offset, int whence) { + auto* callbacks = static_cast(datasource); + callbacks->m_device->seek(offset, (IOSeek)whence); + return 0; +} + +long int IODeviceCallbacks::tellFunc(void* datasource) { + auto* callbacks = static_cast(datasource); + return (long int)callbacks->m_device->pos(); +} + +void IODeviceCallbacks::setupOggCallbacks(ov_callbacks& callbacks) { + callbacks.read_func = readFunc; + callbacks.seek_func = seekFunc; + callbacks.tell_func = tellFunc; + callbacks.close_func = nullptr; +} + +} \ No newline at end of file -- cgit v1.2.3