From 0dd95adcd18174292df77b16a19db1559df2544e Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Thu, 19 Jan 2023 12:51:34 +0000 Subject: [PATCH] Add a minimum threshold for STREAM_ALL_AUDIO --- CMake/Definitions.cmake | 1 + CMake/platforms/rg99.cmake | 1 + CMakeLists.txt | 2 ++ Source/engine/sound.cpp | 55 ++++++++++++++++++++---------------- Source/utils/soundsample.cpp | 4 +-- Source/utils/soundsample.h | 8 +++--- 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/CMake/Definitions.cmake b/CMake/Definitions.cmake index ea2618476..45dd7c14c 100644 --- a/CMake/Definitions.cmake +++ b/CMake/Definitions.cmake @@ -90,6 +90,7 @@ foreach( JOY_BUTTON_BACK REMAP_KEYBOARD_KEYS DEVILUTIONX_DEFAULT_RESAMPLER + STREAM_ALL_AUDIO_MIN_FILE_SIZE ) if(DEFINED ${def_name}) list(APPEND DEVILUTIONX_DEFINITIONS ${def_name}=${${def_name}}) diff --git a/CMake/platforms/rg99.cmake b/CMake/platforms/rg99.cmake index 2dbdf61f6..c8f5c4ea6 100644 --- a/CMake/platforms/rg99.cmake +++ b/CMake/platforms/rg99.cmake @@ -25,6 +25,7 @@ set(DEVILUTIONX_PALETTE_TRANSPARENCY_BLACK_16_LUT OFF) # Must stream all the audio due to RAM constraints. set(STREAM_ALL_AUDIO ON) +set(STREAM_ALL_AUDIO_MIN_FILE_SIZE 4096) # Must use a smaller audio buffer due to RAM constraints. set(DEFAULT_AUDIO_BUFFER_SIZE 768) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cf04b7d9..bd652ab7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,8 @@ option(DISABLE_STREAMING_SOUNDS "Disable streaming sounds (to work around broken mark_as_advanced(DISABLE_STREAMING_SOUNDS) option(STREAM_ALL_AUDIO "Stream all the audio. For extremely RAM-constrained platforms.") mark_as_advanced(STREAM_ALL_AUDIO) +set(STREAM_ALL_AUDIO_MIN_FILE_SIZE 0 CACHE STRING "Minimum file size for streaming the audio when STREAM_ALL_AUDIO is ON") +mark_as_advanced(STREAM_ALL_AUDIO_MIN_FILE_SIZE) option(DEVILUTIONX_PALETTE_TRANSPARENCY_BLACK_16_LUT "Whether to use a lookup table for transparency blending with black. This improves performance of blending transparent black overlays, such as quest dialog background, at the cost of 128 KiB of RAM." ON) mark_as_advanced(DEVILUTIONX_PALETTE_TRANSPARENCY_BLACK_16_LUT) diff --git a/Source/engine/sound.cpp b/Source/engine/sound.cpp index e2c0a2ae4..f939f7a72 100644 --- a/Source/engine/sound.cpp +++ b/Source/engine/sound.cpp @@ -48,42 +48,47 @@ std::string GetMp3Path(const char *path) bool LoadAudioFile(const char *path, bool stream, bool errorDialog, SoundSample &result) { -#ifndef STREAM_ALL_AUDIO + bool isMp3 = true; + AssetRef ref = FindAsset(GetMp3Path(path).c_str()); + if (!ref.ok()) { + ref = FindAsset(path); + isMp3 = false; + } + if (!ref.ok()) + ErrDlg("Audio file not found", StrCat(path, "\n", SDL_GetError(), "\n"), __FILE__, __LINE__); + +#if defined(STREAM_ALL_AUDIO) && STREAM_ALL_AUDIO_MIN_FILE_SIZE > 0 + const size_t size = ref.size(); + stream = size >= STREAM_ALL_AUDIO_MIN_FILE_SIZE; +#endif + +#if !defined(STREAM_ALL_AUDIO) || STREAM_ALL_AUDIO_MIN_FILE_SIZE > 0 if (stream) { #endif - if (result.SetChunkStream(GetMp3Path(path), /*isMp3=*/true, /*logErrors=*/false) != 0) { - SDL_ClearError(); - if (result.SetChunkStream(path, /*isMp3=*/false, /*logErrors=*/true) != 0) { - if (errorDialog) { - ErrDlg("Failed to load audio file", StrCat(path, "\n", SDL_GetError(), "\n"), __FILE__, __LINE__); - } - return false; + if (result.SetChunkStream(path, isMp3, /*logErrors=*/true) != 0) { + if (errorDialog) { + ErrDlg("Failed to load audio file", StrCat(path, "\n", SDL_GetError(), "\n"), __FILE__, __LINE__); } + return false; } -#ifndef STREAM_ALL_AUDIO +#if !defined(STREAM_ALL_AUDIO) || STREAM_ALL_AUDIO_MIN_FILE_SIZE > 0 } else { - bool isMp3 = true; - size_t dwBytes; - AssetHandle handle = OpenAsset(GetMp3Path(path).c_str(), dwBytes); - if (!handle.ok()) { -#ifndef UNPACKED_MPQS - SDL_ClearError(); +#ifndef STREAM_ALL_AUDIO + const size_t size = ref.size(); #endif - isMp3 = false; - handle = OpenAsset(path, dwBytes); - if (!handle.ok()) { - if (errorDialog) - ErrDlg("OpenAsset failed", path, __FILE__, __LINE__); - return false; - } + AssetHandle handle = OpenAsset(std::move(ref)); + if (!handle.ok()) { + if (errorDialog) + ErrDlg("Failed to load audio file", StrCat(path, "\n", SDL_GetError(), "\n"), __FILE__, __LINE__); + return false; } - auto waveFile = MakeArraySharedPtr(dwBytes); - if (!handle.read(waveFile.get(), dwBytes)) { + auto waveFile = MakeArraySharedPtr(size); + if (!handle.read(waveFile.get(), size)) { if (errorDialog) ErrDlg("Failed to read file", StrCat(path, ": ", SDL_GetError()), __FILE__, __LINE__); return false; } - const int error = result.SetChunk(waveFile, dwBytes, isMp3); + const int error = result.SetChunk(waveFile, size, isMp3); if (error != 0) { if (errorDialog) ErrSdl(); diff --git a/Source/utils/soundsample.cpp b/Source/utils/soundsample.cpp index 2cb833845..e609b3d74 100644 --- a/Source/utils/soundsample.cpp +++ b/Source/utils/soundsample.cpp @@ -93,7 +93,7 @@ float VolumeLogToLinear(int logVolume, int logMin, int logMax) void SoundSample::Release() { stream_ = nullptr; -#ifndef STREAM_ALL_AUDIO +#if !defined(STREAM_ALL_AUDIO) || STREAM_ALL_AUDIO_MIN_FILE_SIZE file_data_ = nullptr; file_data_size_ = 0; #endif @@ -136,7 +136,7 @@ int SoundSample::SetChunkStream(std::string filePath, bool isMp3, bool logErrors return 0; } -#ifndef STREAM_ALL_AUDIO +#if !defined(STREAM_ALL_AUDIO) || STREAM_ALL_AUDIO_MIN_FILE_SIZE > 0 int SoundSample::SetChunk(ArraySharedPtr fileData, std::size_t dwBytes, bool isMp3) { isMp3_ = isMp3; diff --git a/Source/utils/soundsample.h b/Source/utils/soundsample.h index 7e8fb0fa1..788a894fe 100644 --- a/Source/utils/soundsample.h +++ b/Source/utils/soundsample.h @@ -33,7 +33,7 @@ public: stream_->setFinishCallback(std::forward(callback)); } -#ifndef STREAM_ALL_AUDIO +#if !defined(STREAM_ALL_AUDIO) || STREAM_ALL_AUDIO_MIN_FILE_SIZE > 0 /** * @brief Sets the sample's WAV, FLAC, or Ogg/Vorbis data. * @param fileData Buffer containing the data @@ -44,7 +44,7 @@ public: int SetChunk(ArraySharedPtr fileData, std::size_t dwBytes, bool isMp3); #endif -#ifndef STREAM_ALL_AUDIO +#if !defined(STREAM_ALL_AUDIO) || STREAM_ALL_AUDIO_MIN_FILE_SIZE > 0 [[nodiscard]] bool IsStreaming() const { return file_data_ == nullptr; @@ -53,7 +53,7 @@ public: int DuplicateFrom(const SoundSample &other) { -#ifdef STREAM_ALL_AUDIO +#if defined(STREAM_ALL_AUDIO) && STREAM_ALL_AUDIO_MIN_FILE_SIZE == 0 return SetChunkStream(other.file_path_, other.isMp3_); #else if (other.IsStreaming()) @@ -104,7 +104,7 @@ public: int GetLength() const; private: -#ifndef STREAM_ALL_AUDIO +#if !defined(STREAM_ALL_AUDIO) || STREAM_ALL_AUDIO_MIN_FILE_SIZE > 0 // Non-streaming audio fields: ArraySharedPtr file_data_; std::size_t file_data_size_;